Fix issue with uppercase logrus import (#351)

* chore: use lowercase for logrus repository

* chore: update dependencies using glide
This commit is contained in:
Martin Linkhorst 2017-10-09 17:14:18 +02:00 committed by GitHub
parent 485ede3228
commit 3331a57a18
155 changed files with 3019 additions and 1196 deletions

View File

@ -19,7 +19,7 @@ package controller
import (
"time"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/kubernetes-incubator/external-dns/plan"
"github.com/kubernetes-incubator/external-dns/registry"

19
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: d1ca92323760e7bdb44d2b80d066dd21bcd49c714faa88372a87a81a9520dffc
updated: 2017-06-16T11:52:01.08864027+02:00
hash: bd2f3e3117cc6b93553cb182322b717569d29c15d00892b87b04b52084fc3116
updated: 2017-10-09T14:34:31.295501637+02:00
imports:
- name: bitbucket.org/ww/goautoneg
version: 75cd24fc2f2c2a2088577d12123ddee5f54e0675
@ -9,7 +9,7 @@ imports:
- compute/metadata
- internal
- name: github.com/alecthomas/kingpin
version: 7f0871f2e17818990e4eed73f9b5c2f429501228
version: 1087e65c9441605df944fb12c33f0fe7072d18ca
- name: github.com/alecthomas/template
version: a0175ee3bccc567396460bf5acd36800cb10c49c
subpackages:
@ -17,7 +17,7 @@ imports:
- name: github.com/alecthomas/units
version: 2efee857e7cfd4f3d0138cc3cbb1b4966962b93a
- name: github.com/aws/aws-sdk-go
version: 3acad2065587626a08fdd692651bf1dd52e79ab4
version: 96358b8282b1a3aa66836d2f2fe66216cc419668
subpackages:
- aws
- aws/awserr
@ -61,7 +61,7 @@ imports:
subpackages:
- quantile
- name: github.com/cloudflare/cloudflare-go
version: 9d186a5948cb4bb3d1f3343bc6bcae91e7aa6479
version: 4c6994ac3877fbb627766edadc67f4e816e8c890
- name: github.com/coreos/go-oidc
version: be73733bb8cc830d0205609b95d125215f8e9c70
subpackages:
@ -83,7 +83,7 @@ imports:
- name: github.com/dgrijalva/jwt-go
version: d2709f9f1f31ebcda9651b03077758c1f3a0018c
- name: github.com/digitalocean/godo
version: 4fa9e9d999007b447089056a1c581b5594f0f851
version: 77ea48de76a7b31b234d854f15d003c68bb2fb90
subpackages:
- context
- name: github.com/docker/distribution
@ -175,7 +175,7 @@ imports:
version: 8a290539e2e8629dbc4e6bad948158f790ec31f4
- name: github.com/PuerkitoBio/urlesc
version: 5bd2802263f21d8788851d5305584c82a5c75d7e
- name: github.com/Sirupsen/logrus
- name: github.com/sirupsen/logrus
version: ba1b36c82c5e05c4f912a88eab0dcd91a171688f
- name: github.com/spf13/pflag
version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7
@ -187,6 +187,7 @@ imports:
- assert
- mock
- require
- suite
- name: github.com/tent/http-link-go
version: ac974c61c2f990f4115b119354b5e0b47550e888
- name: github.com/ugorji/go
@ -254,7 +255,7 @@ imports:
- name: gopkg.in/yaml.v2
version: 53feefa2559fb8dfa8d81baad31be332c97d6c77
- name: k8s.io/apimachinery
version: 75b8dd260ef0469d96d578705a87cffd0e09dab8
version: 85ace5365f33b16fc735c866a12e3c765b9700f2
subpackages:
- pkg/api/errors
- pkg/api/meta
@ -295,7 +296,7 @@ imports:
- pkg/watch
- third_party/forked/golang/reflect
- name: k8s.io/client-go
version: 3627aeb7d4f6ade38f995d2c923e459146493c7e
version: 21300e3e11c918b8e6a70fb7293b310683d6c046
subpackages:
- discovery
- discovery/fake

View File

@ -1,6 +1,6 @@
package: github.com/kubernetes-incubator/external-dns
import:
- package: github.com/Sirupsen/logrus
- package: github.com/sirupsen/logrus
version: ~0.11.5
- package: github.com/alecthomas/kingpin
version: ~2.2.4

View File

@ -23,8 +23,8 @@ import (
"syscall"
"time"
log "github.com/Sirupsen/logrus"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
_ "k8s.io/client-go/plugin/pkg/client/auth"

View File

@ -19,8 +19,8 @@ package externaldns
import (
"time"
"github.com/Sirupsen/logrus"
"github.com/alecthomas/kingpin"
"github.com/sirupsen/logrus"
)
var (

View File

@ -21,7 +21,7 @@ import (
"testing"
"time"
"github.com/Sirupsen/logrus"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

View File

@ -17,8 +17,8 @@ limitations under the License.
package plan
import (
log "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/external-dns/endpoint"
log "github.com/sirupsen/logrus"
)
// Plan can convert a list of desired and current records to a series of create,

View File

@ -19,8 +19,8 @@ package provider
import (
"strings"
log "github.com/Sirupsen/logrus"
"github.com/linki/instrumented_http"
log "github.com/sirupsen/logrus"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"

View File

@ -21,7 +21,7 @@ import (
"io/ioutil"
"strings"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v2"

View File

@ -23,7 +23,7 @@ import (
cloudflare "github.com/cloudflare/cloudflare-go"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/kubernetes-incubator/external-dns/endpoint"
"github.com/kubernetes-incubator/external-dns/plan"

View File

@ -21,7 +21,7 @@ import (
"os"
"strings"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"golang.org/x/oauth2"
"github.com/digitalocean/godo"

View File

@ -19,8 +19,8 @@ package provider
import (
"strings"
log "github.com/Sirupsen/logrus"
"github.com/linki/instrumented_http"
log "github.com/sirupsen/logrus"
dns "google.golang.org/api/dns/v1"

View File

@ -20,7 +20,7 @@ import (
"errors"
"strings"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/kubernetes-incubator/external-dns/endpoint"
"github.com/kubernetes-incubator/external-dns/plan"

View File

@ -17,9 +17,9 @@ limitations under the License.
package registry
import (
log "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/external-dns/endpoint"
"github.com/kubernetes-incubator/external-dns/plan"
log "github.com/sirupsen/logrus"
)
// Registry is an interface which should enables ownership concept in external-dns

View File

@ -17,7 +17,7 @@ limitations under the License.
package source
import (
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/kubernetes-incubator/external-dns/endpoint"
)

View File

@ -22,7 +22,7 @@ import (
"strings"
"text/template"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"

View File

@ -22,7 +22,7 @@ import (
"strings"
"text/template"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"

View File

@ -24,8 +24,8 @@ import (
"sync"
log "github.com/Sirupsen/logrus"
"github.com/linki/instrumented_http"
log "github.com/sirupsen/logrus"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)

View File

@ -581,7 +581,7 @@ Consider the case that you needed to read a local database or a file to
provide suggestions. You can dynamically generate the options
```
func listHosts(args []string) []string {
func listHosts() []string {
// Provide a dynamic list of hosts from a hosts file or otherwise
// for bash completion. In this example we simply return static slice.

View File

@ -2,8 +2,8 @@ package kingpin
import (
"io/ioutil"
"testing"
"os"
"testing"
"github.com/alecthomas/assert"
)

View File

@ -106,7 +106,7 @@ func main() {
if v.Format != "" {
return v.Format
}
return "fmt.Sprintf(\"%v\", *f)"
return "fmt.Sprintf(\"%v\", *f.v)"
},
"ValueName": func(v *Value) string {
name := valueName(v)

View File

@ -216,11 +216,9 @@ func (p *ParseContext) Next() *Token {
return &Token{p.argi, TokenError, err.Error()}
}
if len(p.args) == 0 {
p.args = append(p.args, expanded...)
} else if p.argi >= len(p.args) {
p.args = append(p.args[:p.argi-1], expanded...)
p.args = expanded
} else {
p.args = append(p.args[:p.argi-1], append(expanded, p.args[p.argi+1:]...)...)
p.args = append(expanded, p.args...)
}
return p.Next()
}

View File

@ -25,6 +25,86 @@ func TestParserExpandFromFile(t *testing.T) {
assert.Equal(t, "world", *arg1)
}
func TestParserExpandFromFileLeadingArg(t *testing.T) {
f, err := ioutil.TempFile("", "")
assert.NoError(t, err)
defer os.Remove(f.Name())
f.WriteString("hello\nworld\n")
f.Close()
app := New("test", "")
arg0 := app.Arg("arg0", "").String()
arg1 := app.Arg("arg1", "").String()
arg2 := app.Arg("arg2", "").String()
_, err = app.Parse([]string{"prefix", "@" + f.Name()})
assert.NoError(t, err)
assert.Equal(t, "prefix", *arg0)
assert.Equal(t, "hello", *arg1)
assert.Equal(t, "world", *arg2)
}
func TestParserExpandFromFileTrailingArg(t *testing.T) {
f, err := ioutil.TempFile("", "")
assert.NoError(t, err)
defer os.Remove(f.Name())
f.WriteString("hello\nworld\n")
f.Close()
app := New("test", "")
arg0 := app.Arg("arg0", "").String()
arg1 := app.Arg("arg1", "").String()
arg2 := app.Arg("arg2", "").String()
_, err = app.Parse([]string{"@" + f.Name(), "suffix"})
assert.NoError(t, err)
assert.Equal(t, "hello", *arg0)
assert.Equal(t, "world", *arg1)
assert.Equal(t, "suffix", *arg2)
}
func TestParserExpandFromFileMultipleSurroundingArgs(t *testing.T) {
f, err := ioutil.TempFile("", "")
assert.NoError(t, err)
defer os.Remove(f.Name())
f.WriteString("hello\nworld\n")
f.Close()
app := New("test", "")
arg0 := app.Arg("arg0", "").String()
arg1 := app.Arg("arg1", "").String()
arg2 := app.Arg("arg2", "").String()
arg3 := app.Arg("arg3", "").String()
_, err = app.Parse([]string{"prefix", "@" + f.Name(), "suffix"})
assert.NoError(t, err)
assert.Equal(t, "prefix", *arg0)
assert.Equal(t, "hello", *arg1)
assert.Equal(t, "world", *arg2)
assert.Equal(t, "suffix", *arg3)
}
func TestParserExpandFromFileMultipleFlags(t *testing.T) {
f, err := ioutil.TempFile("", "")
assert.NoError(t, err)
defer os.Remove(f.Name())
f.WriteString("--flag1=f1\n--flag2=f2\n")
f.Close()
app := New("test", "")
flag0 := app.Flag("flag0", "").String()
flag1 := app.Flag("flag1", "").String()
flag2 := app.Flag("flag2", "").String()
flag3 := app.Flag("flag3", "").String()
_, err = app.Parse([]string{"--flag0=f0", "@" + f.Name(), "--flag3=f3"})
assert.NoError(t, err)
assert.Equal(t, "f0", *flag0)
assert.Equal(t, "f1", *flag1)
assert.Equal(t, "f2", *flag2)
assert.Equal(t, "f3", *flag3)
}
func TestParseContextPush(t *testing.T) {
app := New("test", "")
app.Command("foo", "").Command("bar", "")

View File

@ -28,7 +28,7 @@ func (f *boolValue) Set(s string) error {
func (f *boolValue) Get() interface{} { return (bool)(*f.v) }
func (f *boolValue) String() string { return fmt.Sprintf("%v", *f) }
func (f *boolValue) String() string { return fmt.Sprintf("%v", *f.v) }
// Bool parses the next command-line value as bool.
func (p *parserMixin) Bool() (target *bool) {
@ -114,7 +114,7 @@ func (f *uintValue) Set(s string) error {
func (f *uintValue) Get() interface{} { return (uint)(*f.v) }
func (f *uintValue) String() string { return fmt.Sprintf("%v", *f) }
func (f *uintValue) String() string { return fmt.Sprintf("%v", *f.v) }
// Uint parses the next command-line value as uint.
func (p *parserMixin) Uint() (target *uint) {
@ -157,7 +157,7 @@ func (f *uint8Value) Set(s string) error {
func (f *uint8Value) Get() interface{} { return (uint8)(*f.v) }
func (f *uint8Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *uint8Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Uint8 parses the next command-line value as uint8.
func (p *parserMixin) Uint8() (target *uint8) {
@ -200,7 +200,7 @@ func (f *uint16Value) Set(s string) error {
func (f *uint16Value) Get() interface{} { return (uint16)(*f.v) }
func (f *uint16Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *uint16Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Uint16 parses the next command-line value as uint16.
func (p *parserMixin) Uint16() (target *uint16) {
@ -243,7 +243,7 @@ func (f *uint32Value) Set(s string) error {
func (f *uint32Value) Get() interface{} { return (uint32)(*f.v) }
func (f *uint32Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *uint32Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Uint32 parses the next command-line value as uint32.
func (p *parserMixin) Uint32() (target *uint32) {
@ -286,7 +286,7 @@ func (f *uint64Value) Set(s string) error {
func (f *uint64Value) Get() interface{} { return (uint64)(*f.v) }
func (f *uint64Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *uint64Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Uint64 parses the next command-line value as uint64.
func (p *parserMixin) Uint64() (target *uint64) {
@ -329,7 +329,7 @@ func (f *intValue) Set(s string) error {
func (f *intValue) Get() interface{} { return (int)(*f.v) }
func (f *intValue) String() string { return fmt.Sprintf("%v", *f) }
func (f *intValue) String() string { return fmt.Sprintf("%v", *f.v) }
// Int parses the next command-line value as int.
func (p *parserMixin) Int() (target *int) {
@ -372,7 +372,7 @@ func (f *int8Value) Set(s string) error {
func (f *int8Value) Get() interface{} { return (int8)(*f.v) }
func (f *int8Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *int8Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Int8 parses the next command-line value as int8.
func (p *parserMixin) Int8() (target *int8) {
@ -415,7 +415,7 @@ func (f *int16Value) Set(s string) error {
func (f *int16Value) Get() interface{} { return (int16)(*f.v) }
func (f *int16Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *int16Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Int16 parses the next command-line value as int16.
func (p *parserMixin) Int16() (target *int16) {
@ -458,7 +458,7 @@ func (f *int32Value) Set(s string) error {
func (f *int32Value) Get() interface{} { return (int32)(*f.v) }
func (f *int32Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *int32Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Int32 parses the next command-line value as int32.
func (p *parserMixin) Int32() (target *int32) {
@ -501,7 +501,7 @@ func (f *int64Value) Set(s string) error {
func (f *int64Value) Get() interface{} { return (int64)(*f.v) }
func (f *int64Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *int64Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Int64 parses the next command-line value as int64.
func (p *parserMixin) Int64() (target *int64) {
@ -544,7 +544,7 @@ func (f *float64Value) Set(s string) error {
func (f *float64Value) Get() interface{} { return (float64)(*f.v) }
func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *float64Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Float64 parses the next command-line value as float64.
func (p *parserMixin) Float64() (target *float64) {
@ -587,7 +587,7 @@ func (f *float32Value) Set(s string) error {
func (f *float32Value) Get() interface{} { return (float32)(*f.v) }
func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) }
func (f *float32Value) String() string { return fmt.Sprintf("%v", *f.v) }
// Float32 parses the next command-line value as float32.
func (p *parserMixin) Float32() (target *float32) {
@ -708,7 +708,7 @@ func (f *regexpValue) Set(s string) error {
func (f *regexpValue) Get() interface{} { return (*regexp.Regexp)(*f.v) }
func (f *regexpValue) String() string { return fmt.Sprintf("%v", *f) }
func (f *regexpValue) String() string { return fmt.Sprintf("%v", *f.v) }
// Regexp parses the next command-line value as *regexp.Regexp.
func (p *parserMixin) Regexp() (target **regexp.Regexp) {
@ -751,7 +751,7 @@ func (f *resolvedIPValue) Set(s string) error {
func (f *resolvedIPValue) Get() interface{} { return (net.IP)(*f.v) }
func (f *resolvedIPValue) String() string { return fmt.Sprintf("%v", *f) }
func (f *resolvedIPValue) String() string { return fmt.Sprintf("%v", *f.v) }
// Resolve a hostname or IP to an IP.
func (p *parserMixin) ResolvedIP() (target *net.IP) {
@ -794,7 +794,7 @@ func (f *hexBytesValue) Set(s string) error {
func (f *hexBytesValue) Get() interface{} { return ([]byte)(*f.v) }
func (f *hexBytesValue) String() string { return fmt.Sprintf("%v", *f) }
func (f *hexBytesValue) String() string { return fmt.Sprintf("%v", *f.v) }
// Bytes as a hex string.
func (p *parserMixin) HexBytes() (target *[]byte) {

View File

@ -1,3 +1,10 @@
Release v1.8.44 (2017-06-16)
===
### Service Client Updates
* `service/xray`: Updates service API, documentation, and paginators
* Add a response time histogram to the services in response of GetServiceGraph API.
Release v1.8.43 (2017-06-15)
===

View File

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK
const SDKVersion = "1.8.43"
const SDKVersion = "1.8.44"

View File

@ -146,14 +146,14 @@
</div> <!-- #pkg-callgraph -->
{{with .Consts}}
<h2 id="pkg-constants">Constants <a class="permalink" href="pkg-constants"></a></h2>
<h2 id="pkg-constants">Constants <a class="permalink" href="#pkg-constants"></a></h2>
{{range .}}
<pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}
{{end}}
{{end}}
{{with .Vars}}
<h2 id="pkg-variables">Variables <a class="permalink" href="pkg-variables"></a></h2>
<h2 id="pkg-variables">Variables <a class="permalink" href="#pkg-variables"></a></h2>
{{range .}}
<pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}
@ -201,7 +201,7 @@
{{range .Methods}}
{{$name_html := html .Name}}
<h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a> <a class="permalink" href="#{{$tname_html}}"></a></h3>
<h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a> <a class="permalink" href="#{{$tname_html}}.{{$name_html}}"></a></h3>
<pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}
{{$name := printf "%s_%s" $tname .Name}}

View File

@ -96,7 +96,7 @@
</div><!-- .expanded -->
</div><!-- #pkg-index -->
{{ if $.HasPaginators -}}
<div id="pkg-pagination " class="toggle">
<div id="pkg-pagination " class="toggleVisible">
<div class="collapsed">
<h2 class="toggleButton" title="Click to show Index section">Paginators ▹</h2>
</div>
@ -114,7 +114,7 @@
</div>
</div>
{{ end -}}
<div id="pkg-types" class="toggle">
<div id="pkg-types" class="toggleVisible">
<div class="collapsed">
<h2 class="toggleButton" title="Click to show Index section">Types ▹</h2>
</div>
@ -130,7 +130,7 @@
{{ range .Methods -}}
{{ if is_setter $.PDoc.Name . -}}
{{ $name_html := html .Name -}}
<dd><a href="#{{$tname_html}}.{{$name_html}}">{{name_only_html $ . | sanitize}}</a></dd>
<dd><a href="#{{$tname_html}}.{{$name_html}}">{{node_html $ .Decl false | sanitize}}</a></dd>
{{ end -}}
{{ end -}}
{{ end -}}
@ -250,9 +250,9 @@
{{ range .Methods -}}
{{ $name_html := html .Name -}}
{{ if is_op_deprecated $.PDoc.Name .Name -}}
<h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a><div class="deprecated">Deprecated</div> <a class="permalink" href="#{{$name_html}}"></a></h3>
<h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a><div class="deprecated">Deprecated</div> <a class="permalink" href="#{{$tname_html}}.{{$name_html}}"></a></h3>
{{ else }}
<h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a> <a class="permalink" href="#{{$name_html}}"></a></h3>
<h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a> <a class="permalink" href="#{{$tname_html}}.{{$name_html}}"></a></h3>
{{ end -}}
<pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}

View File

@ -345,7 +345,8 @@
"EndTime":{"shape":"Timestamp"},
"Edges":{"shape":"EdgeList"},
"SummaryStatistics":{"shape":"ServiceStatistics"},
"DurationHistogram":{"shape":"Histogram"}
"DurationHistogram":{"shape":"Histogram"},
"ResponseTimeHistogram":{"shape":"Histogram"}
}
},
"ServiceId":{

View File

@ -5,9 +5,9 @@
"BatchGetTraces": "<p>Retrieves a list of traces specified by ID. Each trace is a collection of segment documents that originates from a single request. Use <code>GetTraceSummaries</code> to get a list of trace IDs.</p>",
"GetServiceGraph": "<p>Retrieves a document that describes services that process incoming requests, and downstream services that they call as a result. Root services process incoming requests and make calls to downstream services. Root services are applications that use the AWS X-Ray SDK. Downstream services can be other applications, AWS resources, HTTP web APIs, or SQL databases.</p>",
"GetTraceGraph": "<p>Retrieves a service graph for one or more specific trace IDs.</p>",
"GetTraceSummaries": "<p>Retrieves IDs and metadata for traces available for a specified time frame using an optional filter. To get the full traces, pass the trace IDs to <code>BatchGetTraces</code>.</p>",
"GetTraceSummaries": "<p>Retrieves IDs and metadata for traces available for a specified time frame using an optional filter. To get the full traces, pass the trace IDs to <code>BatchGetTraces</code>.</p> <p>A filter expression can target traced requests that hit specific service nodes or edges, have errors, or come from a known user. For example, the following filter expression targets traces that pass through <code>api.example.com</code>:</p> <p> <code>service(\"api.example.com\")</code> </p> <p>This filter expression finds traces that have an annotation named <code>account</code> with the value <code>12345</code>:</p> <p> <code>annotation.account = \"12345\"</code> </p> <p>For a full list of indexed fields and keywords that you can use in filter expressions, see <a href=\"http://docs.aws.amazon.com/xray/latest/devguide/xray-console-filters.html\">Using Filter Expressions</a> in the <i>AWS X-Ray Developer Guide</i>.</p>",
"PutTelemetryRecords": "<p>Used by the AWS X-Ray daemon to upload telemetry.</p>",
"PutTraceSegments": "<p>Uploads segment documents to AWS X-Ray. The X-Ray SDK generates segment documents and sends them to the X-Ray daemon, which uploads them in batches. A segment document can be a completed segment, an in-progress segment, or an array of subsegments.</p>"
"PutTraceSegments": "<p>Uploads segment documents to AWS X-Ray. The X-Ray SDK generates segment documents and sends them to the X-Ray daemon, which uploads them in batches. A segment document can be a completed segment, an in-progress segment, or an array of subsegments.</p> <p>Segments must include the following fields. For the full segment document schema, see <a href=\"http://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html\">AWS X-Ray Segment Documents</a> in the <i>AWS X-Ray Developer Guide</i>.</p> <p class=\"title\"> <b>Required Segment Document Fields</b> </p> <ul> <li> <p> <code>name</code> - The name of the service that handled the request.</p> </li> <li> <p> <code>id</code> - A 64-bit identifier for the segment, unique among segments in the same trace, in 16 hexadecimal digits.</p> </li> <li> <p> <code>trace_id</code> - A unique identifier that connects all segments and subsegments originating from a single client request.</p> </li> <li> <p> <code>start_time</code> - Time the segment or subsegment was created, in floating point seconds in epoch time, accurate to milliseconds. For example, <code>1480615200.010</code> or <code>1.480615200010E9</code>.</p> </li> <li> <p> <code>end_time</code> - Time the segment or subsegment was closed. For example, <code>1480615200.090</code> or <code>1.480615200090E9</code>. Specify either an <code>end_time</code> or <code>in_progress</code>.</p> </li> <li> <p> <code>in_progress</code> - Set to <code>true</code> instead of specifying an <code>end_time</code> to record that a segment has been started, but is not complete. Send an in progress segment when your application receives a request that will take a long time to serve, to trace the fact that the request was received. When the response is sent, send the complete segment to overwrite the in-progress segment.</p> </li> </ul> <p>A <code>trace_id</code> consists of three numbers separated by hyphens. For example, 1-58406520-a006649127e371903a2de979. This includes:</p> <p class=\"title\"> <b>Trace ID Format</b> </p> <ul> <li> <p>The version number, i.e. <code>1</code>.</p> </li> <li> <p>The time of the original request, in Unix epoch time, in 8 hexadecimal digits. For example, 10:00AM December 2nd, 2016 PST in epoch time is <code>1480615200</code> seconds, or <code>58406520</code> in hexadecimal.</p> </li> <li> <p>A 96-bit identifier for the trace, globally unique, in 24 hexadecimal digits.</p> </li> </ul>"
},
"shapes": {
"Alias": {
@ -47,9 +47,9 @@
}
},
"BackendConnectionErrors": {
"base": "<p></p>",
"base": "<p/>",
"refs": {
"TelemetryRecord$BackendConnectionErrors": "<p></p>"
"TelemetryRecord$BackendConnectionErrors": "<p/>"
}
},
"BatchGetTracesRequest": {
@ -139,8 +139,9 @@
"Histogram": {
"base": null,
"refs": {
"Edge$ResponseTimeHistogram": "<p>Histogram describing the prominence of response times on the edge.</p>",
"Service$DurationHistogram": "<p>Histogram mapping the spread of trace durations</p>"
"Edge$ResponseTimeHistogram": "<p>A histogram that maps the spread of client response times on an edge.</p>",
"Service$DurationHistogram": "<p>A histogram that maps the spread of service durations.</p>",
"Service$ResponseTimeHistogram": "<p>A histogram that maps the spread of service response times.</p>"
}
},
"HistogramEntry": {
@ -192,19 +193,19 @@
"NullableInteger": {
"base": null,
"refs": {
"BackendConnectionErrors$TimeoutCount": "<p></p>",
"BackendConnectionErrors$ConnectionRefusedCount": "<p></p>",
"BackendConnectionErrors$HTTPCode4XXCount": "<p></p>",
"BackendConnectionErrors$HTTPCode5XXCount": "<p></p>",
"BackendConnectionErrors$UnknownHostCount": "<p></p>",
"BackendConnectionErrors$OtherCount": "<p></p>",
"BackendConnectionErrors$TimeoutCount": "<p/>",
"BackendConnectionErrors$ConnectionRefusedCount": "<p/>",
"BackendConnectionErrors$HTTPCode4XXCount": "<p/>",
"BackendConnectionErrors$HTTPCode5XXCount": "<p/>",
"BackendConnectionErrors$UnknownHostCount": "<p/>",
"BackendConnectionErrors$OtherCount": "<p/>",
"Edge$ReferenceId": "<p>Identifier of the edge. Unique within a service map.</p>",
"Http$HttpStatus": "<p>The response status.</p>",
"Service$ReferenceId": "<p>Identifier for the service. Unique within the service map.</p>",
"TelemetryRecord$SegmentsReceivedCount": "<p></p>",
"TelemetryRecord$SegmentsSentCount": "<p></p>",
"TelemetryRecord$SegmentsSpilloverCount": "<p></p>",
"TelemetryRecord$SegmentsRejectedCount": "<p></p>"
"TelemetryRecord$SegmentsReceivedCount": "<p/>",
"TelemetryRecord$SegmentsSentCount": "<p/>",
"TelemetryRecord$SegmentsSpilloverCount": "<p/>",
"TelemetryRecord$SegmentsRejectedCount": "<p/>"
}
},
"NullableLong": {
@ -243,7 +244,7 @@
}
},
"Segment": {
"base": "<p>Information about a segment</p>",
"base": "<p>A segment from a trace that has been ingested by the X-Ray service. The segment can be compiled from documents uploaded with <a>PutTraceSegments</a>, or an <code>inferred</code> segment for a downstream service, generated from a subsegment sent by the service that called it.</p>",
"refs": {
"SegmentList$member": null
}
@ -251,7 +252,7 @@
"SegmentDocument": {
"base": null,
"refs": {
"Segment$Document": "<p>The segment document.</p>"
"Segment$Document": "<p>The segment document</p>"
}
},
"SegmentId": {
@ -273,7 +274,7 @@
}
},
"ServiceId": {
"base": "<p></p>",
"base": "<p/>",
"refs": {
"ServiceIds$member": null
}
@ -297,7 +298,7 @@
"base": null,
"refs": {
"Service$Names": "<p>A list of names for the service, including the canonical name.</p>",
"ServiceId$Names": "<p></p>"
"ServiceId$Names": "<p/>"
}
},
"ServiceStatistics": {
@ -325,16 +326,16 @@
"Http$HttpMethod": "<p>The request method.</p>",
"Http$UserAgent": "<p>The request's user agent string.</p>",
"Http$ClientIp": "<p>The IP address of the requestor.</p>",
"PutTelemetryRecordsRequest$EC2InstanceId": "<p></p>",
"PutTelemetryRecordsRequest$Hostname": "<p></p>",
"PutTelemetryRecordsRequest$ResourceARN": "<p></p>",
"PutTelemetryRecordsRequest$EC2InstanceId": "<p/>",
"PutTelemetryRecordsRequest$Hostname": "<p/>",
"PutTelemetryRecordsRequest$ResourceARN": "<p/>",
"Service$Name": "<p>The canonical name of the service.</p>",
"Service$AccountId": "<p>Identifier of the AWS account in which the service runs.</p>",
"Service$Type": "<p>The type of service.</p> <ul> <li> <p>AWS Resource - The type of an AWS resource. For example, <code>AWS::EC2::Instance</code> for a application running on Amazon EC2 or <code>AWS::DynamoDB::Table</code> for an Amazon DynamoDB table that the application used.</p> </li> <li> <p>AWS Service - The type of an AWS service. For example, <code>AWS::DynamoDB</code> for downstream calls to Amazon DynamoDB that didn't target a specific table.</p> </li> <li> <p> <code>client</code> - Represents the clients that sent requests to a root service.</p> </li> <li> <p> <code>remote</code> - A downstream service of indeterminate type.</p> </li> </ul>",
"Service$State": "<p>The service's state.</p>",
"ServiceId$Name": "<p></p>",
"ServiceId$AccountId": "<p></p>",
"ServiceId$Type": "<p></p>",
"ServiceId$Name": "<p/>",
"ServiceId$AccountId": "<p/>",
"ServiceId$Type": "<p/>",
"ServiceNames$member": null,
"TraceUser$UserName": "<p>The user's name.</p>",
"UnprocessedTraceSegment$Id": "<p>The segment's ID.</p>",
@ -343,7 +344,7 @@
}
},
"TelemetryRecord": {
"base": "<p></p>",
"base": "<p/>",
"refs": {
"TelemetryRecordList$member": null
}
@ -351,7 +352,7 @@
"TelemetryRecordList": {
"base": null,
"refs": {
"PutTelemetryRecordsRequest$TelemetryRecords": "<p></p>"
"PutTelemetryRecordsRequest$TelemetryRecords": "<p/>"
}
},
"ThrottledException": {
@ -373,7 +374,7 @@
"GetTraceSummariesResult$ApproximateTime": "<p>The start time of this page of results.</p>",
"Service$StartTime": "<p>The start time of the first segment that the service generated.</p>",
"Service$EndTime": "<p>The end time of the last segment that the service generated.</p>",
"TelemetryRecord$Timestamp": "<p></p>"
"TelemetryRecord$Timestamp": "<p/>"
}
},
"Trace": {
@ -413,7 +414,7 @@
"TraceSegmentDocumentList": {
"base": null,
"refs": {
"PutTraceSegmentsRequest$TraceSegmentDocuments": "<p>A JSON document defining one or more segments or subsegments. Segments must include the following fields.</p> <p class=\"title\"> <b>Required Segment Document Fields</b> </p> <ul> <li> <p> <code>name</code> - The name of the service that handled the request.</p> </li> <li> <p> <code>id</code> - A 64-bit identifier for the segment, unique among segments in the same trace, in 16 hexadecimal digits.</p> </li> <li> <p> <code>trace_id</code> - A unique identifier that connects all segments and subsegments originating from a single client request.</p> </li> <li> <p> <code>start_time</code> - Time the segment or subsegment was created, in floating point seconds in epoch time, accurate to milliseconds. For example, <code>1480615200.010</code> or <code>1.480615200010E9</code>.</p> </li> <li> <p> <code>end_time</code> - Time the segment or subsegment was closed. For example, <code>1480615200.090</code> or <code>1.480615200090E9</code>. Specify either an <code>end_time</code> or <code>in_progress</code>.</p> </li> <li> <p> <code>in_progress</code> - Set to <code>true</code> instead of specifying an <code>end_time</code> to record that a segment has been started, but is not complete. Send an in progress segment when your application receives a request that will take a long time to serve, to trace the fact that the request was received. When the response is sent, send the complete segment to overwrite the in-progress segment.</p> </li> </ul> <p>A <code>trace_id</code> consists of three numbers separated by hyphens. For example, 1-58406520-a006649127e371903a2de979. This includes:</p> <p class=\"title\"> <b>Trace ID Format</b> </p> <ul> <li> <p>The version number, i.e. <code>1</code>.</p> </li> <li> <p>The time of the original request, in Unix epoch time, in 8 hexadecimal digits. For example, 10:00AM December 2nd, 2016 PST in epoch time is <code>1480615200</code> seconds, or <code>58406520</code> in hexadecimal.</p> </li> <li> <p>A 96-bit identifier for the trace, globally unique, in 24 hexadecimal digits.</p> </li> </ul>"
"PutTraceSegmentsRequest$TraceSegmentDocuments": "<p>A string containing a JSON document defining one or more segments or subsegments.</p>"
}
},
"TraceSummary": {

View File

@ -0,0 +1,4 @@
{
"pagination": {
}
}

View File

@ -313,6 +313,21 @@ func (c *XRay) GetTraceSummariesRequest(input *GetTraceSummariesInput) (req *req
// Retrieves IDs and metadata for traces available for a specified time frame
// using an optional filter. To get the full traces, pass the trace IDs to BatchGetTraces.
//
// A filter expression can target traced requests that hit specific service
// nodes or edges, have errors, or come from a known user. For example, the
// following filter expression targets traces that pass through api.example.com:
//
// service("api.example.com")
//
// This filter expression finds traces that have an annotation named account
// with the value 12345:
//
// annotation.account = "12345"
//
// For a full list of indexed fields and keywords that you can use in filter
// expressions, see Using Filter Expressions (http://docs.aws.amazon.com/xray/latest/devguide/xray-console-filters.html)
// in the AWS X-Ray Developer Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
@ -482,6 +497,48 @@ func (c *XRay) PutTraceSegmentsRequest(input *PutTraceSegmentsInput) (req *reque
// document can be a completed segment, an in-progress segment, or an array
// of subsegments.
//
// Segments must include the following fields. For the full segment document
// schema, see AWS X-Ray Segment Documents (http://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html)
// in the AWS X-Ray Developer Guide.
//
// Required Segment Document Fields
//
// * name - The name of the service that handled the request.
//
// * id - A 64-bit identifier for the segment, unique among segments in the
// same trace, in 16 hexadecimal digits.
//
// * trace_id - A unique identifier that connects all segments and subsegments
// originating from a single client request.
//
// * start_time - Time the segment or subsegment was created, in floating
// point seconds in epoch time, accurate to milliseconds. For example, 1480615200.010
// or 1.480615200010E9.
//
// * end_time - Time the segment or subsegment was closed. For example, 1480615200.090
// or 1.480615200090E9. Specify either an end_time or in_progress.
//
// * in_progress - Set to true instead of specifying an end_time to record
// that a segment has been started, but is not complete. Send an in progress
// segment when your application receives a request that will take a long
// time to serve, to trace the fact that the request was received. When the
// response is sent, send the complete segment to overwrite the in-progress
// segment.
//
// A trace_id consists of three numbers separated by hyphens. For example, 1-58406520-a006649127e371903a2de979.
// This includes:
//
// Trace ID Format
//
// * The version number, i.e. 1.
//
// * The time of the original request, in Unix epoch time, in 8 hexadecimal
// digits. For example, 10:00AM December 2nd, 2016 PST in epoch time is 1480615200
// seconds, or 58406520 in hexadecimal.
//
// * A 96-bit identifier for the trace, globally unique, in 24 hexadecimal
// digits.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
@ -772,7 +829,7 @@ type Edge struct {
// Identifier of the edge. Unique within a service map.
ReferenceId *int64 `type:"integer"`
// Histogram describing the prominence of response times on the edge.
// A histogram that maps the spread of client response times on an edge.
ResponseTimeHistogram []*HistogramEntry `type:"list"`
// The start time of the first segment on the edge.
@ -1474,46 +1531,7 @@ func (s PutTelemetryRecordsOutput) GoString() string {
type PutTraceSegmentsInput struct {
_ struct{} `type:"structure"`
// A JSON document defining one or more segments or subsegments. Segments must
// include the following fields.
//
// Required Segment Document Fields
//
// * name - The name of the service that handled the request.
//
// * id - A 64-bit identifier for the segment, unique among segments in the
// same trace, in 16 hexadecimal digits.
//
// * trace_id - A unique identifier that connects all segments and subsegments
// originating from a single client request.
//
// * start_time - Time the segment or subsegment was created, in floating
// point seconds in epoch time, accurate to milliseconds. For example, 1480615200.010
// or 1.480615200010E9.
//
// * end_time - Time the segment or subsegment was closed. For example, 1480615200.090
// or 1.480615200090E9. Specify either an end_time or in_progress.
//
// * in_progress - Set to true instead of specifying an end_time to record
// that a segment has been started, but is not complete. Send an in progress
// segment when your application receives a request that will take a long
// time to serve, to trace the fact that the request was received. When the
// response is sent, send the complete segment to overwrite the in-progress
// segment.
//
// A trace_id consists of three numbers separated by hyphens. For example, 1-58406520-a006649127e371903a2de979.
// This includes:
//
// Trace ID Format
//
// * The version number, i.e. 1.
//
// * The time of the original request, in Unix epoch time, in 8 hexadecimal
// digits. For example, 10:00AM December 2nd, 2016 PST in epoch time is 1480615200
// seconds, or 58406520 in hexadecimal.
//
// * A 96-bit identifier for the trace, globally unique, in 24 hexadecimal
// digits.
// A string containing a JSON document defining one or more segments or subsegments.
//
// TraceSegmentDocuments is a required field
TraceSegmentDocuments []*string `type:"list" required:"true"`
@ -1572,12 +1590,15 @@ func (s *PutTraceSegmentsOutput) SetUnprocessedTraceSegments(v []*UnprocessedTra
return s
}
// Information about a segment
// A segment from a trace that has been ingested by the X-Ray service. The segment
// can be compiled from documents uploaded with PutTraceSegments, or an inferred
// segment for a downstream service, generated from a subsegment sent by the
// service that called it.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/Segment
type Segment struct {
_ struct{} `type:"structure"`
// The segment document.
// The segment document
Document *string `min:"1" type:"string"`
// The segment's ID.
@ -1616,7 +1637,7 @@ type Service struct {
// Identifier of the AWS account in which the service runs.
AccountId *string `type:"string"`
// Histogram mapping the spread of trace durations
// A histogram that maps the spread of service durations.
DurationHistogram []*HistogramEntry `type:"list"`
// Connections to downstream services.
@ -1634,6 +1655,9 @@ type Service struct {
// Identifier for the service. Unique within the service map.
ReferenceId *int64 `type:"integer"`
// A histogram that maps the spread of service response times.
ResponseTimeHistogram []*HistogramEntry `type:"list"`
// Indicates that the service was the first service to process a request.
Root *bool `type:"boolean"`
@ -1714,6 +1738,12 @@ func (s *Service) SetReferenceId(v int64) *Service {
return s
}
// SetResponseTimeHistogram sets the ResponseTimeHistogram field's value.
func (s *Service) SetResponseTimeHistogram(v []*HistogramEntry) *Service {
s.ResponseTimeHistogram = v
return s
}
// SetRoot sets the Root field's value.
func (s *Service) SetRoot(v bool) *Service {
s.Root = &v

View File

@ -26,3 +26,4 @@ notifications:
recipients:
- jamesog@cloudflare.com
- msilverlock@cloudflare.com
- salvatore@cloudflare.com

View File

@ -28,10 +28,11 @@ The current feature list includes:
- [x] Cloudflare IPs
- [x] User Administration (partial)
- [x] Virtual DNS Management
- [x] Custom hostnames
- [ ] Organization Administration
- [ ] [Railgun](https://www.cloudflare.com/railgun/) administration
- [ ] [Keyless SSL](https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/)
- [ ] [Origin CA](https://blog.cloudflare.com/universal-ssl-encryption-all-the-way-to-the-origin-for-free/)
- [x] [Origin CA](https://blog.cloudflare.com/universal-ssl-encryption-all-the-way-to-the-origin-for-free/)
Pull Requests are welcome, but please open an issue (or comment in an existing issue) to discuss any
non-trivial changes before submitting code.

View File

@ -12,15 +12,23 @@ import (
)
const apiURL = "https://api.cloudflare.com/client/v4"
const (
// AuthKeyEmail specifies that we should authenticate with API key and email address
AuthKeyEmail = 1 << iota
// AuthUserService specifies that we should authenticate with a User-Service key
AuthUserService
)
// API holds the configuration for the current API client. A client should not
// be modified concurrently.
type API struct {
APIKey string
APIEmail string
BaseURL string
headers http.Header
httpClient *http.Client
APIKey string
APIEmail string
APIUserServiceKey string
BaseURL string
headers http.Header
httpClient *http.Client
authType int
}
// New creates a new Cloudflare v4 API client.
@ -34,6 +42,7 @@ func New(key, email string, opts ...Option) (*API, error) {
APIEmail: email,
BaseURL: apiURL,
headers: make(http.Header),
authType: AuthKeyEmail,
}
err := api.parseOptions(opts...)
@ -50,6 +59,11 @@ func New(key, email string, opts ...Option) (*API, error) {
return api, nil
}
// SetAuthType sets the authentication method (AuthyKeyEmail or AuthUserService).
func (api *API) SetAuthType(authType int) {
api.authType = authType
}
// ZoneIDByName retrieves a zone's ID from the name.
func (api *API) ZoneIDByName(zoneName string) (string, error) {
res, err := api.ListZones(zoneName)
@ -67,6 +81,10 @@ func (api *API) ZoneIDByName(zoneName string) (string, error) {
// makeRequest makes a HTTP request and returns the body as a byte slice,
// closing it before returnng. params will be serialized to JSON.
func (api *API) makeRequest(method, uri string, params interface{}) ([]byte, error) {
return api.makeRequestWithAuthType(method, uri, params, api.authType)
}
func (api *API) makeRequestWithAuthType(method, uri string, params interface{}, authType int) ([]byte, error) {
// Replace nil with a JSON object if needed
var reqBody io.Reader
if params != nil {
@ -79,7 +97,7 @@ func (api *API) makeRequest(method, uri string, params interface{}) ([]byte, err
reqBody = nil
}
resp, err := api.request(method, uri, reqBody)
resp, err := api.request(method, uri, reqBody, authType)
if err != nil {
return nil, err
}
@ -114,7 +132,7 @@ func (api *API) makeRequest(method, uri string, params interface{}) ([]byte, err
// request makes a HTTP request to the given API endpoint, returning the raw
// *http.Response, or an error if one occurred. The caller is responsible for
// closing the response body.
func (api *API) request(method, uri string, reqBody io.Reader) (*http.Response, error) {
func (api *API) request(method, uri string, reqBody io.Reader, authType int) (*http.Response, error) {
req, err := http.NewRequest(method, api.BaseURL+uri, reqBody)
if err != nil {
return nil, errors.Wrap(err, "HTTP request creation failed")
@ -122,8 +140,17 @@ func (api *API) request(method, uri string, reqBody io.Reader) (*http.Response,
// Apply any user-defined headers first.
req.Header = cloneHeader(api.headers)
req.Header.Set("X-Auth-Key", api.APIKey)
req.Header.Set("X-Auth-Email", api.APIEmail)
if authType&AuthKeyEmail != 0 {
req.Header.Set("X-Auth-Key", api.APIKey)
req.Header.Set("X-Auth-Email", api.APIEmail)
}
if authType&AuthUserService != 0 {
req.Header.Set("X-Auth-User-Service-Key", api.APIUserServiceKey)
}
if req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "application/json")
}
resp, err := api.httpClient.Do(req)
if err != nil {

View File

@ -20,13 +20,13 @@ var (
server *httptest.Server
)
func setup() {
func setup(opts ...Option) {
// test server
mux = http.NewServeMux()
server = httptest.NewServer(mux)
// Cloudflare client configured to use test server
client, _ = New("cloudflare@example.org", "deadbeef")
client, _ = New("deadbeef", "cloudflare@example.org", opts...)
client.BaseURL = server.URL
}
@ -34,6 +34,48 @@ func teardown() {
server.Close()
}
func TestClient_Headers(t *testing.T) {
// it should set default headers
setup()
mux.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method)
assert.Equal(t, "cloudflare@example.org", r.Header.Get("X-Auth-Email"))
assert.Equal(t, "deadbeef", r.Header.Get("X-Auth-Key"))
assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
})
client.UserDetails()
teardown()
// it should override appropriate default headers when custom headers given
headers := make(http.Header)
headers.Set("Content-Type", "application/xhtml+xml")
headers.Add("X-Random", "a random header")
setup(Headers(headers))
mux.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method)
assert.Equal(t, "cloudflare@example.org", r.Header.Get("X-Auth-Email"))
assert.Equal(t, "deadbeef", r.Header.Get("X-Auth-Key"))
assert.Equal(t, "application/xhtml+xml", r.Header.Get("Content-Type"))
assert.Equal(t, "a random header", r.Header.Get("X-Random"))
})
client.UserDetails()
teardown()
// it should set X-Auth-User-Service-Key and omit X-Auth-Email and X-Auth-Key when client.authType is AuthUserService
setup()
client.SetAuthType(AuthUserService)
client.APIUserServiceKey = "userservicekey"
mux.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method)
assert.Empty(t, r.Header.Get("X-Auth-Email"))
assert.Empty(t, r.Header.Get("X-Auth-Key"))
assert.Equal(t, "userservicekey", r.Header.Get("X-Auth-User-Service-Key"))
assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
})
client.UserDetails()
teardown()
}
func TestClient_Auth(t *testing.T) {
setup()
defer teardown()

View File

@ -0,0 +1,163 @@
package main
import (
"fmt"
"strings"
"github.com/cloudflare/cloudflare-go"
"github.com/codegangsta/cli"
)
func dnsCreate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone", "name", "type", "content"); err != nil {
return
}
zone := c.String("zone")
name := c.String("name")
rtype := c.String("type")
content := c.String("content")
ttl := c.Int("ttl")
proxy := c.Bool("proxy")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
record := cloudflare.DNSRecord{
Name: name,
Type: strings.ToUpper(rtype),
Content: content,
TTL: ttl,
Proxied: proxy,
}
// TODO: Print the result.
_, err = api.CreateDNSRecord(zoneID, record)
if err != nil {
fmt.Println("Error creating DNS record:", err)
}
}
func dnsCreateOrUpdate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone", "name", "type", "content"); err != nil {
return
}
zone := c.String("zone")
name := c.String("name")
rtype := strings.ToUpper(c.String("type"))
content := c.String("content")
ttl := c.Int("ttl")
proxy := c.Bool("proxy")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
// Look for an existing record
rr := cloudflare.DNSRecord{
Name: name + "." + zone,
}
records, err := api.DNSRecords(zoneID, rr)
if err != nil {
fmt.Println(err)
return
}
if len(records) > 0 {
// Record exists - find the ID and update it.
// This is imprecise without knowing the original content; if a label
// has multiple RRs we'll just update the first one.
for _, r := range records {
if r.Type == rtype {
rr.ID = r.ID
rr.Type = r.Type
rr.Content = content
rr.TTL = ttl
rr.Proxied = proxy
err := api.UpdateDNSRecord(zoneID, r.ID, rr)
if err != nil {
fmt.Println("Error updating DNS record:", err)
}
}
}
} else {
// Record doesn't exist - create it
rr.Type = rtype
rr.Content = content
rr.TTL = ttl
rr.Proxied = proxy
// TODO: Print the response.
_, err := api.CreateDNSRecord(zoneID, rr)
if err != nil {
fmt.Println("Error creating DNS record:", err)
}
}
}
func dnsUpdate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone", "id"); err != nil {
return
}
zone := c.String("zone")
recordID := c.String("id")
name := c.String("name")
content := c.String("content")
ttl := c.Int("ttl")
proxy := c.Bool("proxy")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
record := cloudflare.DNSRecord{
ID: recordID,
Name: name,
Content: content,
TTL: ttl,
Proxied: proxy,
}
err = api.UpdateDNSRecord(zoneID, recordID, record)
if err != nil {
fmt.Println("Error updating DNS record:", err)
}
}
func dnsDelete(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone", "id"); err != nil {
return
}
zone := c.String("zone")
recordID := c.String("id")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
err = api.DeleteDNSRecord(zoneID, recordID)
if err != nil {
fmt.Println("Error deleting DNS record:", err)
}
}

View File

@ -5,7 +5,6 @@ import (
"fmt"
"log"
"os"
"reflect"
"strings"
"github.com/cloudflare/cloudflare-go"
@ -82,437 +81,6 @@ func checkFlags(c *cli.Context, flags ...string) error {
return nil
}
func ips(*cli.Context) {
ips, _ := cloudflare.IPs()
fmt.Println("IPv4 ranges:")
for _, r := range ips.IPv4CIDRs {
fmt.Println(" ", r)
}
fmt.Println()
fmt.Println("IPv6 ranges:")
for _, r := range ips.IPv6CIDRs {
fmt.Println(" ", r)
}
}
func userInfo(*cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
user, err := api.UserDetails()
if err != nil {
fmt.Println(err)
return
}
var output []table
output = append(output, table{
"ID": user.ID,
"Email": user.Email,
"Username": user.Username,
"Name": user.FirstName + " " + user.LastName,
"2FA": fmt.Sprintf("%t", user.TwoFA),
})
makeTable(output, "ID", "Email", "Username", "Name", "2FA")
}
func userUpdate(*cli.Context) {
}
func zoneCreate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone"); err != nil {
return
}
zone := c.String("zone")
jumpstart := c.Bool("jumpstart")
orgID := c.String("org-id")
var org cloudflare.Organization
if orgID != "" {
org.ID = orgID
}
api.CreateZone(zone, jumpstart, org)
}
func zoneCheck(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone"); err != nil {
return
}
zone := c.String("zone")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
res, err := api.ZoneActivationCheck(zoneID)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%s\n", res.Messages[0].Message)
}
func zoneList(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
zones, err := api.ListZones()
if err != nil {
fmt.Println(err)
return
}
var output []table
for _, z := range zones {
output = append(output, table{
"ID": z.ID,
"Name": z.Name,
"Plan": z.Plan.LegacyID,
"Status": z.Status,
})
}
makeTable(output, "ID", "Name", "Plan", "Status")
}
func zoneInfo(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
var zone string
if len(c.Args()) > 0 {
zone = c.Args()[0]
} else if c.String("zone") != "" {
zone = c.String("zone")
} else {
cli.ShowSubcommandHelp(c)
return
}
zones, err := api.ListZones(zone)
if err != nil {
fmt.Println(err)
return
}
var output []table
for _, z := range zones {
var nameservers []string
if len(z.VanityNS) > 0 {
nameservers = z.VanityNS
} else {
nameservers = z.NameServers
}
output = append(output, table{
"ID": z.ID,
"Zone": z.Name,
"Plan": z.Plan.LegacyID,
"Status": z.Status,
"Name Servers": strings.Join(nameservers, ", "),
"Paused": fmt.Sprintf("%t", z.Paused),
"Type": z.Type,
})
}
makeTable(output, "ID", "Zone", "Plan", "Status", "Name Servers", "Paused", "Type")
}
func zonePlan(*cli.Context) {
}
func zoneSettings(*cli.Context) {
}
func zoneRecords(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
var zone string
if len(c.Args()) > 0 {
zone = c.Args()[0]
} else if c.String("zone") != "" {
zone = c.String("zone")
} else {
cli.ShowSubcommandHelp(c)
return
}
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
// Create a an empty record for searching for records
rr := cloudflare.DNSRecord{}
var records []cloudflare.DNSRecord
if c.String("id") != "" {
rec, err := api.DNSRecord(zoneID, c.String("id"))
if err != nil {
fmt.Println(err)
return
}
records = append(records, rec)
} else {
if c.String("name") != "" {
rr.Name = c.String("name")
}
if c.String("content") != "" {
rr.Name = c.String("content")
}
var err error
records, err = api.DNSRecords(zoneID, rr)
if err != nil {
fmt.Println(err)
return
}
}
var output []table
for _, r := range records {
switch r.Type {
case "MX":
r.Content = fmt.Sprintf("%d %s", r.Priority, r.Content)
case "SRV":
dp := reflect.ValueOf(r.Data).Interface().(map[string]interface{})
r.Content = fmt.Sprintf("%.f %s", dp["priority"], r.Content)
// Cloudflare's API, annoyingly, automatically prepends the weight
// and port into content, separated by tabs.
// XXX: File this as a bug. LOC doesn't do this.
r.Content = strings.Replace(r.Content, "\t", " ", -1)
}
output = append(output, table{
"ID": r.ID,
"Type": r.Type,
"Name": r.Name,
"Content": r.Content,
"Proxied": fmt.Sprintf("%t", r.Proxied),
"TTL": fmt.Sprintf("%d", r.TTL),
})
}
makeTable(output, "ID", "Type", "Name", "Content", "Proxied", "TTL")
}
func dnsCreate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone", "name", "type", "content"); err != nil {
return
}
zone := c.String("zone")
name := c.String("name")
rtype := c.String("type")
content := c.String("content")
ttl := c.Int("ttl")
proxy := c.Bool("proxy")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
record := cloudflare.DNSRecord{
Name: name,
Type: strings.ToUpper(rtype),
Content: content,
TTL: ttl,
Proxied: proxy,
}
// TODO: Print the result.
_, err = api.CreateDNSRecord(zoneID, record)
if err != nil {
fmt.Println("Error creating DNS record:", err)
}
}
func dnsCreateOrUpdate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone", "name", "type", "content"); err != nil {
return
}
zone := c.String("zone")
name := c.String("name")
rtype := strings.ToUpper(c.String("type"))
content := c.String("content")
ttl := c.Int("ttl")
proxy := c.Bool("proxy")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
// Look for an existing record
rr := cloudflare.DNSRecord{
Name: name + "." + zone,
}
records, err := api.DNSRecords(zoneID, rr)
if err != nil {
fmt.Println(err)
return
}
if len(records) > 0 {
// Record exists - find the ID and update it.
// This is imprecise without knowing the original content; if a label
// has multiple RRs we'll just update the first one.
for _, r := range records {
if r.Type == rtype {
rr.ID = r.ID
rr.Type = r.Type
rr.Content = content
rr.TTL = ttl
rr.Proxied = proxy
err := api.UpdateDNSRecord(zoneID, r.ID, rr)
if err != nil {
fmt.Println("Error updating DNS record:", err)
}
}
}
} else {
// Record doesn't exist - create it
rr.Type = rtype
rr.Content = content
rr.TTL = ttl
rr.Proxied = proxy
// TODO: Print the response.
_, err := api.CreateDNSRecord(zoneID, rr)
if err != nil {
fmt.Println("Error creating DNS record:", err)
}
}
}
func dnsUpdate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone", "id"); err != nil {
return
}
zone := c.String("zone")
recordID := c.String("id")
name := c.String("name")
content := c.String("content")
ttl := c.Int("ttl")
proxy := c.Bool("proxy")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
record := cloudflare.DNSRecord{
ID: recordID,
Name: name,
Content: content,
TTL: ttl,
Proxied: proxy,
}
err = api.UpdateDNSRecord(zoneID, recordID, record)
if err != nil {
fmt.Println("Error updating DNS record:", err)
}
}
func dnsDelete(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone", "id"); err != nil {
return
}
zone := c.String("zone")
recordID := c.String("id")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
err = api.DeleteDNSRecord(zoneID, recordID)
if err != nil {
fmt.Println("Error deleting DNS record:", err)
}
}
func zoneCerts(*cli.Context) {
}
func zoneKeyless(*cli.Context) {
}
func zoneRailgun(*cli.Context) {
}
func pageRules(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone"); err != nil {
return
}
zone := c.String("zone")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
rules, err := api.ListPageRules(zoneID)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%3s %-32s %-8s %s\n", "Pri", "ID", "Status", "URL")
for _, r := range rules {
var settings []string
fmt.Printf("%3d %s %-8s %s\n", r.Priority, r.ID, r.Status, r.Targets[0].Constraint.Value)
for _, a := range r.Actions {
v := reflect.ValueOf(a.Value)
var s string
switch a.Value.(type) {
case int:
s = fmt.Sprintf("%s: %d", cloudflare.PageRuleActions[a.ID], v.Int())
case float64:
s = fmt.Sprintf("%s: %.f", cloudflare.PageRuleActions[a.ID], v.Float())
case map[string]interface{}:
vmap := a.Value.(map[string]interface{})
s = fmt.Sprintf("%s: %.f - %s", cloudflare.PageRuleActions[a.ID], vmap["status_code"], vmap["url"])
case nil:
s = fmt.Sprintf("%s", cloudflare.PageRuleActions[a.ID])
default:
s = fmt.Sprintf("%s: %s", cloudflare.PageRuleActions[a.ID], strings.Title(strings.Replace(v.String(), "_", " ", -1)))
}
settings = append(settings, s)
}
fmt.Println(" ", strings.Join(settings, ", "))
}
}
func railgun(*cli.Context) {
}
func main() {
app := cli.NewApp()
app.Name = "flarectl"

View File

@ -0,0 +1,96 @@
package main
import (
"fmt"
"strings"
"github.com/cloudflare/cloudflare-go"
"github.com/codegangsta/cli"
)
func ips(*cli.Context) {
ips, _ := cloudflare.IPs()
fmt.Println("IPv4 ranges:")
for _, r := range ips.IPv4CIDRs {
fmt.Println(" ", r)
}
fmt.Println()
fmt.Println("IPv6 ranges:")
for _, r := range ips.IPv6CIDRs {
fmt.Println(" ", r)
}
}
func userInfo(*cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
user, err := api.UserDetails()
if err != nil {
fmt.Println(err)
return
}
var output []table
output = append(output, table{
"ID": user.ID,
"Email": user.Email,
"Username": user.Username,
"Name": user.FirstName + " " + user.LastName,
"2FA": fmt.Sprintf("%t", user.TwoFA),
})
makeTable(output, "ID", "Email", "Username", "Name", "2FA")
}
func userUpdate(*cli.Context) {
}
func pageRules(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone"); err != nil {
return
}
zone := c.String("zone")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
rules, err := api.ListPageRules(zoneID)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%3s %-32s %-8s %s\n", "Pri", "ID", "Status", "URL")
for _, r := range rules {
var settings []string
fmt.Printf("%3d %s %-8s %s\n", r.Priority, r.ID, r.Status, r.Targets[0].Constraint.Value)
for _, a := range r.Actions {
var s string
switch v := a.Value.(type) {
case int:
s = fmt.Sprintf("%s: %d", cloudflare.PageRuleActions[a.ID], v)
case float64:
s = fmt.Sprintf("%s: %.f", cloudflare.PageRuleActions[a.ID], v)
case map[string]interface{}:
s = fmt.Sprintf("%s: %.f - %s", cloudflare.PageRuleActions[a.ID], v["status_code"], v["url"])
case nil:
s = fmt.Sprintf("%s", cloudflare.PageRuleActions[a.ID])
default:
vs := fmt.Sprintf("%s", v)
s = fmt.Sprintf("%s: %s", cloudflare.PageRuleActions[a.ID], strings.Title(strings.Replace(vs, "_", " ", -1)))
}
settings = append(settings, s)
}
fmt.Println(" ", strings.Join(settings, ", "))
}
}
func railgun(*cli.Context) {
}

View File

@ -0,0 +1,198 @@
package main
import (
"fmt"
"strings"
"github.com/cloudflare/cloudflare-go"
"github.com/codegangsta/cli"
)
func zoneCerts(*cli.Context) {
}
func zoneKeyless(*cli.Context) {
}
func zoneRailgun(*cli.Context) {
}
func zoneCreate(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone"); err != nil {
return
}
zone := c.String("zone")
jumpstart := c.Bool("jumpstart")
orgID := c.String("org-id")
var org cloudflare.Organization
if orgID != "" {
org.ID = orgID
}
api.CreateZone(zone, jumpstart, org)
}
func zoneCheck(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
if err := checkFlags(c, "zone"); err != nil {
return
}
zone := c.String("zone")
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
res, err := api.ZoneActivationCheck(zoneID)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%s\n", res.Messages[0].Message)
}
func zoneList(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
zones, err := api.ListZones()
if err != nil {
fmt.Println(err)
return
}
var output []table
for _, z := range zones {
output = append(output, table{
"ID": z.ID,
"Name": z.Name,
"Plan": z.Plan.Name,
"Status": z.Status,
})
}
makeTable(output, "ID", "Name", "Plan", "Status")
}
func zoneInfo(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
var zone string
if len(c.Args()) > 0 {
zone = c.Args()[0]
} else if c.String("zone") != "" {
zone = c.String("zone")
} else {
cli.ShowSubcommandHelp(c)
return
}
zones, err := api.ListZones(zone)
if err != nil {
fmt.Println(err)
return
}
var output []table
for _, z := range zones {
var nameservers []string
if len(z.VanityNS) > 0 {
nameservers = z.VanityNS
} else {
nameservers = z.NameServers
}
output = append(output, table{
"ID": z.ID,
"Zone": z.Name,
"Plan": z.Plan.Name,
"Status": z.Status,
"Name Servers": strings.Join(nameservers, ", "),
"Paused": fmt.Sprintf("%t", z.Paused),
"Type": z.Type,
})
}
makeTable(output, "ID", "Zone", "Plan", "Status", "Name Servers", "Paused", "Type")
}
func zonePlan(*cli.Context) {
}
func zoneSettings(*cli.Context) {
}
func zoneRecords(c *cli.Context) {
if err := checkEnv(); err != nil {
fmt.Println(err)
return
}
var zone string
if len(c.Args()) > 0 {
zone = c.Args()[0]
} else if c.String("zone") != "" {
zone = c.String("zone")
} else {
cli.ShowSubcommandHelp(c)
return
}
zoneID, err := api.ZoneIDByName(zone)
if err != nil {
fmt.Println(err)
return
}
// Create a an empty record for searching for records
rr := cloudflare.DNSRecord{}
var records []cloudflare.DNSRecord
if c.String("id") != "" {
rec, err := api.DNSRecord(zoneID, c.String("id"))
if err != nil {
fmt.Println(err)
return
}
records = append(records, rec)
} else {
if c.String("name") != "" {
rr.Name = c.String("name")
}
if c.String("content") != "" {
rr.Name = c.String("content")
}
var err error
records, err = api.DNSRecords(zoneID, rr)
if err != nil {
fmt.Println(err)
return
}
}
var output []table
for _, r := range records {
switch r.Type {
case "MX":
r.Content = fmt.Sprintf("%d %s", r.Priority, r.Content)
case "SRV":
dp := r.Data.(map[string]interface{})
r.Content = fmt.Sprintf("%.f %s", dp["priority"], r.Content)
// Cloudflare's API, annoyingly, automatically prepends the weight
// and port into content, separated by tabs.
// XXX: File this as a bug. LOC doesn't do this.
r.Content = strings.Replace(r.Content, "\t", " ", -1)
}
output = append(output, table{
"ID": r.ID,
"Type": r.Type,
"Name": r.Name,
"Content": r.Content,
"Proxied": fmt.Sprintf("%t", r.Proxied),
"TTL": fmt.Sprintf("%d", r.TTL),
})
}
makeTable(output, "ID", "Type", "Name", "Content", "Proxied", "TTL")
}

View File

@ -0,0 +1,149 @@
package cloudflare
import (
"encoding/json"
"net/url"
"strconv"
"github.com/pkg/errors"
)
// CustomHostnameSSL represents the SSL section in a given custom hostname.
type CustomHostnameSSL struct {
Status string `json:"status,omitempty"`
Method string `json:"method,omitempty"`
Type string `json:"type,omitempty"`
CnameTarget string `json:"cname_target,omitempty"`
CnameName string `json:"cname_name,omitempty"`
}
// CustomMetadata defines custom metadata for the hostname. This requires logic to be implemented by Cloudflare to act on the data provided.
type CustomMetadata map[string]interface{}
// CustomHostname represents a custom hostname in a zone.
type CustomHostname struct {
ID string `json:"id,omitempty"`
Hostname string `json:"hostname,omitempty"`
SSL CustomHostnameSSL `json:"ssl,omitempty"`
CustomMetadata CustomMetadata `json:"custom_metadata,omitempty"`
}
// CustomHostNameResponse represents a response from the Custom Hostnames endpoints.
type CustomHostnameResponse struct {
Result CustomHostname `json:"result"`
Response
}
// CustomHostnameListResponse represents a response from the Custom Hostnames endpoints.
type CustomHostnameListResponse struct {
Result []CustomHostname `json:"result"`
Response
ResultInfo `json:"result_info"`
}
// Modify SSL configuration for the given custom hostname in the given zone.
//
// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-update-custom-hostname-configuration
func (api *API) UpdateCustomHostnameSSL(zoneID string, customHostnameID string, ssl CustomHostnameSSL) (CustomHostname, error) {
return CustomHostname{}, errors.New("Not implemented")
}
// Delete a custom hostname (and any issued SSL certificates)
//
// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-delete-a-custom-hostname-and-any-issued-ssl-certificates-
func (api *API) DeleteCustomHostname(zoneID string, customHostnameID string) error {
uri := "/zones/" + zoneID + "/custom_hostnames/" + customHostnameID
res, err := api.makeRequest("DELETE", uri, nil)
if err != nil {
return errors.Wrap(err, errMakeRequestError)
}
var response *CustomHostnameResponse
err = json.Unmarshal(res, &response)
if err != nil {
return errors.Wrap(err, errUnmarshalError)
}
return nil
}
// CreateCustomHostname creates a new custom hostname and requests that an SSL certificate be issued for it.
//
// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-create-custom-hostname
func (api *API) CreateCustomHostname(zoneID string, ch CustomHostname) (*CustomHostnameResponse, error) {
uri := "/zones/" + zoneID + "/custom_hostnames"
res, err := api.makeRequest("POST", uri, ch)
if err != nil {
return nil, errors.Wrap(err, errMakeRequestError)
}
var response *CustomHostnameResponse
err = json.Unmarshal(res, &response)
if err != nil {
return nil, errors.Wrap(err, errUnmarshalError)
}
return response, nil
}
// CustomHostnames fetches custom hostnames for the given zone,
// by applying filter.Hostname if not empty and scoping the result to page'th 50 items.
//
// The returned ResultInfo can be used to implement pagination.
//
// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-list-custom-hostnames
func (api *API) CustomHostnames(zoneID string, page int, filter CustomHostname) ([]CustomHostname, ResultInfo, error) {
v := url.Values{}
v.Set("per_page", "50")
v.Set("page", strconv.Itoa(page))
if filter.Hostname != "" {
v.Set("hostname", filter.Hostname)
}
query := "?" + v.Encode()
uri := "/zones/" + zoneID + "/custom_hostnames" + query
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return []CustomHostname{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError)
}
var customHostnameListResponse CustomHostnameListResponse
err = json.Unmarshal(res, &customHostnameListResponse)
if err != nil {
return []CustomHostname{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError)
}
return customHostnameListResponse.Result, customHostnameListResponse.ResultInfo, nil
}
// CustomHostname inspects the given custom hostname in the given zone.
//
// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-custom-hostname-configuration-details
func (api *API) CustomHostname(zoneID string, customHostnameID string) (CustomHostname, error) {
uri := "/zones/" + zoneID + "/custom_hostnames/" + customHostnameID
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return CustomHostname{}, errors.Wrap(err, errMakeRequestError)
}
var response CustomHostnameResponse
err = json.Unmarshal(res, &response)
if err != nil {
return CustomHostname{}, errors.Wrap(err, errUnmarshalError)
}
return response.Result, nil
}
// CustomHostnameIDByName retrieves the ID for the given hostname in the given zone.
func (api *API) CustomHostnameIDByName(zoneID string, hostname string) (string, error) {
customHostnames, _, err := api.CustomHostnames(zoneID, 1, CustomHostname{Hostname: hostname})
if err != nil {
return "", errors.Wrap(err, "CustomHostnames command failed")
}
for _, ch := range customHostnames {
if ch.Hostname == hostname {
return ch.ID, nil
}
}
return "", errors.New("CustomHostname could not be found")
}

View File

@ -0,0 +1,177 @@
package cloudflare
import (
"fmt"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
)
func TestCustomHostname_DeleteCustomHostname(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/zones/foo/custom_hostnames/bar", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "DELETE", r.Method, "Expected method 'DELETE', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `
{
"id": "bar"
}`)
})
err := client.DeleteCustomHostname("foo", "bar")
assert.NoError(t, err)
}
func TestCustomHostname_CreateCustomHostname(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/zones/foo/custom_hostnames", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "POST", r.Method, "Expected method 'POST', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `
{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "0d89c70d-ad9f-4843-b99f-6cc0252067e9",
"hostname": "app.example.com",
"ssl": {
"status": "pending_validation",
"method": "cname",
"type": "dv",
"cname_target": "dcv.digicert.com",
"cname_name": "810b7d5f01154524b961ba0cd578acc2.app.example.com"
}
}
}`)
})
response, err := client.CreateCustomHostname("foo", CustomHostname{Hostname: "app.example.com", SSL: CustomHostnameSSL{Method: "cname", Type: "dv"}})
want := &CustomHostnameResponse{
Result: CustomHostname{
ID: "0d89c70d-ad9f-4843-b99f-6cc0252067e9",
Hostname: "app.example.com",
SSL: CustomHostnameSSL{
Type: "dv",
Method: "cname",
Status: "pending_validation",
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
},
},
Response: Response{Success: true, Errors: []ResponseInfo{}, Messages: []ResponseInfo{}},
}
if assert.NoError(t, err) {
assert.Equal(t, want, response)
}
}
func TestCustomHostname_CustomHostnames(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/zones/foo/custom_hostnames", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"result": [
{
"id": "custom_host_1",
"hostname": "custom.host.one",
"ssl": {
"type": "dv",
"method": "cname",
"status": "pending_validation",
"cname_target": "dcv.digicert.com",
"cname_name": "810b7d5f01154524b961ba0cd578acc2.app.example.com"
},
"custom_metadata": {
"a_random_field": "random field value"
}
}
],
"result_info": {
"page": 1,
"per_page": 20,
"count": 5,
"total_count": 5
}
}`)
})
customHostnames, _, err := client.CustomHostnames("foo", 1, CustomHostname{})
want := []CustomHostname{
{
ID: "custom_host_1",
Hostname: "custom.host.one",
SSL: CustomHostnameSSL{
Type: "dv",
Method: "cname",
Status: "pending_validation",
CnameTarget: "dcv.digicert.com",
CnameName: "810b7d5f01154524b961ba0cd578acc2.app.example.com",
},
CustomMetadata: CustomMetadata{"a_random_field": "random field value"},
},
}
if assert.NoError(t, err) {
assert.Equal(t, want, customHostnames)
}
}
func TestCustomHostname_CustomHostname(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/zones/foo/custom_hostnames/bar", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"result": {
"id": "bar",
"hostname": "foo.bar.com",
"ssl": {
"type": "dv",
"method": "http",
"status": "active"
},
"custom_metadata": {
"origin": "a.custom.origin"
}
}
}`)
})
customHostname, err := client.CustomHostname("foo", "bar")
want := CustomHostname{
ID: "bar",
Hostname: "foo.bar.com",
SSL: CustomHostnameSSL{
Status: "active",
Method: "http",
Type: "dv",
},
CustomMetadata: CustomMetadata{"origin": "a.custom.origin"},
}
if assert.NoError(t, err) {
assert.Equal(t, want, customHostname)
}
}

View File

@ -43,9 +43,8 @@ type DNSListResponse struct {
}
// CreateDNSRecord creates a DNS record for the zone identifier.
// API reference:
// https://api.cloudflare.com/#dns-records-for-a-zone-create-dns-record
// POST /zones/:zone_identifier/dns_records
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-create-dns-record
func (api *API) CreateDNSRecord(zoneID string, rr DNSRecord) (*DNSRecordResponse, error) {
uri := "/zones/" + zoneID + "/dns_records"
res, err := api.makeRequest("POST", uri, rr)
@ -63,9 +62,10 @@ func (api *API) CreateDNSRecord(zoneID string, rr DNSRecord) (*DNSRecordResponse
}
// DNSRecords returns a slice of DNS records for the given zone identifier.
// API reference:
// https://api.cloudflare.com/#dns-records-for-a-zone-list-dns-records
// GET /zones/:zone_identifier/dns_records
//
// This takes a DNSRecord to allow filtering of the results returned.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-list-dns-records
func (api *API) DNSRecords(zoneID string, rr DNSRecord) ([]DNSRecord, error) {
// Construct a query string
v := url.Values{}
@ -111,9 +111,8 @@ func (api *API) DNSRecords(zoneID string, rr DNSRecord) ([]DNSRecord, error) {
// DNSRecord returns a single DNS record for the given zone & record
// identifiers.
// API reference:
// https://api.cloudflare.com/#dns-records-for-a-zone-dns-record-details
// GET /zones/:zone_identifier/dns_records/:identifier
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-dns-record-details
func (api *API) DNSRecord(zoneID, recordID string) (DNSRecord, error) {
uri := "/zones/" + zoneID + "/dns_records/" + recordID
res, err := api.makeRequest("GET", uri, nil)
@ -130,9 +129,8 @@ func (api *API) DNSRecord(zoneID, recordID string) (DNSRecord, error) {
// UpdateDNSRecord updates a single DNS record for the given zone & record
// identifiers.
// API reference:
// https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record
// PUT /zones/:zone_identifier/dns_records/:identifier
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record
func (api *API) UpdateDNSRecord(zoneID, recordID string, rr DNSRecord) error {
rec, err := api.DNSRecord(zoneID, recordID)
if err != nil {
@ -159,9 +157,8 @@ func (api *API) UpdateDNSRecord(zoneID, recordID string, rr DNSRecord) error {
// DeleteDNSRecord deletes a single DNS record for the given zone & record
// identifiers.
// API reference:
// https://api.cloudflare.com/#dns-records-for-a-zone-delete-dns-record
// DELETE /zones/:zone_identifier/dns_records/:identifier
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-delete-dns-record
func (api *API) DeleteDNSRecord(zoneID, recordID string) error {
uri := "/zones/" + zoneID + "/dns_records/" + recordID
res, err := api.makeRequest("DELETE", uri, nil)

View File

@ -0,0 +1,100 @@
package cloudflare_test
import (
"fmt"
"log"
cloudflare "github.com/cloudflare/cloudflare-go"
)
func ExampleAPI_DNSRecords_all() {
api, err := cloudflare.New("deadbeef", "test@example.org")
if err != nil {
log.Fatal(err)
}
zoneID, err := api.ZoneIDByName("example.com")
if err != nil {
log.Fatal(err)
}
// Fetch all records for a zone
recs, err := api.DNSRecords(zoneID, cloudflare.DNSRecord{})
if err != nil {
log.Fatal(err)
}
for _, r := range recs {
fmt.Printf("%s: %s\n", r.Name, r.Content)
}
}
func ExampleAPI_DNSRecords_filterByContent() {
api, err := cloudflare.New("deadbeef", "test@example.org")
if err != nil {
log.Fatal(err)
}
zoneID, err := api.ZoneIDByName("example.com")
if err != nil {
log.Fatal(err)
}
// Fetch only records whose content is 127.0.0.1
localhost := cloudflare.DNSRecord{Content: "127.0.0.1"}
recs, err := api.DNSRecords(zoneID, localhost)
if err != nil {
log.Fatal(err)
}
for _, r := range recs {
fmt.Printf("%s: %s\n", r.Name, r.Content)
}
}
func ExampleAPI_DNSRecords_filterByName() {
api, err := cloudflare.New("deadbeef", "test@example.org")
if err != nil {
log.Fatal(err)
}
zoneID, err := api.ZoneIDByName("example.com")
if err != nil {
log.Fatal(err)
}
// Fetch records of any type with name "foo.example.com"
// The name must be fully-qualified
foo := cloudflare.DNSRecord{Name: "foo.example.com"}
recs, err := api.DNSRecords(zoneID, foo)
if err != nil {
log.Fatal(err)
}
for _, r := range recs {
fmt.Printf("%s: %s\n", r.Name, r.Content)
}
}
func ExampleAPI_DNSRecords_filterByType() {
api, err := cloudflare.New("deadbeef", "test@example.org")
if err != nil {
log.Fatal(err)
}
zoneID, err := api.ZoneIDByName("example.com")
if err != nil {
log.Fatal(err)
}
// Fetch only AAAA type records
aaaa := cloudflare.DNSRecord{Type: "AAAA"}
recs, err := api.DNSRecords(zoneID, aaaa)
if err != nil {
log.Fatal(err)
}
for _, r := range recs {
fmt.Printf("%s: %s\n", r.Name, r.Content)
}
}

View File

@ -2,9 +2,10 @@ package cloudflare
// Error messages
const (
errEmptyCredentials = "invalid credentials: key & email must not be empty"
errMakeRequestError = "error from makeRequest"
errUnmarshalError = "error unmarshalling the JSON response"
errEmptyCredentials = "invalid credentials: key & email must not be empty"
errMakeRequestError = "error from makeRequest"
errUnmarshalError = "error unmarshalling the JSON response"
errRequestNotSuccessful = "error reported by API"
)
var _ Error = &UserError{}

View File

@ -0,0 +1,33 @@
package cloudflare_test
import (
"fmt"
cloudflare "github.com/cloudflare/cloudflare-go"
)
func Example() {
api, err := cloudflare.New("deadbeef", "cloudflare@example.org")
if err != nil {
fmt.Println(err)
return
}
// Fetch the zone ID for zone example.org
zoneID, err := api.ZoneIDByName("example.org")
if err != nil {
fmt.Println(err)
return
}
// Fetch all DNS records for example.org
records, err := api.DNSRecords(zoneID, cloudflare.DNSRecord{})
if err != nil {
fmt.Println(err)
return
}
for _, r := range records {
fmt.Printf("%s: %s\n", r.Name, r.Content)
}
}

View File

@ -8,27 +8,23 @@ import (
"github.com/pkg/errors"
)
// IPRanges contains lists of IPv4 and IPv6 CIDRs
// IPRanges contains lists of IPv4 and IPv6 CIDRs.
type IPRanges struct {
IPv4CIDRs []string `json:"ipv4_cidrs"`
IPv6CIDRs []string `json:"ipv6_cidrs"`
}
// IPsResponse is the API response containing a list of IPs
// IPsResponse is the API response containing a list of IPs.
type IPsResponse struct {
Response
Result IPRanges `json:"result"`
}
/*
IPs gets a list of Cloudflare's IP ranges
This does not require logging in to the API.
API reference:
https://api.cloudflare.com/#cloudflare-ips
GET /client/v4/ips
*/
// IPs gets a list of Cloudflare's IP ranges.
//
// This does not require logging in to the API.
//
// API reference: https://api.cloudflare.com/#cloudflare-ips
func IPs() (IPRanges, error) {
resp, err := http.Get(apiURL + "/ips")
if err != nil {

View File

@ -22,36 +22,31 @@ type KeylessSSLResponse struct {
}
// CreateKeyless creates a new Keyless SSL configuration for the zone.
// API reference:
// https://api.cloudflare.com/#keyless-ssl-for-a-zone-create-a-keyless-ssl-configuration
// POST /zones/:zone_identifier/keyless_certificates
//
// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-create-a-keyless-ssl-configuration
func (api *API) CreateKeyless() {
}
// ListKeyless lists Keyless SSL configurations for a zone.
// API reference:
// https://api.cloudflare.com/#keyless-ssl-for-a-zone-list-keyless-ssls
// GET /zones/:zone_identifier/keyless_certificates
//
// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-list-keyless-ssls
func (api *API) ListKeyless() {
}
// Keyless provides the configuration for a given Keyless SSL identifier.
// API reference:
// https://api.cloudflare.com/#keyless-ssl-for-a-zone-keyless-ssl-details
// GET /zones/:zone_identifier/keyless_certificates/:identifier
//
// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-keyless-ssl-details
func (api *API) Keyless() {
}
// UpdateKeyless updates an existing Keyless SSL configuration.
// API reference:
// https://api.cloudflare.com/#keyless-ssl-for-a-zone-update-keyless-configuration
// PATCH /zones/:zone_identifier/keyless_certificates/:identifier
//
// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-update-keyless-configuration
func (api *API) UpdateKeyless() {
}
// DeleteKeyless deletes an existing Keyless SSL configuration.
// API reference:
// https://api.cloudflare.com/#keyless-ssl-for-a-zone-delete-keyless-configuration
// DELETE /zones/:zone_identifier/keyless_certificates/:identifier
//
// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-delete-keyless-configuration
func (api *API) DeleteKeyless() {
}

View File

@ -2,6 +2,7 @@ package cloudflare
import (
"encoding/json"
"time"
"github.com/pkg/errors"
)
@ -22,10 +23,55 @@ type organizationResponse struct {
ResultInfo `json:"result_info"`
}
// OrganizationMember has details on a member.
type OrganizationMember struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Email string `json:"email,omitempty"`
Status string `json:"status,omitempty"`
Roles []OrganizationRole `json:"roles,omitempty"`
}
// OrganizationInvite has details on an invite.
type OrganizationInvite struct {
ID string `json:"id,omitempty"`
InvitedMemberID string `json:"invited_member_id,omitempty"`
InvitedMemberEmail string `json:"invited_member_email,omitempty"`
OrganizationID string `json:"organization_id,omitempty"`
OrganizationName string `json:"organization_name,omitempty"`
Roles []OrganizationRole `json:"roles,omitempty"`
InvitedBy string `json:"invited_by,omitempty"`
InvitedOn *time.Time `json:"invited_on,omitempty"`
ExpiresOn *time.Time `json:"expires_on,omitempty"`
Status string `json:"status,omitempty"`
}
// OrganizationRole has details on a role.
type OrganizationRole struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Permissions []string `json:"permissions,omitempty"`
}
// OrganizationDetails represents details of an organization.
type OrganizationDetails struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Members []OrganizationMember `json:"members"`
Invites []OrganizationInvite `json:"invites"`
Roles []OrganizationRole `json:"roles,omitempty"`
}
// organizationDetailsResponse represents the response from the OrganizationDetails endpoint.
type organizationDetailsResponse struct {
Response
Result OrganizationDetails `json:"result"`
}
// ListOrganizations lists organizations of the logged-in user.
// API reference:
// https://api.cloudflare.com/#user-s-organizations-list-organizations
// GET /user/organizations
//
// API reference: https://api.cloudflare.com/#user-s-organizations-list-organizations
func (api *API) ListOrganizations() ([]Organization, ResultInfo, error) {
var r organizationResponse
res, err := api.makeRequest("GET", "/user/organizations", nil)
@ -40,3 +86,100 @@ func (api *API) ListOrganizations() ([]Organization, ResultInfo, error) {
return r.Result, r.ResultInfo, nil
}
// OrganizationDetails returns details for the specified organization of the logged-in user.
//
// API reference: https://api.cloudflare.com/#organizations-organization-details
func (api *API) OrganizationDetails(organizationID string) (OrganizationDetails, error) {
var r organizationDetailsResponse
uri := "/organizations/" + organizationID
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return OrganizationDetails{}, errors.Wrap(err, errMakeRequestError)
}
err = json.Unmarshal(res, &r)
if err != nil {
return OrganizationDetails{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}
// organizationMembersResponse represents the response from the Organization members endpoint.
type organizationMembersResponse struct {
Response
Result []OrganizationMember `json:"result"`
ResultInfo `json:"result_info"`
}
// OrganizationMembers returns list of members for specified organization of the logged-in user.
//
// API reference: https://api.cloudflare.com/#organization-members-list-members
func (api *API) OrganizationMembers(organizationID string) ([]OrganizationMember, ResultInfo, error) {
var r organizationMembersResponse
uri := "/organizations/" + organizationID + "/members"
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return []OrganizationMember{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError)
}
err = json.Unmarshal(res, &r)
if err != nil {
return []OrganizationMember{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, r.ResultInfo, nil
}
// organizationInvitesResponse represents the response from the Organization invites endpoint.
type organizationInvitesResponse struct {
Response
Result []OrganizationInvite `json:"result"`
ResultInfo `json:"result_info"`
}
// OrganizationMembers returns list of invites for specified organization of the logged-in user.
//
// API reference: https://api.cloudflare.com/#organization-invites
func (api *API) OrganizationInvites(organizationID string) ([]OrganizationInvite, ResultInfo, error) {
var r organizationInvitesResponse
uri := "/organizations/" + organizationID + "/invites"
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return []OrganizationInvite{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError)
}
err = json.Unmarshal(res, &r)
if err != nil {
return []OrganizationInvite{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, r.ResultInfo, nil
}
// organizationRolesResponse represents the response from the Organization roles endpoint.
type organizationRolesResponse struct {
Response
Result []OrganizationRole `json:"result"`
ResultInfo `json:"result_info"`
}
// OrganizationRoles returns list of roles for specified organization of the logged-in user.
//
// API reference: https://api.cloudflare.com/#organization-roles-list-roles
func (api *API) OrganizationRoles(organizationID string) ([]OrganizationRole, ResultInfo, error) {
var r organizationRolesResponse
uri := "/organizations/" + organizationID + "/roles"
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return []OrganizationRole{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError)
}
err = json.Unmarshal(res, &r)
if err != nil {
return []OrganizationRole{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, r.ResultInfo, nil
}

View File

@ -2,10 +2,10 @@ package cloudflare
import (
"fmt"
"github.com/stretchr/testify/assert"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"time"
)
func TestOrganizations_ListOrganizations(t *testing.T) {
@ -56,11 +56,340 @@ func TestOrganizations_ListOrganizations(t *testing.T) {
assert.Equal(t, user, want)
}
want_pagination := ResultInfo{
wantPagination := ResultInfo{
Page: 1,
PerPage: 20,
Count: 1,
Total: 2000,
}
assert.Equal(t, paginator, want_pagination)
assert.Equal(t, paginator, wantPagination)
}
func TestOrganizations_OrganizationDetails(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/organizations/01a7362d577a6c3019a474fd6f485823", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "01a7362d577a6c3019a474fd6f485823",
"name": "Cloudflare, Inc.",
"members": [
{
"id": "7c5dae5552338874e5053f2534d2767a",
"name": "John Smith",
"email": "user@example.com",
"status": "accepted",
"roles": [
{
"id": "3536bcfad5faccb999b47003c79917fb",
"name": "Organization Admin",
"description": "Administrative access to the entire Organization",
"permissions": [
"#zones:read"
]
}
]
}
],
"invites": [
{
"id": "4f5f0c14a2a41d5063dd301b2f829f04",
"invited_member_id": "5a7805061c76ada191ed06f989cc3dac",
"invited_member_email": "user@example.com",
"organization_id": "5a7805061c76ada191ed06f989cc3dac",
"organization_name": "Cloudflare, Inc.",
"roles": [
{
"id": "3536bcfad5faccb999b47003c79917fb",
"name": "Organization Admin",
"description": "Administrative access to the entire Organization",
"permissions": [
"#zones:read"
]
}
],
"invited_by": "user@example.com",
"invited_on": "2014-01-01T05:20:00Z",
"expires_on": "2014-01-01T05:20:00Z",
"status": "accepted"
}
],
"roles": [
{
"id": "3536bcfad5faccb999b47003c79917fb",
"name": "Organization Admin",
"description": "Administrative access to the entire Organization",
"permissions": [
"#zones:read"
]
}
]
}
}`)
})
organizationDetails, err := client.OrganizationDetails("01a7362d577a6c3019a474fd6f485823")
invitedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
expiresOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
want := OrganizationDetails{
ID: "01a7362d577a6c3019a474fd6f485823",
Name: "Cloudflare, Inc.",
Members: []OrganizationMember{{
ID: "7c5dae5552338874e5053f2534d2767a",
Name: "John Smith",
Email: "user@example.com",
Status: "accepted",
Roles: []OrganizationRole{{
ID: "3536bcfad5faccb999b47003c79917fb",
Name: "Organization Admin",
Description: "Administrative access to the entire Organization",
Permissions: []string{
"#zones:read",
},
}},
}},
Invites: []OrganizationInvite{{
ID: "4f5f0c14a2a41d5063dd301b2f829f04",
InvitedMemberID: "5a7805061c76ada191ed06f989cc3dac",
InvitedMemberEmail: "user@example.com",
OrganizationID: "5a7805061c76ada191ed06f989cc3dac",
OrganizationName: "Cloudflare, Inc.",
Roles: []OrganizationRole{{
ID: "3536bcfad5faccb999b47003c79917fb",
Name: "Organization Admin",
Description: "Administrative access to the entire Organization",
Permissions: []string{
"#zones:read",
}}},
InvitedBy: "user@example.com",
InvitedOn: &invitedOn,
ExpiresOn: &expiresOn,
Status: "accepted",
}},
Roles: []OrganizationRole{{
ID: "3536bcfad5faccb999b47003c79917fb",
Name: "Organization Admin",
Description: "Administrative access to the entire Organization",
Permissions: []string{"#zones:read"},
}},
}
if assert.NoError(t, err) {
assert.Equal(t, organizationDetails, want)
}
}
func TestOrganizations_OrganizationMembers(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/organizations/01a7362d577a6c3019a474fd6f485823/members", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": [
{
"id": "7c5dae5552338874e5053f2534d2767a",
"name": "John Smith",
"email": "user@example.com",
"status": "accepted",
"roles": [
{
"id": "3536bcfad5faccb999b47003c79917fb",
"name": "Organization Admin",
"description": "Administrative access to the entire Organization",
"permissions": [
"#zones:read"
]
}
]
}
],
"result_info": {
"page": 1,
"per_page": 20,
"count": 1,
"total_count": 2000
}
}`)
})
members, paginator, err := client.OrganizationMembers("01a7362d577a6c3019a474fd6f485823")
want := []OrganizationMember{{
ID: "7c5dae5552338874e5053f2534d2767a",
Name: "John Smith",
Email: "user@example.com",
Status: "accepted",
Roles: []OrganizationRole{{
ID: "3536bcfad5faccb999b47003c79917fb",
Name: "Organization Admin",
Description: "Administrative access to the entire Organization",
Permissions: []string{
"#zones:read",
},
}},
}}
if assert.NoError(t, err) {
assert.Equal(t, members, want)
}
wantPagination := ResultInfo{
Page: 1,
PerPage: 20,
Count: 1,
Total: 2000,
}
assert.Equal(t, paginator, wantPagination)
}
func TestOrganizations_OrganizationInvites(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/organizations/01a7362d577a6c3019a474fd6f485823/invites", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": [
{
"id": "4f5f0c14a2a41d5063dd301b2f829f04",
"invited_member_id": "5a7805061c76ada191ed06f989cc3dac",
"invited_member_email": "user@example.com",
"organization_id": "5a7805061c76ada191ed06f989cc3dac",
"organization_name": "Cloudflare, Inc.",
"roles": [
{
"id": "3536bcfad5faccb999b47003c79917fb",
"name": "Organization Admin",
"description": "Administrative access to the entire Organization",
"permissions": [
"#zones:read"
]
}
],
"invited_by": "user@example.com",
"invited_on": "2014-01-01T05:20:00Z",
"expires_on": "2014-01-01T05:20:00Z",
"status": "accepted"
}
],
"result_info": {
"page": 1,
"per_page": 20,
"count": 1,
"total_count": 2000
}
}`)
})
members, paginator, err := client.OrganizationInvites("01a7362d577a6c3019a474fd6f485823")
invitedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
expiresOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z")
want := []OrganizationInvite{{
ID: "4f5f0c14a2a41d5063dd301b2f829f04",
InvitedMemberID: "5a7805061c76ada191ed06f989cc3dac",
InvitedMemberEmail: "user@example.com",
OrganizationID: "5a7805061c76ada191ed06f989cc3dac",
OrganizationName: "Cloudflare, Inc.",
Roles: []OrganizationRole{{
ID: "3536bcfad5faccb999b47003c79917fb",
Name: "Organization Admin",
Description: "Administrative access to the entire Organization",
Permissions: []string{
"#zones:read",
}}},
InvitedBy: "user@example.com",
InvitedOn: &invitedOn,
ExpiresOn: &expiresOn,
Status: "accepted",
}}
if assert.NoError(t, err) {
assert.Equal(t, members, want)
}
wantPagination := ResultInfo{
Page: 1,
PerPage: 20,
Count: 1,
Total: 2000,
}
assert.Equal(t, paginator, wantPagination)
}
func TestOrganizations_OrganizationRoles(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/organizations/01a7362d577a6c3019a474fd6f485823/roles", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %s", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": [
{
"id": "3536bcfad5faccb999b47003c79917fb",
"name": "Organization Admin",
"description": "Administrative access to the entire Organization",
"permissions": [
"#zones:read"
]
}
],
"result_info": {
"page": 1,
"per_page": 20,
"count": 1,
"total_count": 2000
}
}`)
})
members, paginator, err := client.OrganizationRoles("01a7362d577a6c3019a474fd6f485823")
want := []OrganizationRole{{
ID: "3536bcfad5faccb999b47003c79917fb",
Name: "Organization Admin",
Description: "Administrative access to the entire Organization",
Permissions: []string{
"#zones:read",
}}}
if assert.NoError(t, err) {
assert.Equal(t, members, want)
}
wantPagination := ResultInfo{
Page: 1,
PerPage: 20,
Count: 1,
Total: 2000,
}
assert.Equal(t, paginator, wantPagination)
}

168
vendor/github.com/cloudflare/cloudflare-go/origin_ca.go generated vendored Normal file
View File

@ -0,0 +1,168 @@
package cloudflare
import (
"encoding/json"
"net/url"
"time"
"github.com/pkg/errors"
)
// OriginCACertificate represents a Cloudflare-issued certificate.
//
// API reference: https://api.cloudflare.com/#cloudflare-ca
type OriginCACertificate struct {
ID string `json:"id"`
Certificate string `json:"certificate"`
Hostnames []string `json:"hostnames"`
ExpiresOn time.Time `json:"expires_on"`
RequestType string `json:"request_type"`
RequestValidity int `json:"requested_validity"`
CSR string `json:"csr"`
}
// OriginCACertificateListOptions represents the parameters used to list Cloudflare-issued certificates.
type OriginCACertificateListOptions struct {
ZoneID string
}
// OriginCACertificateID represents the ID of the revoked certificate from the Revoke Certificate endpoint.
type OriginCACertificateID struct {
ID string `json:"id"`
}
// originCACertificateResponse represents the response from the Create Certificate and the Certificate Details endpoints.
type originCACertificateResponse struct {
Response
Result OriginCACertificate `json:"result"`
}
// originCACertificateResponseList represents the response from the List Certificates endpoint.
type originCACertificateResponseList struct {
Response
Result []OriginCACertificate `json:"result"`
ResultInfo ResultInfo `json:"result_info"`
}
// originCACertificateResponseRevoke represents the response from the Revoke Certificate endpoint.
type originCACertificateResponseRevoke struct {
Response
Result OriginCACertificateID `json:"result"`
}
// CreateOriginCertificate creates a Cloudflare-signed certificate.
//
// This function requires api.APIUserServiceKey be set to your Certificates API key.
//
// API reference: https://api.cloudflare.com/#cloudflare-ca-create-certificate
func (api *API) CreateOriginCertificate(certificate OriginCACertificate) (*OriginCACertificate, error) {
uri := "/certificates"
res, err := api.makeRequestWithAuthType("POST", uri, certificate, AuthUserService)
if err != nil {
return nil, errors.Wrap(err, errMakeRequestError)
}
var originResponse *originCACertificateResponse
err = json.Unmarshal(res, &originResponse)
if err != nil {
return nil, errors.Wrap(err, errUnmarshalError)
}
if !originResponse.Success {
return nil, errors.New(errRequestNotSuccessful)
}
return &originResponse.Result, nil
}
// OriginCertificates lists all Cloudflare-issued certificates.
//
// This function requires api.APIUserServiceKey be set to your Certificates API key.
//
// API reference: https://api.cloudflare.com/#cloudflare-ca-list-certificates
func (api *API) OriginCertificates(options OriginCACertificateListOptions) ([]OriginCACertificate, error) {
v := url.Values{}
if options.ZoneID != "" {
v.Set("zone_id", options.ZoneID)
}
uri := "/certificates" + "?" + v.Encode()
res, err := api.makeRequestWithAuthType("GET", uri, nil, AuthUserService)
if err != nil {
return nil, errors.Wrap(err, errMakeRequestError)
}
var originResponse *originCACertificateResponseList
err = json.Unmarshal(res, &originResponse)
if err != nil {
return nil, errors.Wrap(err, errUnmarshalError)
}
if !originResponse.Success {
return nil, errors.New(errRequestNotSuccessful)
}
return originResponse.Result, nil
}
// OriginCertificate returns the details for a Cloudflare-issued certificate.
//
// This function requires api.APIUserServiceKey be set to your Certificates API key.
//
// API reference: https://api.cloudflare.com/#cloudflare-ca-certificate-details
func (api *API) OriginCertificate(certificateID string) (*OriginCACertificate, error) {
uri := "/certificates/" + certificateID
res, err := api.makeRequestWithAuthType("GET", uri, nil, AuthUserService)
if err != nil {
return nil, errors.Wrap(err, errMakeRequestError)
}
var originResponse *originCACertificateResponse
err = json.Unmarshal(res, &originResponse)
if err != nil {
return nil, errors.Wrap(err, errUnmarshalError)
}
if !originResponse.Success {
return nil, errors.New(errRequestNotSuccessful)
}
return &originResponse.Result, nil
}
// RevokeOriginCertificate revokes a created certificate for a zone.
//
// This function requires api.APIUserServiceKey be set to your Certificates API key.
//
// API reference: https://api.cloudflare.com/#cloudflare-ca-revoke-certificate
func (api *API) RevokeOriginCertificate(certificateID string) (*OriginCACertificateID, error) {
uri := "/certificates/" + certificateID
res, err := api.makeRequestWithAuthType("DELETE", uri, nil, AuthUserService)
if err != nil {
return nil, errors.Wrap(err, errMakeRequestError)
}
var originResponse *originCACertificateResponseRevoke
err = json.Unmarshal(res, &originResponse)
if err != nil {
return nil, errors.Wrap(err, errUnmarshalError)
}
if !originResponse.Success {
return nil, errors.New(errRequestNotSuccessful)
}
return &originResponse.Result, nil
}

View File

@ -0,0 +1,187 @@
package cloudflare
import (
"fmt"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestOriginCA_CreateOriginCertificate(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/certificates", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "POST", r.Method, "Expected method 'POST', got %ss", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "0x47530d8f561faa08",
"certificate": "-----BEGIN CERTIFICATE-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE-----",
"hostnames": [
"example.com",
"*.another.com"
],
"expires_on": "2014-01-01T05:20:00.12345Z",
"request_type": "origin-rsa",
"requested_validity": 5475,
"csr": "-----BEGIN CERTIFICATE REQUEST-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE REQUEST-----"
}
}`)
})
expiresOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
testCertificate := OriginCACertificate{
ID: "0x47530d8f561faa08",
Certificate: "-----BEGIN CERTIFICATE-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE-----",
Hostnames: []string{"example.com", "*.another.com"},
ExpiresOn: expiresOn,
RequestType: "origin-rsa",
RequestValidity: 5475,
CSR: "-----BEGIN CERTIFICATE REQUEST-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE REQUEST-----",
}
createdCertificate, err := client.CreateOriginCertificate(testCertificate)
if assert.NoError(t, err) {
assert.Equal(t, createdCertificate, &testCertificate)
}
}
func TestOriginCA_OriginCertificates(t *testing.T) {
setup()
defer teardown()
testZoneID := "023e105f4ecef8ad9ca31a8372d0c353"
mux.HandleFunc("/certificates", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %ss", r.Method)
assert.Equal(t, testZoneID, r.URL.Query().Get("zone_id"), "Expected zone_id '', got %%s", testZoneID)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": [
{
"id": "0x47530d8f561faa08",
"certificate": "-----BEGIN CERTIFICATE-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE-----",
"hostnames": [
"example.com",
"*.another.com"
],
"expires_on": "2014-01-01T05:20:00.12345Z",
"request_type": "origin-rsa",
"requested_validity": 5475,
"csr": "-----BEGIN CERTIFICATE REQUEST-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE REQUEST-----"
}
],
"result_info": {
"page": 1,
"per_page": 20,
"count": 1,
"total_count": 2000
}
}`)
})
expiresOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
testCertificate := OriginCACertificate{
ID: "0x47530d8f561faa08",
Certificate: "-----BEGIN CERTIFICATE-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE-----",
Hostnames: []string{"example.com", "*.another.com"},
ExpiresOn: expiresOn,
RequestType: "origin-rsa",
RequestValidity: 5475,
CSR: "-----BEGIN CERTIFICATE REQUEST-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE REQUEST-----",
}
certs, err := client.OriginCertificates(OriginCACertificateListOptions{ZoneID: testZoneID})
if assert.NoError(t, err) {
assert.IsType(t, []OriginCACertificate{}, certs, "Expected type []OriginCACertificate and got %v", certs)
assert.Equal(t, certs[0], testCertificate)
}
}
func TestOriginCA_OriginCertificate(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/certificates/0x47530d8f561faa08", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Expected method 'GET', got %ss", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "0x47530d8f561faa08",
"certificate": "-----BEGIN CERTIFICATE-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE-----",
"hostnames": [
"example.com",
"*.another.com"
],
"expires_on": "2014-01-01T05:20:00.12345Z",
"request_type": "origin-rsa",
"requested_validity": 5475,
"csr": "-----BEGIN CERTIFICATE REQUEST-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE REQUEST-----"
}
}`)
})
expiresOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
testCertificate := OriginCACertificate{
ID: "0x47530d8f561faa08",
Certificate: "-----BEGIN CERTIFICATE-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE-----",
Hostnames: []string{"example.com", "*.another.com"},
ExpiresOn: expiresOn,
RequestType: "origin-rsa",
RequestValidity: 5475,
CSR: "-----BEGIN CERTIFICATE REQUEST-----MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNVBAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGlnaUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmowp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiIWDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZwIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPRBPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6DhJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpYQ4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO297Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w=-----END CERTIFICATE REQUEST-----",
}
cert, err := client.OriginCertificate(testCertificate.ID)
if assert.NoError(t, err) {
assert.IsType(t, &OriginCACertificate{}, cert, "Expected type &OriginCACertificate and got %v", cert)
assert.Equal(t, cert, &testCertificate)
}
}
func TestOriginCA_RevokeCertificate(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/certificates/0x47530d8f561faa08", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "DELETE", r.Method, "Expected method 'DELETE', got %ss", r.Method)
w.Header().Set("content-type", "application/json")
fmt.Fprintf(w, `{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "0x47530d8f561faa08"
}
}`)
})
testCertificate := OriginCACertificateID{
ID: "0x47530d8f561faa08",
}
cert, err := client.RevokeOriginCertificate(testCertificate.ID)
if assert.NoError(t, err) {
assert.IsType(t, &OriginCACertificateID{}, cert, "Expected type &OriginCACertificateID and got %v", cert)
assert.Equal(t, cert, &testCertificate)
}
}

View File

@ -7,12 +7,10 @@ import (
"github.com/pkg/errors"
)
/*
PageRuleTarget is the target to evaluate on a request.
Currently Target must always be "url" and Operator must be "matches". Value
is the URL pattern to match against.
*/
// PageRuleTarget is the target to evaluate on a request.
//
// Currently Target must always be "url" and Operator must be "matches". Value
// is the URL pattern to match against.
type PageRuleTarget struct {
Target string `json:"target"`
Constraint struct {
@ -52,7 +50,7 @@ type PageRuleAction struct {
Value interface{} `json:"value"`
}
// PageRuleActions maps API action IDs to human-readable strings
// PageRuleActions maps API action IDs to human-readable strings.
var PageRuleActions = map[string]string{
"always_online": "Always Online", // Value of type string
"always_use_https": "Always Use HTTPS", // Value of type interface{}
@ -103,13 +101,9 @@ type PageRulesResponse struct {
Result []PageRule `json:"result"`
}
/*
CreatePageRule creates a new Page Rule for a zone.
API reference:
https://api.cloudflare.com/#page-rules-for-a-zone-create-a-page-rule
POST /zones/:zone_identifier/pagerules
*/
// CreatePageRule creates a new Page Rule for a zone.
//
// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-create-a-page-rule
func (api *API) CreatePageRule(zoneID string, rule PageRule) error {
uri := "/zones/" + zoneID + "/pagerules"
res, err := api.makeRequest("POST", uri, rule)
@ -124,13 +118,9 @@ func (api *API) CreatePageRule(zoneID string, rule PageRule) error {
return nil
}
/*
ListPageRules returns all Page Rules for a zone.
API reference:
https://api.cloudflare.com/#page-rules-for-a-zone-list-page-rules
GET /zones/:zone_identifier/pagerules
*/
// ListPageRules returns all Page Rules for a zone.
//
// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-list-page-rules
func (api *API) ListPageRules(zoneID string) ([]PageRule, error) {
uri := "/zones/" + zoneID + "/pagerules"
res, err := api.makeRequest("GET", uri, nil)
@ -145,13 +135,9 @@ func (api *API) ListPageRules(zoneID string) ([]PageRule, error) {
return r.Result, nil
}
/*
PageRule fetches detail about one Page Rule for a zone.
API reference:
https://api.cloudflare.com/#page-rules-for-a-zone-page-rule-details
GET /zones/:zone_identifier/pagerules/:identifier
*/
// PageRule fetches detail about one Page Rule for a zone.
//
// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-page-rule-details
func (api *API) PageRule(zoneID, ruleID string) (PageRule, error) {
uri := "/zones/" + zoneID + "/pagerules/" + ruleID
res, err := api.makeRequest("GET", uri, nil)
@ -166,14 +152,10 @@ func (api *API) PageRule(zoneID, ruleID string) (PageRule, error) {
return r.Result, nil
}
/*
ChangePageRule lets change individual settings for a Page Rule. This is in
contrast to UpdatePageRule which replaces the entire Page Rule.
API reference:
https://api.cloudflare.com/#page-rules-for-a-zone-change-a-page-rule
PATCH /zones/:zone_identifier/pagerules/:identifier
*/
// ChangePageRule lets you change individual settings for a Page Rule. This is
// in contrast to UpdatePageRule which replaces the entire Page Rule.
//
// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-change-a-page-rule
func (api *API) ChangePageRule(zoneID, ruleID string, rule PageRule) error {
uri := "/zones/" + zoneID + "/pagerules/" + ruleID
res, err := api.makeRequest("PATCH", uri, rule)
@ -188,14 +170,10 @@ func (api *API) ChangePageRule(zoneID, ruleID string, rule PageRule) error {
return nil
}
/*
UpdatePageRule lets you replace a Page Rule. This is in contrast to
ChangePageRule which lets you change individual settings.
API reference:
https://api.cloudflare.com/#page-rules-for-a-zone-update-a-page-rule
PUT /zones/:zone_identifier/pagerules/:identifier
*/
// UpdatePageRule lets you replace a Page Rule. This is in contrast to
// ChangePageRule which lets you change individual settings.
//
// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-update-a-page-rule
func (api *API) UpdatePageRule(zoneID, ruleID string, rule PageRule) error {
uri := "/zones/" + zoneID + "/pagerules/" + ruleID
res, err := api.makeRequest("PUT", uri, nil)
@ -210,13 +188,9 @@ func (api *API) UpdatePageRule(zoneID, ruleID string, rule PageRule) error {
return nil
}
/*
DeletePageRule deletes a Page Rule for a zone.
API reference:
https://api.cloudflare.com/#page-rules-for-a-zone-delete-a-page-rule
DELETE /zones/:zone_identifier/pagerules/:identifier
*/
// DeletePageRule deletes a Page Rule for a zone.
//
// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-delete-a-page-rule
func (api *API) DeletePageRule(zoneID, ruleID string) error {
uri := "/zones/" + zoneID + "/pagerules/" + ruleID
res, err := api.makeRequest("DELETE", uri, nil)

View File

@ -46,9 +46,8 @@ type railgunsResponse struct {
}
// CreateRailgun creates a new Railgun.
// API reference:
// https://api.cloudflare.com/#railgun-create-railgun
// POST /railguns
//
// API reference: https://api.cloudflare.com/#railgun-create-railgun
func (api *API) CreateRailgun(name string) (Railgun, error) {
uri := "/railguns"
params := struct {
@ -68,9 +67,8 @@ func (api *API) CreateRailgun(name string) (Railgun, error) {
}
// ListRailguns lists Railguns connected to an account.
// API reference:
// https://api.cloudflare.com/#railgun-list-railguns
// GET /railguns
//
// API reference: https://api.cloudflare.com/#railgun-list-railguns
func (api *API) ListRailguns(options RailgunListOptions) ([]Railgun, error) {
v := url.Values{}
if options.Direction != "" {
@ -89,9 +87,8 @@ func (api *API) ListRailguns(options RailgunListOptions) ([]Railgun, error) {
}
// RailgunDetails returns the details for a Railgun.
// API reference:
// https://api.cloudflare.com/#railgun-railgun-details
// GET /railguns/:identifier
//
// API reference: https://api.cloudflare.com/#railgun-railgun-details
func (api *API) RailgunDetails(railgunID string) (Railgun, error) {
uri := "/railguns/" + railgunID
res, err := api.makeRequest("GET", uri, nil)
@ -106,9 +103,8 @@ func (api *API) RailgunDetails(railgunID string) (Railgun, error) {
}
// RailgunZones returns the zones that are currently using a Railgun.
// API reference:
// https://api.cloudflare.com/#railgun-get-zones-connected-to-a-railgun
// GET /railguns/:identifier/zones
//
// API reference: https://api.cloudflare.com/#railgun-get-zones-connected-to-a-railgun
func (api *API) RailgunZones(railgunID string) ([]Zone, error) {
uri := "/railguns/" + railgunID + "/zones"
res, err := api.makeRequest("GET", uri, nil)
@ -123,9 +119,8 @@ func (api *API) RailgunZones(railgunID string) ([]Zone, error) {
}
// enableRailgun enables (true) or disables (false) a Railgun for all zones connected to it.
// API reference:
// https://api.cloudflare.com/#railgun-enable-or-disable-a-railgun
// PATCH /railguns/:identifier
//
// API reference: https://api.cloudflare.com/#railgun-enable-or-disable-a-railgun
func (api *API) enableRailgun(railgunID string, enable bool) (Railgun, error) {
uri := "/railguns/" + railgunID
params := struct {
@ -145,25 +140,22 @@ func (api *API) enableRailgun(railgunID string, enable bool) (Railgun, error) {
}
// EnableRailgun enables a Railgun for all zones connected to it.
// API reference:
// https://api.cloudflare.com/#railgun-enable-or-disable-a-railgun
// PATCH /railguns/:identifier
//
// API reference: https://api.cloudflare.com/#railgun-enable-or-disable-a-railgun
func (api *API) EnableRailgun(railgunID string) (Railgun, error) {
return api.enableRailgun(railgunID, true)
}
// DisableRailgun enables a Railgun for all zones connected to it.
// API reference:
// https://api.cloudflare.com/#railgun-enable-or-disable-a-railgun
// PATCH /railguns/:identifier
//
// API reference: https://api.cloudflare.com/#railgun-enable-or-disable-a-railgun
func (api *API) DisableRailgun(railgunID string) (Railgun, error) {
return api.enableRailgun(railgunID, false)
}
// DeleteRailgun disables and deletes a Railgun.
// API reference:
// https://api.cloudflare.com/#railgun-delete-railgun
// DELETE /railguns/:identifier
//
// API reference: https://api.cloudflare.com/#railgun-delete-railgun
func (api *API) DeleteRailgun(railgunID string) error {
uri := "/railguns/" + railgunID
if _, err := api.makeRequest("DELETE", uri, nil); err != nil {
@ -222,9 +214,8 @@ type railgunDiagnosisResponse struct {
}
// ZoneRailguns returns the available Railguns for a zone.
// API reference:
// https://api.cloudflare.com/#railguns-for-a-zone-get-available-railguns
// GET /zones/:zone_identifier/railguns
//
// API reference: https://api.cloudflare.com/#railguns-for-a-zone-get-available-railguns
func (api *API) ZoneRailguns(zoneID string) ([]ZoneRailgun, error) {
uri := "/zones/" + zoneID + "/railguns"
res, err := api.makeRequest("GET", uri, nil)
@ -239,9 +230,8 @@ func (api *API) ZoneRailguns(zoneID string) ([]ZoneRailgun, error) {
}
// ZoneRailgunDetails returns the configuration for a given Railgun.
// API reference:
// https://api.cloudflare.com/#railguns-for-a-zone-get-railgun-details
// GET /zones/:zone_identifier/railguns/:identifier
//
// API reference: https://api.cloudflare.com/#railguns-for-a-zone-get-railgun-details
func (api *API) ZoneRailgunDetails(zoneID, railgunID string) (ZoneRailgun, error) {
uri := "/zones/" + zoneID + "/railguns/" + railgunID
res, err := api.makeRequest("GET", uri, nil)
@ -256,9 +246,8 @@ func (api *API) ZoneRailgunDetails(zoneID, railgunID string) (ZoneRailgun, error
}
// TestRailgunConnection tests a Railgun connection for a given zone.
// API reference:
// https://api.cloudflare.com/#railgun-connections-for-a-zone-test-railgun-connection
// GET /zones/:zone_identifier/railguns/:identifier/diagnose
//
// API reference: https://api.cloudflare.com/#railgun-connections-for-a-zone-test-railgun-connection
func (api *API) TestRailgunConnection(zoneID, railgunID string) (RailgunDiagnosis, error) {
uri := "/zones/" + zoneID + "/railguns/" + railgunID + "/diagnose"
res, err := api.makeRequest("GET", uri, nil)
@ -273,9 +262,8 @@ func (api *API) TestRailgunConnection(zoneID, railgunID string) (RailgunDiagnosi
}
// connectZoneRailgun connects (true) or disconnects (false) a Railgun for a given zone.
// API reference:
// https://api.cloudflare.com/#railguns-for-a-zone-connect-or-disconnect-a-railgun
// PATCH /zones/:zone_identifier/railguns/:identifier
//
// API reference: https://api.cloudflare.com/#railguns-for-a-zone-connect-or-disconnect-a-railgun
func (api *API) connectZoneRailgun(zoneID, railgunID string, connect bool) (ZoneRailgun, error) {
uri := "/zones/" + zoneID + "/railguns/" + railgunID
params := struct {
@ -295,17 +283,15 @@ func (api *API) connectZoneRailgun(zoneID, railgunID string, connect bool) (Zone
}
// ConnectZoneRailgun connects a Railgun for a given zone.
// API reference:
// https://api.cloudflare.com/#railguns-for-a-zone-connect-or-disconnect-a-railgun
// PATCH /zones/:zone_identifier/railguns/:identifier
//
// API reference: https://api.cloudflare.com/#railguns-for-a-zone-connect-or-disconnect-a-railgun
func (api *API) ConnectZoneRailgun(zoneID, railgunID string) (ZoneRailgun, error) {
return api.connectZoneRailgun(zoneID, railgunID, true)
}
// DisconnectZoneRailgun disconnects a Railgun for a given zone.
// API reference:
// https://api.cloudflare.com/#railguns-for-a-zone-connect-or-disconnect-a-railgun
// PATCH /zones/:zone_identifier/railguns/:identifier
//
// API reference: https://api.cloudflare.com/#railguns-for-a-zone-connect-or-disconnect-a-railgun
func (api *API) DisconnectZoneRailgun(zoneID, railgunID string) (ZoneRailgun, error) {
return api.connectZoneRailgun(zoneID, railgunID, false)
}

View File

@ -51,9 +51,8 @@ type ZoneCustomSSLPriority struct {
}
// CreateSSL allows you to add a custom SSL certificate to the given zone.
// API reference:
// https://api.cloudflare.com/#custom-ssl-for-a-zone-create-ssl-configuration
// POST /zones/:zone_identifier/custom_certificates
//
// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-create-ssl-configuration
func (api *API) CreateSSL(zoneID string, options ZoneCustomSSLOptions) (ZoneCustomSSL, error) {
uri := "/zones/" + zoneID + "/custom_certificates"
res, err := api.makeRequest("POST", uri, options)
@ -68,9 +67,8 @@ func (api *API) CreateSSL(zoneID string, options ZoneCustomSSLOptions) (ZoneCust
}
// ListSSL lists the custom certificates for the given zone.
// API reference:
// https://api.cloudflare.com/#custom-ssl-for-a-zone-list-ssl-configurations
// GET /zones/:zone_identifier/custom_certificates
//
// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-list-ssl-configurations
func (api *API) ListSSL(zoneID string) ([]ZoneCustomSSL, error) {
uri := "/zones/" + zoneID + "/custom_certificates"
res, err := api.makeRequest("GET", uri, nil)
@ -85,9 +83,8 @@ func (api *API) ListSSL(zoneID string) ([]ZoneCustomSSL, error) {
}
// SSLDetails returns the configuration details for a custom SSL certificate.
// API reference:
// https://api.cloudflare.com/#custom-ssl-for-a-zone-ssl-configuration-details
// GET /zones/:zone_identifier/custom_certificates/:identifier
//
// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-ssl-configuration-details
func (api *API) SSLDetails(zoneID, certificateID string) (ZoneCustomSSL, error) {
uri := "/zones/" + zoneID + "/custom_certificates/" + certificateID
res, err := api.makeRequest("GET", uri, nil)
@ -102,9 +99,8 @@ func (api *API) SSLDetails(zoneID, certificateID string) (ZoneCustomSSL, error)
}
// UpdateSSL updates (replaces) a custom SSL certificate.
// API reference:
// https://api.cloudflare.com/#custom-ssl-for-a-zone-update-ssl-configuration
// PATCH /zones/:zone_identifier/custom_certificates/:identifier
//
// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-update-ssl-configuration
func (api *API) UpdateSSL(zoneID, certificateID string, options ZoneCustomSSLOptions) (ZoneCustomSSL, error) {
uri := "/zones/" + zoneID + "/custom_certificates/" + certificateID
res, err := api.makeRequest("PATCH", uri, options)
@ -120,9 +116,8 @@ func (api *API) UpdateSSL(zoneID, certificateID string, options ZoneCustomSSLOpt
// ReprioritizeSSL allows you to change the priority (which is served for a given
// request) of custom SSL certificates associated with the given zone.
// API reference:
// https://api.cloudflare.com/#custom-ssl-for-a-zone-re-prioritize-ssl-certificates
// PUT /zones/:zone_identifier/custom_certificates/prioritize
//
// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-re-prioritize-ssl-certificates
func (api *API) ReprioritizeSSL(zoneID string, p []ZoneCustomSSLPriority) ([]ZoneCustomSSL, error) {
uri := "/zones/" + zoneID + "/custom_certificates/prioritize"
params := struct {
@ -142,9 +137,8 @@ func (api *API) ReprioritizeSSL(zoneID string, p []ZoneCustomSSLPriority) ([]Zon
}
// DeleteSSL deletes a custom SSL certificate from the given zone.
// API reference:
// https://api.cloudflare.com/#custom-ssl-for-a-zone-delete-an-ssl-certificate
// DELETE /zones/:zone_identifier/custom_certificates/:identifier
//
// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-delete-an-ssl-certificate
func (api *API) DeleteSSL(zoneID, certificateID string) error {
uri := "/zones/" + zoneID + "/custom_certificates/" + certificateID
if _, err := api.makeRequest("DELETE", uri, nil); err != nil {

View File

@ -59,9 +59,8 @@ type UserBillingProfile struct {
}
// UserDetails provides information about the logged-in user.
// API reference:
// https://api.cloudflare.com/#user-user-details
// GET /user
//
// API reference: https://api.cloudflare.com/#user-user-details
func (api *API) UserDetails() (User, error) {
var r UserResponse
res, err := api.makeRequest("GET", "/user", nil)
@ -78,9 +77,8 @@ func (api *API) UserDetails() (User, error) {
}
// UpdateUser updates the properties of the given user.
// API reference:
// https://api.cloudflare.com/#user-update-user
// PATCH /user
//
// API reference: https://api.cloudflare.com/#user-update-user
func (api *API) UpdateUser(user *User) (User, error) {
var r UserResponse
res, err := api.makeRequest("PATCH", "/user", user)
@ -97,9 +95,8 @@ func (api *API) UpdateUser(user *User) (User, error) {
}
// UserBillingProfile returns the billing profile of the user.
// API reference:
// https://api.cloudflare.com/#user-billing-profile
// GET /user/billing/profile
//
// API reference: https://api.cloudflare.com/#user-billing-profile
func (api *API) UserBillingProfile() (UserBillingProfile, error) {
var r userBillingProfileResponse
res, err := api.makeRequest("GET", "/user/billing/profile", nil)

View File

@ -31,9 +31,8 @@ type VirtualDNSListResponse struct {
}
// CreateVirtualDNS creates a new Virtual DNS cluster.
// API reference:
// https://api.cloudflare.com/#virtual-dns-users--create-a-virtual-dns-cluster
// POST /user/virtual_dns
//
// API reference: https://api.cloudflare.com/#virtual-dns-users--create-a-virtual-dns-cluster
func (api *API) CreateVirtualDNS(v *VirtualDNS) (*VirtualDNS, error) {
res, err := api.makeRequest("POST", "/user/virtual_dns", v)
if err != nil {
@ -50,9 +49,8 @@ func (api *API) CreateVirtualDNS(v *VirtualDNS) (*VirtualDNS, error) {
}
// VirtualDNS fetches a single virtual DNS cluster.
// API reference:
// https://api.cloudflare.com/#virtual-dns-users--get-a-virtual-dns-cluster
// GET /user/virtual_dns/:identifier
//
// API reference: https://api.cloudflare.com/#virtual-dns-users--get-a-virtual-dns-cluster
func (api *API) VirtualDNS(virtualDNSID string) (*VirtualDNS, error) {
uri := "/user/virtual_dns/" + virtualDNSID
res, err := api.makeRequest("GET", uri, nil)
@ -70,9 +68,8 @@ func (api *API) VirtualDNS(virtualDNSID string) (*VirtualDNS, error) {
}
// ListVirtualDNS lists the virtual DNS clusters associated with an account.
// API reference:
// https://api.cloudflare.com/#virtual-dns-users--get-virtual-dns-clusters
// GET /user/virtual_dns
//
// API reference: https://api.cloudflare.com/#virtual-dns-users--get-virtual-dns-clusters
func (api *API) ListVirtualDNS() ([]*VirtualDNS, error) {
res, err := api.makeRequest("GET", "/user/virtual_dns", nil)
if err != nil {
@ -89,9 +86,8 @@ func (api *API) ListVirtualDNS() ([]*VirtualDNS, error) {
}
// UpdateVirtualDNS updates a Virtual DNS cluster.
// API reference:
// https://api.cloudflare.com/#virtual-dns-users--modify-a-virtual-dns-cluster
// PATCH /user/virtual_dns/:identifier
//
// API reference: https://api.cloudflare.com/#virtual-dns-users--modify-a-virtual-dns-cluster
func (api *API) UpdateVirtualDNS(virtualDNSID string, vv VirtualDNS) error {
uri := "/user/virtual_dns/" + virtualDNSID
res, err := api.makeRequest("PUT", uri, vv)
@ -110,9 +106,8 @@ func (api *API) UpdateVirtualDNS(virtualDNSID string, vv VirtualDNS) error {
// DeleteVirtualDNS deletes a Virtual DNS cluster. Note that this cannot be
// undone, and will stop all traffic to that cluster.
// API reference:
// https://api.cloudflare.com/#virtual-dns-users--delete-a-virtual-dns-cluster
// DELETE /user/virtual_dns/:identifier
//
// API reference: https://api.cloudflare.com/#virtual-dns-users--delete-a-virtual-dns-cluster
func (api *API) DeleteVirtualDNS(virtualDNSID string) error {
uri := "/user/virtual_dns/" + virtualDNSID
res, err := api.makeRequest("DELETE", uri, nil)

View File

@ -18,22 +18,24 @@ type Owner struct {
// Zone describes a Cloudflare zone.
type Zone struct {
ID string `json:"id"`
Name string `json:"name"`
DevMode int `json:"development_mode"`
OriginalNS []string `json:"original_name_servers"`
OriginalRegistrar string `json:"original_registrar"`
OriginalDNSHost string `json:"original_dnshost"`
CreatedOn time.Time `json:"created_on"`
ModifiedOn time.Time `json:"modified_on"`
NameServers []string `json:"name_servers"`
Owner Owner `json:"owner"`
Permissions []string `json:"permissions"`
Plan ZonePlan `json:"plan"`
PlanPending ZonePlan `json:"plan_pending,omitempty"`
Status string `json:"status"`
Paused bool `json:"paused"`
Type string `json:"type"`
ID string `json:"id"`
Name string `json:"name"`
// DevMode contains the time in seconds until development expires (if
// positive) or since it expired (if negative). It will be 0 if never used.
DevMode int `json:"development_mode"`
OriginalNS []string `json:"original_name_servers"`
OriginalRegistrar string `json:"original_registrar"`
OriginalDNSHost string `json:"original_dnshost"`
CreatedOn time.Time `json:"created_on"`
ModifiedOn time.Time `json:"modified_on"`
NameServers []string `json:"name_servers"`
Owner Owner `json:"owner"`
Permissions []string `json:"permissions"`
Plan ZoneRatePlan `json:"plan"`
PlanPending ZoneRatePlan `json:"plan_pending,omitempty"`
Status string `json:"status"`
Paused bool `json:"paused"`
Type string `json:"type"`
Host struct {
Name string
Website string
@ -44,7 +46,7 @@ type Zone struct {
Meta ZoneMeta `json:"meta"`
}
// ZoneMeta metadata about a zone.
// ZoneMeta describes metadata about a zone.
type ZoneMeta struct {
// custom_certificate_quota is broken - sometimes it's a string, sometimes a number!
// CustCertQuota int `json:"custom_certificate_quota"`
@ -53,16 +55,21 @@ type ZoneMeta struct {
PhishingDetected bool `json:"phishing_detected"`
}
// ZonePlan contains the plan information for a zone.
type ZonePlan struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Price int `json:"price,omitempty"`
Currency string `json:"currency,omitempty"`
Frequency string `json:"frequency,omitempty"`
LegacyID string `json:"legacy_id,omitempty"`
IsSubscribed bool `json:"is_subscribed,omitempty"`
CanSubscribe bool `json:"can_subscribe,omitempty"`
// ZoneRatePlan contains the plan information for a zone.
type ZoneRatePlan struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Price int `json:"price,omitempty"`
Currency string `json:"currency,omitempty"`
Duration int `json:"duration,omitempty"`
Frequency string `json:"frequency,omitempty"`
Components []zoneRatePlanComponents `json:"components,omitempty"`
}
type zoneRatePlanComponents struct {
Name string `json:"name"`
Default int `json:"Default"`
UnitPrice int `json:"unit_price"`
}
// ZoneID contains only the zone ID.
@ -88,17 +95,17 @@ type ZoneIDResponse struct {
Result ZoneID `json:"result"`
}
// AvailableZonePlansResponse represents the response from the Available Plans endpoint.
type AvailableZonePlansResponse struct {
// AvailableZoneRatePlansResponse represents the response from the Available Rate Plans endpoint.
type AvailableZoneRatePlansResponse struct {
Response
Result []ZonePlan `json:"result"`
Result []ZoneRatePlan `json:"result"`
ResultInfo
}
// ZonePlanResponse represents the response from the Plan Details endpoint.
type ZonePlanResponse struct {
// ZoneRatePlanResponse represents the response from the Plan Details endpoint.
type ZoneRatePlanResponse struct {
Response
Result ZonePlan `json:"result"`
Result ZoneRatePlan `json:"result"`
}
// ZoneSetting contains settings for a zone.
@ -116,6 +123,21 @@ type ZoneSettingResponse struct {
Result []ZoneSetting `json:"result"`
}
// ZoneSSLSetting contains ssl setting for a zone.
type ZoneSSLSetting struct {
ID string `json:"id"`
Editable bool `json:"editable"`
ModifiedOn string `json:"modified_on"`
Value string `json:"value"`
CertificateStatus string `json:"certificate_status"`
}
// ZoneSettingResponse represents the response from the Zone SSL Setting endpoint.
type ZoneSSLSettingResponse struct {
Response
Result ZoneSSLSetting `json:"result"`
}
// ZoneAnalyticsData contains totals and timeseries analytics data for a zone.
type ZoneAnalyticsData struct {
Totals ZoneAnalytics `json:"totals"`
@ -212,6 +234,12 @@ type newZone struct {
// CreateZone creates a zone on an account.
//
// Setting jumpstart to true will attempt to automatically scan for existing
// DNS records. Setting this to false will create the zone with no DNS records.
//
// If Organization is non-empty, it must have at least the ID field populated.
// This will add the new zone to the specified multi-user organization.
//
// API reference: https://api.cloudflare.com/#zone-create-a-zone
func (api *API) CreateZone(name string, jumpstart bool, org Organization) (Zone, error) {
var newzone newZone
@ -315,17 +343,15 @@ func (api *API) ZoneDetails(zoneID string) (Zone, error) {
// ZoneOptions is a subset of Zone, for editable options.
type ZoneOptions struct {
// FIXME(jamesog): Using omitempty here means we can't disable Paused.
// Currently unsure how to work around this.
Paused bool `json:"paused,omitempty"`
VanityNS []string `json:"vanity_name_servers,omitempty"`
Plan *ZonePlan `json:"plan,omitempty"`
Paused *bool `json:"paused,omitempty"`
VanityNS []string `json:"vanity_name_servers,omitempty"`
Plan *ZoneRatePlan `json:"plan,omitempty"`
}
// ZoneSetPaused pauses Cloudflare service for the entire zone, sending all
// traffic direct to the origin.
func (api *API) ZoneSetPaused(zoneID string, paused bool) (Zone, error) {
zoneopts := ZoneOptions{Paused: paused}
zoneopts := ZoneOptions{Paused: &paused}
zone, err := api.EditZone(zoneID, zoneopts)
if err != nil {
return Zone{}, err
@ -346,8 +372,8 @@ func (api *API) ZoneSetVanityNS(zoneID string, ns []string) (Zone, error) {
return zone, nil
}
// ZoneSetPlan changes the zone plan.
func (api *API) ZoneSetPlan(zoneID string, plan ZonePlan) (Zone, error) {
// ZoneSetRatePlan changes the zone plan.
func (api *API) ZoneSetRatePlan(zoneID string, plan ZoneRatePlan) (Zone, error) {
zoneopts := ZoneOptions{Plan: &plan}
zone, err := api.EditZone(zoneID, zoneopts)
if err != nil {
@ -358,6 +384,7 @@ func (api *API) ZoneSetPlan(zoneID string, plan ZonePlan) (Zone, error) {
}
// EditZone edits the given zone.
//
// This is usually called by ZoneSetPaused, ZoneSetVanityNS or ZoneSetPlan.
//
// API reference: https://api.cloudflare.com/#zone-edit-zone-properties
@ -376,6 +403,7 @@ func (api *API) EditZone(zoneID string, zoneOpts ZoneOptions) (Zone, error) {
}
// PurgeEverything purges the cache for the given zone.
//
// Note: this will substantially increase load on the origin server for that
// zone if there is a high cached vs. uncached request ratio.
//
@ -427,36 +455,19 @@ func (api *API) DeleteZone(zoneID string) (ZoneID, error) {
return r.Result, nil
}
// AvailableZonePlans returns information about all plans available to the specified zone.
// AvailableZoneRatePlans returns information about all plans available to the specified zone.
//
// API reference: https://api.cloudflare.com/#zone-plan-available-plans
func (api *API) AvailableZonePlans(zoneID string) ([]ZonePlan, error) {
uri := "/zones/" + zoneID + "/available_plans"
func (api *API) AvailableZoneRatePlans(zoneID string) ([]ZoneRatePlan, error) {
uri := "/zones/" + zoneID + "/available_rate_plans"
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return []ZonePlan{}, errors.Wrap(err, errMakeRequestError)
return []ZoneRatePlan{}, errors.Wrap(err, errMakeRequestError)
}
var r AvailableZonePlansResponse
var r AvailableZoneRatePlansResponse
err = json.Unmarshal(res, &r)
if err != nil {
return []ZonePlan{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}
// ZonePlanDetails returns information about a zone plan.
//
// API reference: https://api.cloudflare.com/#zone-plan-plan-details
func (api *API) ZonePlanDetails(zoneID, planID string) (ZonePlan, error) {
uri := "/zones/" + zoneID + "/available_plans/" + planID
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return ZonePlan{}, errors.Wrap(err, errMakeRequestError)
}
var r ZonePlanResponse
err = json.Unmarshal(res, &r)
if err != nil {
return ZonePlan{}, errors.Wrap(err, errUnmarshalError)
return []ZoneRatePlan{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}
@ -478,9 +489,7 @@ func (o ZoneAnalyticsOptions) encode() string {
// ZoneAnalyticsDashboard returns zone analytics information.
//
// API reference:
// https://api.cloudflare.com/#zone-analytics-dashboard
// GET /zones/:zone_identifier/analytics/dashboard
// API reference: https://api.cloudflare.com/#zone-analytics-dashboard
func (api *API) ZoneAnalyticsDashboard(zoneID string, options ZoneAnalyticsOptions) (ZoneAnalyticsData, error) {
uri := "/zones/" + zoneID + "/analytics/dashboard" + "?" + options.encode()
res, err := api.makeRequest("GET", uri, nil)
@ -497,9 +506,7 @@ func (api *API) ZoneAnalyticsDashboard(zoneID string, options ZoneAnalyticsOptio
// ZoneAnalyticsByColocation returns zone analytics information by datacenter.
//
// API reference:
// https://api.cloudflare.com/#zone-analytics-analytics-by-co-locations
// GET /zones/:zone_identifier/analytics/colos
// API reference: https://api.cloudflare.com/#zone-analytics-analytics-by-co-locations
func (api *API) ZoneAnalyticsByColocation(zoneID string, options ZoneAnalyticsOptions) ([]ZoneAnalyticsColocation, error) {
uri := "/zones/" + zoneID + "/analytics/colos" + "?" + options.encode()
res, err := api.makeRequest("GET", uri, nil)
@ -514,8 +521,19 @@ func (api *API) ZoneAnalyticsByColocation(zoneID string, options ZoneAnalyticsOp
return r.Result, nil
}
// Zone Settings
// https://api.cloudflare.com/#zone-settings-for-a-zone-get-all-zone-settings
// e.g.
// https://api.cloudflare.com/#zone-settings-for-a-zone-get-always-online-setting
// https://api.cloudflare.com/#zone-settings-for-a-zone-change-always-online-setting
// ZoneSSLSetting returns information about ssl setting to the specified zone.
//
// API reference: https://api.cloudflare.com/#zone-settings-get-ssl-setting
func (api *API) ZoneSSLSettings(zoneID string) (ZoneSSLSetting, error) {
uri := "/zones/" + zoneID + "/settings/ssl"
res, err := api.makeRequest("GET", uri, nil)
if err != nil {
return ZoneSSLSetting{}, errors.Wrap(err, errMakeRequestError)
}
var r ZoneSSLSettingResponse
err = json.Unmarshal(res, &r)
if err != nil {
return ZoneSSLSetting{}, errors.Wrap(err, errUnmarshalError)
}
return r.Result, nil
}

View File

@ -0,0 +1,42 @@
package cloudflare_test
import (
"fmt"
"log"
cloudflare "github.com/cloudflare/cloudflare-go"
)
func ExampleAPI_ListZones_all() {
api, err := cloudflare.New("deadbeef", "test@example.org")
if err != nil {
log.Fatal(err)
}
// Fetch a slice of all zones available to this account.
zones, err := api.ListZones()
if err != nil {
log.Fatal(err)
}
for _, z := range zones {
fmt.Println(z.Name)
}
}
func ExampleAPI_ListZones_filter() {
api, err := cloudflare.New("deadbeef", "test@example.org")
if err != nil {
log.Fatal(err)
}
// Fetch a slice of zones example.org and example.net.
zones, err := api.ListZones("example.org", "example.net")
if err != nil {
log.Fatal(err)
}
for _, z := range zones {
fmt.Println(z.Name)
}
}

View File

@ -1,5 +1,10 @@
# Change Log
## [v1.1.1] - 2017-09-29
- #151 Following user agent field recommendations - @joonas
- #148 AsRequest method to create load balancers requests - @lukegb
## [v1.1.0] - 2017-06-06
### Added

View File

@ -1,6 +1,10 @@
package godo
import "github.com/digitalocean/godo/context"
import (
"net/http"
"github.com/digitalocean/godo/context"
)
// AccountService is an interface for interfacing with the Account
// endpoints of the DigitalOcean API
@ -41,7 +45,7 @@ func (s *AccountServiceOp) Get(ctx context.Context) (*Account, *Response, error)
path := "v2/account"
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -12,7 +12,7 @@ func TestAccountGet(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/account", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
response := `
{ "account": {

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -61,7 +62,7 @@ func (s *ActionsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Action
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -85,7 +86,7 @@ func (s *ActionsServiceOp) Get(ctx context.Context, id int) (*Action, *Response,
}
path := fmt.Sprintf("%s/%d", actionsBasePath, id)
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -14,7 +14,7 @@ func TestAction_List(t *testing.T) {
mux.HandleFunc("/v2/actions", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, `{"actions": [{"id":1},{"id":2}]}`)
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
})
actions, _, err := client.Actions.List(ctx, nil)
@ -34,7 +34,7 @@ func TestAction_ListActionMultiplePages(t *testing.T) {
mux.HandleFunc("/v2/actions", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, `{"actions": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/droplets/?page=2"}}}`)
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
})
_, resp, err := client.Actions.List(ctx, nil)
@ -63,7 +63,7 @@ func TestAction_RetrievePageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/actions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -82,7 +82,7 @@ func TestAction_Get(t *testing.T) {
mux.HandleFunc("/v2/actions/12345", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, `{"action": {"id":12345,"region":{"name":"name","slug":"slug","available":true,"sizes":["512mb"],"features":["virtio"]},"region_slug":"slug"}}`)
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
})
action, _, err := client.Actions.Get(ctx, 12345)

View File

@ -1,6 +1,7 @@
package godo
import (
"net/http"
"path"
"github.com/digitalocean/godo/context"
@ -54,7 +55,7 @@ var _ CertificatesService = &CertificatesServiceOp{}
func (c *CertificatesServiceOp) Get(ctx context.Context, cID string) (*Certificate, *Response, error) {
urlStr := path.Join(certificatesBasePath, cID)
req, err := c.client.NewRequest(ctx, "GET", urlStr, nil)
req, err := c.client.NewRequest(ctx, http.MethodGet, urlStr, nil)
if err != nil {
return nil, nil, err
}
@ -75,7 +76,7 @@ func (c *CertificatesServiceOp) List(ctx context.Context, opt *ListOptions) ([]C
return nil, nil, err
}
req, err := c.client.NewRequest(ctx, "GET", urlStr, nil)
req, err := c.client.NewRequest(ctx, http.MethodGet, urlStr, nil)
if err != nil {
return nil, nil, err
}
@ -94,7 +95,7 @@ func (c *CertificatesServiceOp) List(ctx context.Context, opt *ListOptions) ([]C
// Create a new certificate with provided configuration.
func (c *CertificatesServiceOp) Create(ctx context.Context, cr *CertificateRequest) (*Certificate, *Response, error) {
req, err := c.client.NewRequest(ctx, "POST", certificatesBasePath, cr)
req, err := c.client.NewRequest(ctx, http.MethodPost, certificatesBasePath, cr)
if err != nil {
return nil, nil, err
}
@ -112,7 +113,7 @@ func (c *CertificatesServiceOp) Create(ctx context.Context, cr *CertificateReque
func (c *CertificatesServiceOp) Delete(ctx context.Context, cID string) (*Response, error) {
urlStr := path.Join(certificatesBasePath, cID)
req, err := c.client.NewRequest(ctx, "DELETE", urlStr, nil)
req, err := c.client.NewRequest(ctx, http.MethodDelete, urlStr, nil)
if err != nil {
return nil, err
}

View File

@ -55,7 +55,7 @@ func TestCertificates_Get(t *testing.T) {
cID := "892071a0-bb95-49bc-8021-3afd67a210bf"
urlStr = path.Join(urlStr, cID)
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, certJSONResponse)
})
@ -81,7 +81,7 @@ func TestCertificates_List(t *testing.T) {
urlStr := "/v2/certificates"
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, certsJSONResponse)
})
@ -130,7 +130,7 @@ func TestCertificates_Create(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
assert.Equal(t, createRequest, v)
fmt.Fprint(w, certJSONResponse)
@ -160,7 +160,7 @@ func TestCertificates_Delete(t *testing.T) {
urlStr := "/v2/certificates"
urlStr = path.Join(urlStr, cID)
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Certificates.Delete(ctx, cID)

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -101,7 +102,7 @@ func (s DomainsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Domain,
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -126,7 +127,7 @@ func (s *DomainsServiceOp) Get(ctx context.Context, name string) (*Domain, *Resp
path := fmt.Sprintf("%s/%s", domainsBasePath, name)
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -148,7 +149,7 @@ func (s *DomainsServiceOp) Create(ctx context.Context, createRequest *DomainCrea
path := domainsBasePath
req, err := s.client.NewRequest(ctx, "POST", path, createRequest)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, createRequest)
if err != nil {
return nil, nil, err
}
@ -169,7 +170,7 @@ func (s *DomainsServiceOp) Delete(ctx context.Context, name string) (*Response,
path := fmt.Sprintf("%s/%s", domainsBasePath, name)
req, err := s.client.NewRequest(ctx, "DELETE", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}
@ -201,7 +202,7 @@ func (s *DomainsServiceOp) Records(ctx context.Context, domain string, opt *List
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -230,7 +231,7 @@ func (s *DomainsServiceOp) Record(ctx context.Context, domain string, id int) (*
path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id)
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -256,7 +257,7 @@ func (s *DomainsServiceOp) DeleteRecord(ctx context.Context, domain string, id i
path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id)
req, err := s.client.NewRequest(ctx, "DELETE", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}
@ -313,7 +314,7 @@ func (s *DomainsServiceOp) CreateRecord(ctx context.Context,
}
path := fmt.Sprintf("%s/%s/records", domainsBasePath, domain)
req, err := s.client.NewRequest(ctx, "POST", path, createRequest)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, createRequest)
if err != nil {
return nil, nil, err

View File

@ -13,7 +13,7 @@ func TestDomains_ListDomains(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/domains", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"domains": [{"name":"foo.com"},{"name":"bar.com"}]}`)
})
@ -33,7 +33,7 @@ func TestDomains_ListDomainsMultiplePages(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/domains", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"domains": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/domains/?page=2"}}}`)
})
@ -63,7 +63,7 @@ func TestDomains_RetrievePageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/domains", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -81,7 +81,7 @@ func TestDomains_GetDomain(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/domains/example.com", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"domain":{"name":"example.com"}}`)
})
@ -112,7 +112,7 @@ func TestDomains_Create(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, createRequest) {
t.Errorf("Request body = %+v, expected %+v", v, createRequest)
}
@ -136,7 +136,7 @@ func TestDomains_Destroy(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/domains/example.com", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Domains.Delete(ctx, "example.com")
@ -150,7 +150,7 @@ func TestDomains_AllRecordsForDomainName(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/domains/example.com/records", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"domain_records":[{"id":1},{"id":2}]}`)
})
@ -195,7 +195,7 @@ func TestDomains_GetRecordforDomainName(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/domains/example.com/records/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"domain_record":{"id":1}}`)
})
@ -215,7 +215,7 @@ func TestDomains_DeleteRecordForDomainName(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/domains/example.com/records/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Domains.DeleteRecord(ctx, "example.com", 1)
@ -247,7 +247,7 @@ func TestDomains_CreateRecordForDomainName(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, createRequest) {
t.Errorf("Request body = %+v, expected %+v", v, createRequest)
}

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"net/url"
"github.com/digitalocean/godo/context"
@ -247,7 +248,7 @@ func (s *DropletActionsServiceOp) doAction(ctx context.Context, id int, request
path := dropletActionPath(id)
req, err := s.client.NewRequest(ctx, "POST", path, request)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, request)
if err != nil {
return nil, nil, err
}
@ -272,7 +273,7 @@ func (s *DropletActionsServiceOp) doActionByTag(ctx context.Context, tag string,
path := dropletActionPathByTag(tag)
req, err := s.client.NewRequest(ctx, "POST", path, request)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, request)
if err != nil {
return nil, nil, err
}
@ -312,7 +313,7 @@ func (s *DropletActionsServiceOp) GetByURI(ctx context.Context, rawurl string) (
}
func (s *DropletActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) {
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -23,7 +23,7 @@ func TestDropletActions_Shutdown(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
}
@ -61,7 +61,7 @@ func TestDropletActions_ShutdownByTag(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
}
@ -95,7 +95,7 @@ func TestDropletAction_PowerOff(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
}
@ -133,7 +133,7 @@ func TestDropletAction_PowerOffByTag(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
}
@ -167,7 +167,7 @@ func TestDropletAction_PowerOn(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
}
@ -205,7 +205,7 @@ func TestDropletAction_PowerOnByTag(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
}
@ -238,7 +238,7 @@ func TestDropletAction_Reboot(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
}
@ -274,7 +274,7 @@ func TestDropletAction_Restore(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -312,7 +312,7 @@ func TestDropletAction_Resize(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -349,7 +349,7 @@ func TestDropletAction_Rename(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -384,7 +384,7 @@ func TestDropletAction_PowerCycle(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
}
@ -423,7 +423,7 @@ func TestDropletAction_PowerCycleByTag(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
}
@ -458,7 +458,7 @@ func TestDropletAction_Snapshot(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -498,7 +498,7 @@ func TestDropletAction_SnapshotByTag(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -533,7 +533,7 @@ func TestDropletAction_EnableBackups(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -572,7 +572,7 @@ func TestDropletAction_EnableBackupsByTag(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -607,7 +607,7 @@ func TestDropletAction_DisableBackups(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -646,7 +646,7 @@ func TestDropletAction_DisableBackupsByTag(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -681,7 +681,7 @@ func TestDropletAction_PasswordReset(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -717,7 +717,7 @@ func TestDropletAction_RebuildByImageID(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = \n%#v, expected \n%#v", v, request)
@ -753,7 +753,7 @@ func TestDropletAction_RebuildByImageSlug(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -789,7 +789,7 @@ func TestDropletAction_ChangeKernel(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -824,7 +824,7 @@ func TestDropletAction_EnableIPv6(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -863,7 +863,7 @@ func TestDropletAction_EnableIPv6ByTag(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -898,7 +898,7 @@ func TestDropletAction_EnablePrivateNetworking(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -937,7 +937,7 @@ func TestDropletAction_EnablePrivateNetworkingByTag(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -972,7 +972,7 @@ func TestDropletAction_Upgrade(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, request) {
t.Errorf("Request body = %+v, expected %+v", v, request)
@ -997,7 +997,7 @@ func TestDropletActions_Get(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets/123/actions/456", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`)
})

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -275,7 +276,7 @@ func (n NetworkV6) String() string {
// Performs a list request given a path.
func (s *DropletsServiceOp) list(ctx context.Context, path string) ([]Droplet, *Response, error) {
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -322,7 +323,7 @@ func (s *DropletsServiceOp) Get(ctx context.Context, dropletID int) (*Droplet, *
path := fmt.Sprintf("%s/%d", dropletBasePath, dropletID)
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -344,7 +345,7 @@ func (s *DropletsServiceOp) Create(ctx context.Context, createRequest *DropletCr
path := dropletBasePath
req, err := s.client.NewRequest(ctx, "POST", path, createRequest)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, createRequest)
if err != nil {
return nil, nil, err
}
@ -369,7 +370,7 @@ func (s *DropletsServiceOp) CreateMultiple(ctx context.Context, createRequest *D
path := dropletBasePath
req, err := s.client.NewRequest(ctx, "POST", path, createRequest)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, createRequest)
if err != nil {
return nil, nil, err
}
@ -388,7 +389,7 @@ func (s *DropletsServiceOp) CreateMultiple(ctx context.Context, createRequest *D
// Performs a delete request given a path
func (s *DropletsServiceOp) delete(ctx context.Context, path string) (*Response, error) {
req, err := s.client.NewRequest(ctx, "DELETE", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}
@ -432,7 +433,7 @@ func (s *DropletsServiceOp) Kernels(ctx context.Context, dropletID int, opt *Lis
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -458,7 +459,7 @@ func (s *DropletsServiceOp) Actions(ctx context.Context, dropletID int, opt *Lis
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -487,7 +488,7 @@ func (s *DropletsServiceOp) Backups(ctx context.Context, dropletID int, opt *Lis
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -516,7 +517,7 @@ func (s *DropletsServiceOp) Snapshots(ctx context.Context, dropletID int, opt *L
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -541,7 +542,7 @@ func (s *DropletsServiceOp) Neighbors(ctx context.Context, dropletID int) ([]Dro
path := fmt.Sprintf("%s/%d/neighbors", dropletBasePath, dropletID)
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -13,7 +13,7 @@ func TestDroplets_ListDroplets(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"droplets": [{"id":1},{"id":2}]}`)
})
@ -37,7 +37,7 @@ func TestDroplets_ListDropletsByTag(t *testing.T) {
t.Errorf("Droplets.ListByTag did not request with a tag parameter")
}
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"droplets": [{"id":1},{"id":2}]}`)
})
@ -57,7 +57,7 @@ func TestDroplets_ListDropletsMultiplePages(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
dr := dropletsRoot{
Droplets: []Droplet{
@ -103,7 +103,7 @@ func TestDroplets_RetrievePageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -121,7 +121,7 @@ func TestDroplets_GetDroplet(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets/12345", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"droplet":{"id":12345}}`)
})
@ -265,7 +265,7 @@ func TestDroplets_Destroy(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets/12345", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Droplets.Delete(ctx, 12345)
@ -283,7 +283,7 @@ func TestDroplets_DestroyByTag(t *testing.T) {
t.Errorf("Droplets.DeleteByTag did not request with a tag parameter")
}
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Droplets.DeleteByTag(ctx, "testing-1")
@ -297,7 +297,7 @@ func TestDroplets_Kernels(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets/12345/kernels", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"kernels": [{"id":1},{"id":2}]}`)
})
@ -318,7 +318,7 @@ func TestDroplets_Snapshots(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets/12345/snapshots", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"snapshots": [{"id":1},{"id":2}]}`)
})
@ -339,7 +339,7 @@ func TestDroplets_Backups(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets/12345/backups", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"backups": [{"id":1},{"id":2}]}`)
})
@ -360,7 +360,7 @@ func TestDroplets_Actions(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets/12345/actions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"actions": [{"id":1},{"id":2}]}`)
})
@ -381,7 +381,7 @@ func TestDroplets_Neighbors(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets/12345/neighbors", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"droplets": [{"id":1},{"id":2}]}`)
})

View File

@ -1,6 +1,7 @@
package godo
import (
"net/http"
"path"
"strconv"
@ -107,7 +108,7 @@ var _ FirewallsService = &FirewallsServiceOp{}
func (fw *FirewallsServiceOp) Get(ctx context.Context, fID string) (*Firewall, *Response, error) {
path := path.Join(firewallsBasePath, fID)
req, err := fw.client.NewRequest(ctx, "GET", path, nil)
req, err := fw.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -123,7 +124,7 @@ func (fw *FirewallsServiceOp) Get(ctx context.Context, fID string) (*Firewall, *
// Create a new Firewall with a given configuration.
func (fw *FirewallsServiceOp) Create(ctx context.Context, fr *FirewallRequest) (*Firewall, *Response, error) {
req, err := fw.client.NewRequest(ctx, "POST", firewallsBasePath, fr)
req, err := fw.client.NewRequest(ctx, http.MethodPost, firewallsBasePath, fr)
if err != nil {
return nil, nil, err
}
@ -158,7 +159,7 @@ func (fw *FirewallsServiceOp) Update(ctx context.Context, fID string, fr *Firewa
// Delete a Firewall by its identifier.
func (fw *FirewallsServiceOp) Delete(ctx context.Context, fID string) (*Response, error) {
path := path.Join(firewallsBasePath, fID)
return fw.createAndDoReq(ctx, "DELETE", path, nil)
return fw.createAndDoReq(ctx, http.MethodDelete, path, nil)
}
// List Firewalls.
@ -185,37 +186,37 @@ func (fw *FirewallsServiceOp) ListByDroplet(ctx context.Context, dID int, opt *L
// AddDroplets to a Firewall.
func (fw *FirewallsServiceOp) AddDroplets(ctx context.Context, fID string, dropletIDs ...int) (*Response, error) {
path := path.Join(firewallsBasePath, fID, "droplets")
return fw.createAndDoReq(ctx, "POST", path, &dropletsRequest{IDs: dropletIDs})
return fw.createAndDoReq(ctx, http.MethodPost, path, &dropletsRequest{IDs: dropletIDs})
}
// RemoveDroplets from a Firewall.
func (fw *FirewallsServiceOp) RemoveDroplets(ctx context.Context, fID string, dropletIDs ...int) (*Response, error) {
path := path.Join(firewallsBasePath, fID, "droplets")
return fw.createAndDoReq(ctx, "DELETE", path, &dropletsRequest{IDs: dropletIDs})
return fw.createAndDoReq(ctx, http.MethodDelete, path, &dropletsRequest{IDs: dropletIDs})
}
// AddTags to a Firewall.
func (fw *FirewallsServiceOp) AddTags(ctx context.Context, fID string, tags ...string) (*Response, error) {
path := path.Join(firewallsBasePath, fID, "tags")
return fw.createAndDoReq(ctx, "POST", path, &tagsRequest{Tags: tags})
return fw.createAndDoReq(ctx, http.MethodPost, path, &tagsRequest{Tags: tags})
}
// RemoveTags from a Firewall.
func (fw *FirewallsServiceOp) RemoveTags(ctx context.Context, fID string, tags ...string) (*Response, error) {
path := path.Join(firewallsBasePath, fID, "tags")
return fw.createAndDoReq(ctx, "DELETE", path, &tagsRequest{Tags: tags})
return fw.createAndDoReq(ctx, http.MethodDelete, path, &tagsRequest{Tags: tags})
}
// AddRules to a Firewall.
func (fw *FirewallsServiceOp) AddRules(ctx context.Context, fID string, rr *FirewallRulesRequest) (*Response, error) {
path := path.Join(firewallsBasePath, fID, "rules")
return fw.createAndDoReq(ctx, "POST", path, rr)
return fw.createAndDoReq(ctx, http.MethodPost, path, rr)
}
// RemoveRules from a Firewall.
func (fw *FirewallsServiceOp) RemoveRules(ctx context.Context, fID string, rr *FirewallRulesRequest) (*Response, error) {
path := path.Join(firewallsBasePath, fID, "rules")
return fw.createAndDoReq(ctx, "DELETE", path, rr)
return fw.createAndDoReq(ctx, http.MethodDelete, path, rr)
}
type dropletsRequest struct {
@ -245,7 +246,7 @@ func (fw *FirewallsServiceOp) createAndDoReq(ctx context.Context, method, path s
}
func (fw *FirewallsServiceOp) listHelper(ctx context.Context, path string) ([]Firewall, *Response, error) {
req, err := fw.client.NewRequest(ctx, "GET", path, nil)
req, err := fw.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -224,7 +224,7 @@ func TestFirewalls_Get(t *testing.T) {
urlStr = path.Join(urlStr, fID)
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, firewallJSONResponse)
})
@ -333,7 +333,7 @@ func TestFirewalls_Create(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, expectedFirewallRequest) {
t.Errorf("Request body = %+v, expected %+v", v, expectedFirewallRequest)
}
@ -481,7 +481,7 @@ func TestFirewalls_Delete(t *testing.T) {
fID := "fe6b88f2-b42b-4bf7-bbd3-5ae20208f0b0"
urlStr = path.Join(urlStr, fID)
mux.HandleFunc(urlStr, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Firewalls.Delete(ctx, fID)
@ -496,7 +496,7 @@ func TestFirewalls_List(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/firewalls", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, firewallListJSONResponse)
})
@ -517,7 +517,7 @@ func TestFirewalls_ListByDroplet(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/droplets/123/firewalls", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, firewallListJSONResponse)
})
@ -550,7 +550,7 @@ func TestFirewalls_AddDroplets(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, dRequest) {
t.Errorf("Request body = %+v, expected %+v", v, dRequest)
}
@ -589,7 +589,7 @@ func TestFirewalls_RemoveDroplets(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
if !reflect.DeepEqual(v, dRequest) {
t.Errorf("Request body = %+v, expected %+v", v, dRequest)
}
@ -628,7 +628,7 @@ func TestFirewalls_AddTags(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, tRequest) {
t.Errorf("Request body = %+v, expected %+v", v, tRequest)
}
@ -666,7 +666,7 @@ func TestFirewalls_RemoveTags(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
if !reflect.DeepEqual(v, tRequest) {
t.Errorf("Request body = %+v, expected %+v", v, tRequest)
}
@ -721,7 +721,7 @@ func TestFirewalls_AddRules(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, rr) {
t.Errorf("Request body = %+v, expected %+v", v, rr)
}
@ -776,7 +776,7 @@ func TestFirewalls_RemoveRules(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
if !reflect.DeepEqual(v, rr) {
t.Errorf("Request body = %+v, expected %+v", v, rr)
}

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -63,7 +64,7 @@ func (f *FloatingIPsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Fl
return nil, nil, err
}
req, err := f.client.NewRequest(ctx, "GET", path, nil)
req, err := f.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -84,7 +85,7 @@ func (f *FloatingIPsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Fl
func (f *FloatingIPsServiceOp) Get(ctx context.Context, ip string) (*FloatingIP, *Response, error) {
path := fmt.Sprintf("%s/%s", floatingBasePath, ip)
req, err := f.client.NewRequest(ctx, "GET", path, nil)
req, err := f.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -103,7 +104,7 @@ func (f *FloatingIPsServiceOp) Get(ctx context.Context, ip string) (*FloatingIP,
func (f *FloatingIPsServiceOp) Create(ctx context.Context, createRequest *FloatingIPCreateRequest) (*FloatingIP, *Response, error) {
path := floatingBasePath
req, err := f.client.NewRequest(ctx, "POST", path, createRequest)
req, err := f.client.NewRequest(ctx, http.MethodPost, path, createRequest)
if err != nil {
return nil, nil, err
}
@ -124,7 +125,7 @@ func (f *FloatingIPsServiceOp) Create(ctx context.Context, createRequest *Floati
func (f *FloatingIPsServiceOp) Delete(ctx context.Context, ip string) (*Response, error) {
path := fmt.Sprintf("%s/%s", floatingBasePath, ip)
req, err := f.client.NewRequest(ctx, "DELETE", path, nil)
req, err := f.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -57,7 +58,7 @@ func (s *FloatingIPActionsServiceOp) List(ctx context.Context, ip string, opt *L
func (s *FloatingIPActionsServiceOp) doAction(ctx context.Context, ip string, request *ActionRequest) (*Action, *Response, error) {
path := floatingIPActionPath(ip)
req, err := s.client.NewRequest(ctx, "POST", path, request)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, request)
if err != nil {
return nil, nil, err
}
@ -72,7 +73,7 @@ func (s *FloatingIPActionsServiceOp) doAction(ctx context.Context, ip string, re
}
func (s *FloatingIPActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) {
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -87,7 +88,7 @@ func (s *FloatingIPActionsServiceOp) get(ctx context.Context, path string) (*Act
}
func (s *FloatingIPActionsServiceOp) list(ctx context.Context, path string) ([]Action, *Response, error) {
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -24,7 +24,7 @@ func TestFloatingIPsActions_Assign(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, assignRequest) {
t.Errorf("Request body = %#v, expected %#v", v, assignRequest)
}
@ -59,7 +59,7 @@ func TestFloatingIPsActions_Unassign(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, unassignRequest) {
t.Errorf("Request body = %+v, expected %+v", v, unassignRequest)
}
@ -83,7 +83,7 @@ func TestFloatingIPsActions_Get(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/floating_ips/192.168.0.1/actions/456", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`)
})
@ -103,7 +103,7 @@ func TestFloatingIPsActions_List(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/floating_ips/192.168.0.1/actions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprintf(w, `{"actions":[{"status":"in-progress"}]}`)
})
@ -123,7 +123,7 @@ func TestFloatingIPsActions_ListMultiplePages(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/floating_ips/192.168.0.1/actions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"actions":[{"status":"in-progress"}], "links":{"pages":{"next":"http://example.com/v2/floating_ips/192.168.0.1/actions?page=2"}}}`)
})
@ -153,7 +153,7 @@ func TestFloatingIPsActions_ListPageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/floating_ips/192.168.0.1/actions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})

View File

@ -13,7 +13,7 @@ func TestFloatingIPs_ListFloatingIPs(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/floating_ips", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"floating_ips": [{"region":{"slug":"nyc3"},"droplet":{"id":1},"ip":"192.168.0.1"},{"region":{"slug":"nyc3"},"droplet":{"id":2},"ip":"192.168.0.2"}]}`)
})
@ -36,7 +36,7 @@ func TestFloatingIPs_ListFloatingIPsMultiplePages(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/floating_ips", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"floating_ips": [{"region":{"slug":"nyc3"},"droplet":{"id":1},"ip":"192.168.0.1"},{"region":{"slug":"nyc3"},"droplet":{"id":2},"ip":"192.168.0.2"}], "links":{"pages":{"next":"http://example.com/v2/floating_ips/?page=2"}}}`)
})
@ -66,7 +66,7 @@ func TestFloatingIPs_RetrievePageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/floating_ips", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -84,7 +84,7 @@ func TestFloatingIPs_Get(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/floating_ips/192.168.0.1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"floating_ip":{"region":{"slug":"nyc3"},"droplet":{"id":1},"ip":"192.168.0.1"}}`)
})
@ -115,7 +115,7 @@ func TestFloatingIPs_Create(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, createRequest) {
t.Errorf("Request body = %+v, expected %+v", v, createRequest)
}
@ -139,7 +139,7 @@ func TestFloatingIPs_Destroy(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/floating_ips/192.168.0.1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.FloatingIPs.Delete(ctx, "192.168.0.1")

View File

@ -210,7 +210,7 @@ func SetBaseURL(bu string) ClientOpt {
// SetUserAgent is a client option for setting the user agent.
func SetUserAgent(ua string) ClientOpt {
return func(c *Client) error {
c.UserAgent = fmt.Sprintf("%s+%s", ua, c.UserAgent)
c.UserAgent = fmt.Sprintf("%s %s", ua, c.UserAgent)
return nil
}
}

View File

@ -106,7 +106,7 @@ func testClientDefaultBaseURL(t *testing.T, c *Client) {
func testClientDefaultUserAgent(t *testing.T, c *Client) {
if c.UserAgent != userAgent {
t.Errorf("NewClick UserAgent = %v, expected %v", c.UserAgent, userAgent)
t.Errorf("NewClient UserAgent = %v, expected %v", c.UserAgent, userAgent)
}
}
@ -138,7 +138,7 @@ func TestNewRequest(t *testing.T) {
`{"name":"l","region":"","size":"","image":0,`+
`"ssh_keys":null,"backups":false,"ipv6":false,`+
`"private_networking":false,"monitoring":false,"tags":null}`+"\n"
req, _ := c.NewRequest(ctx, "GET", inURL, inBody)
req, _ := c.NewRequest(ctx, http.MethodGet, inURL, inBody)
// test relative URL was expanded
if req.URL.String() != outURL {
@ -166,7 +166,7 @@ func TestNewRequest_withUserData(t *testing.T) {
`{"name":"l","region":"","size":"","image":0,`+
`"ssh_keys":null,"backups":false,"ipv6":false,`+
`"private_networking":false,"monitoring":false,"user_data":"u","tags":null}`+"\n"
req, _ := c.NewRequest(ctx, "GET", inURL, inBody)
req, _ := c.NewRequest(ctx, http.MethodGet, inURL, inBody)
// test relative URL was expanded
if req.URL.String() != outURL {
@ -188,21 +188,21 @@ func TestNewRequest_withUserData(t *testing.T) {
func TestNewRequest_badURL(t *testing.T) {
c := NewClient(nil)
_, err := c.NewRequest(ctx, "GET", ":", nil)
_, err := c.NewRequest(ctx, http.MethodGet, ":", nil)
testURLParseError(t, err)
}
func TestNewRequest_withCustomUserAgent(t *testing.T) {
ua := "testing"
ua := "testing/0.0.1"
c, err := New(nil, SetUserAgent(ua))
if err != nil {
t.Fatalf("New() unexpected error: %v", err)
}
req, _ := c.NewRequest(ctx, "GET", "/foo", nil)
req, _ := c.NewRequest(ctx, http.MethodGet, "/foo", nil)
expected := fmt.Sprintf("%s+%s", ua, userAgent)
expected := fmt.Sprintf("%s %s", ua, userAgent)
if got := req.Header.Get("User-Agent"); got != expected {
t.Errorf("New() UserAgent = %s; expected %s", got, expected)
}
@ -217,13 +217,13 @@ func TestDo(t *testing.T) {
}
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if m := "GET"; m != r.Method {
if m := http.MethodGet; m != r.Method {
t.Errorf("Request method = %v, expected %v", r.Method, m)
}
fmt.Fprint(w, `{"A":"a"}`)
})
req, _ := client.NewRequest(ctx, "GET", "/", nil)
req, _ := client.NewRequest(ctx, http.MethodGet, "/", nil)
body := new(foo)
_, err := client.Do(context.Background(), req, body)
if err != nil {
@ -244,7 +244,7 @@ func TestDo_httpError(t *testing.T) {
http.Error(w, "Bad Request", 400)
})
req, _ := client.NewRequest(ctx, "GET", "/", nil)
req, _ := client.NewRequest(ctx, http.MethodGet, "/", nil)
_, err := client.Do(context.Background(), req, nil)
if err == nil {
@ -262,7 +262,7 @@ func TestDo_redirectLoop(t *testing.T) {
http.Redirect(w, r, "/", http.StatusFound)
})
req, _ := client.NewRequest(ctx, "GET", "/", nil)
req, _ := client.NewRequest(ctx, http.MethodGet, "/", nil)
_, err := client.Do(context.Background(), req, nil)
if err == nil {
@ -347,7 +347,7 @@ func TestDo_rateLimit(t *testing.T) {
t.Errorf("Client rate reset not initialized to zero value")
}
req, _ := client.NewRequest(ctx, "GET", "/", nil)
req, _ := client.NewRequest(ctx, http.MethodGet, "/", nil)
_, err := client.Do(context.Background(), req, nil)
if err != nil {
t.Fatalf("Do(): %v", err)
@ -378,7 +378,7 @@ func TestDo_rateLimit_errorResponse(t *testing.T) {
var expected int
req, _ := client.NewRequest(ctx, "GET", "/", nil)
req, _ := client.NewRequest(ctx, http.MethodGet, "/", nil)
_, _ = client.Do(context.Background(), req, nil)
if expected = 60; client.Rate.Limit != expected {
@ -414,13 +414,13 @@ func TestDo_completion_callback(t *testing.T) {
}
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if m := "GET"; m != r.Method {
if m := http.MethodGet; m != r.Method {
t.Errorf("Request method = %v, expected %v", r.Method, m)
}
fmt.Fprint(w, `{"A":"a"}`)
})
req, _ := client.NewRequest(ctx, "GET", "/", nil)
req, _ := client.NewRequest(ctx, http.MethodGet, "/", nil)
body := new(foo)
var completedReq *http.Request
var completedResp string
@ -506,13 +506,14 @@ func TestAddOptions(t *testing.T) {
}
func TestCustomUserAgent(t *testing.T) {
c, err := New(nil, SetUserAgent("testing"))
ua := "testing/0.0.1"
c, err := New(nil, SetUserAgent(ua))
if err != nil {
t.Fatalf("New() unexpected error: %v", err)
}
expected := fmt.Sprintf("%s+%s", "testing", userAgent)
expected := fmt.Sprintf("%s %s", ua, userAgent)
if got := c.UserAgent; got != expected {
t.Errorf("New() UserAgent = %s; expected %s", got, expected)
}

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -35,7 +36,7 @@ func (i *ImageActionsServiceOp) Transfer(ctx context.Context, imageID int, trans
path := fmt.Sprintf("v2/images/%d/actions", imageID)
req, err := i.client.NewRequest(ctx, "POST", path, transferRequest)
req, err := i.client.NewRequest(ctx, http.MethodPost, path, transferRequest)
if err != nil {
return nil, nil, err
}
@ -61,7 +62,7 @@ func (i *ImageActionsServiceOp) Convert(ctx context.Context, imageID int) (*Acti
"type": "convert",
}
req, err := i.client.NewRequest(ctx, "POST", path, convertRequest)
req, err := i.client.NewRequest(ctx, http.MethodPost, path, convertRequest)
if err != nil {
return nil, nil, err
}
@ -87,7 +88,7 @@ func (i *ImageActionsServiceOp) Get(ctx context.Context, imageID, actionID int)
path := fmt.Sprintf("v2/images/%d/actions/%d", imageID, actionID)
req, err := i.client.NewRequest(ctx, "GET", path, nil)
req, err := i.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -21,7 +21,7 @@ func TestImageActions_Transfer(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, transferRequest) {
t.Errorf("Request body = %+v, expected %+v", v, transferRequest)
}
@ -56,7 +56,7 @@ func TestImageActions_Convert(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, convertRequest) {
t.Errorf("Request body = %+v, expected %+v", v, convertRequest)
}
@ -81,7 +81,7 @@ func TestImageActions_Get(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/images/123/actions/456", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`)
})

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -140,7 +141,7 @@ func (s *ImagesServiceOp) Delete(ctx context.Context, imageID int) (*Response, e
path := fmt.Sprintf("%s/%d", imageBasePath, imageID)
req, err := s.client.NewRequest(ctx, "DELETE", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}
@ -154,7 +155,7 @@ func (s *ImagesServiceOp) Delete(ctx context.Context, imageID int) (*Response, e
func (s *ImagesServiceOp) get(ctx context.Context, ID interface{}) (*Image, *Response, error) {
path := fmt.Sprintf("%s/%v", imageBasePath, ID)
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -180,7 +181,7 @@ func (s *ImagesServiceOp) list(ctx context.Context, opt *ListOptions, listOpt *l
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -13,7 +13,7 @@ func TestImages_List(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"images":[{"id":1},{"id":2}]}`)
})
@ -33,7 +33,7 @@ func TestImages_ListDistribution(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
expected := "distribution"
actual := r.URL.Query().Get("type")
if actual != expected {
@ -58,7 +58,7 @@ func TestImages_ListApplication(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
expected := "application"
actual := r.URL.Query().Get("type")
if actual != expected {
@ -83,7 +83,7 @@ func TestImages_ListUser(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
expected := "true"
actual := r.URL.Query().Get("private")
if actual != expected {
@ -109,7 +109,7 @@ func TestImages_ListImagesMultiplePages(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"images": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/images/?page=2"}}}`)
})
@ -138,7 +138,7 @@ func TestImages_RetrievePageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/images", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -156,7 +156,7 @@ func TestImages_GetImageByID(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/images/12345", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"image":{"id":12345}}`)
})
@ -176,7 +176,7 @@ func TestImages_GetImageBySlug(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/images/ubuntu", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"image":{"id":12345}}`)
})
@ -232,7 +232,7 @@ func TestImages_Destroy(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/images/12345", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Images.Delete(ctx, 12345)

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -70,7 +71,7 @@ func (s *KeysServiceOp) List(ctx context.Context, opt *ListOptions) ([]Key, *Res
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -89,7 +90,7 @@ func (s *KeysServiceOp) List(ctx context.Context, opt *ListOptions) ([]Key, *Res
// Performs a get given a path
func (s *KeysServiceOp) get(ctx context.Context, path string) (*Key, *Response, error) {
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -129,7 +130,7 @@ func (s *KeysServiceOp) Create(ctx context.Context, createRequest *KeyCreateRequ
return nil, nil, NewArgError("createRequest", "cannot be nil")
}
req, err := s.client.NewRequest(ctx, "POST", keysBasePath, createRequest)
req, err := s.client.NewRequest(ctx, http.MethodPost, keysBasePath, createRequest)
if err != nil {
return nil, nil, err
}
@ -195,7 +196,7 @@ func (s *KeysServiceOp) UpdateByFingerprint(ctx context.Context, fingerprint str
// Delete key using a path
func (s *KeysServiceOp) delete(ctx context.Context, path string) (*Response, error) {
req, err := s.client.NewRequest(ctx, "DELETE", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}

View File

@ -13,7 +13,7 @@ func TestKeys_List(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/account/keys", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"ssh_keys":[{"id":1},{"id":2}]}`)
})
@ -33,7 +33,7 @@ func TestKeys_ListKeysMultiplePages(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/account/keys", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"droplets": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/account/keys/?page=2"}}}`)
})
@ -62,7 +62,7 @@ func TestKeys_RetrievePageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/account/keys", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -79,7 +79,7 @@ func TestKeys_GetByID(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/account/keys/12345", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"ssh_key": {"id":12345}}`)
})
@ -99,7 +99,7 @@ func TestKeys_GetByFingerprint(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/account/keys/aa:bb:cc", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"ssh_key": {"fingerprint":"aa:bb:cc"}}`)
})
@ -130,7 +130,7 @@ func TestKeys_Create(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, createRequest) {
t.Errorf("Request body = %+v, expected %+v", v, createRequest)
}
@ -226,7 +226,7 @@ func TestKeys_DestroyByID(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/account/keys/12345", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Keys.DeleteByID(ctx, 12345)
@ -240,7 +240,7 @@ func TestKeys_DestroyByFingerprint(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/account/keys/aa:bb:cc", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Keys.DeleteByFingerprint(ctx, "aa:bb:cc")

View File

@ -2,12 +2,14 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
const loadBalancersBasePath = "/v2/load_balancers"
const forwardingRulesPath = "forwarding_rules"
const dropletsPath = "droplets"
// LoadBalancersService is an interface for managing load balancers with the DigitalOcean API.
@ -46,6 +48,32 @@ func (l LoadBalancer) String() string {
return Stringify(l)
}
// AsRequest creates a LoadBalancerRequest that can be submitted to Update with the current values of the LoadBalancer.
// Modifying the returned LoadBalancerRequest will not modify the original LoadBalancer.
func (l LoadBalancer) AsRequest() *LoadBalancerRequest {
r := LoadBalancerRequest{
Name: l.Name,
Algorithm: l.Algorithm,
ForwardingRules: append([]ForwardingRule(nil), l.ForwardingRules...),
DropletIDs: append([]int(nil), l.DropletIDs...),
Tag: l.Tag,
RedirectHttpToHttps: l.RedirectHttpToHttps,
HealthCheck: l.HealthCheck,
}
if l.HealthCheck != nil {
r.HealthCheck = &HealthCheck{}
*r.HealthCheck = *l.HealthCheck
}
if l.StickySessions != nil {
r.StickySessions = &StickySessions{}
*r.StickySessions = *l.StickySessions
}
if l.Region != nil {
r.Region = l.Region.Slug
}
return &r
}
// ForwardingRule represents load balancer forwarding rules.
type ForwardingRule struct {
EntryProtocol string `json:"entry_protocol,omitempty"`
@ -143,7 +171,7 @@ var _ LoadBalancersService = &LoadBalancersServiceOp{}
func (l *LoadBalancersServiceOp) Get(ctx context.Context, lbID string) (*LoadBalancer, *Response, error) {
path := fmt.Sprintf("%s/%s", loadBalancersBasePath, lbID)
req, err := l.client.NewRequest(ctx, "GET", path, nil)
req, err := l.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -164,7 +192,7 @@ func (l *LoadBalancersServiceOp) List(ctx context.Context, opt *ListOptions) ([]
return nil, nil, err
}
req, err := l.client.NewRequest(ctx, "GET", path, nil)
req, err := l.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -183,7 +211,7 @@ func (l *LoadBalancersServiceOp) List(ctx context.Context, opt *ListOptions) ([]
// Create a new load balancer with a given configuration.
func (l *LoadBalancersServiceOp) Create(ctx context.Context, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) {
req, err := l.client.NewRequest(ctx, "POST", loadBalancersBasePath, lbr)
req, err := l.client.NewRequest(ctx, http.MethodPost, loadBalancersBasePath, lbr)
if err != nil {
return nil, nil, err
}
@ -219,7 +247,7 @@ func (l *LoadBalancersServiceOp) Update(ctx context.Context, lbID string, lbr *L
func (l *LoadBalancersServiceOp) Delete(ctx context.Context, ldID string) (*Response, error) {
path := fmt.Sprintf("%s/%s", loadBalancersBasePath, ldID)
req, err := l.client.NewRequest(ctx, "DELETE", path, nil)
req, err := l.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}
@ -231,7 +259,7 @@ func (l *LoadBalancersServiceOp) Delete(ctx context.Context, ldID string) (*Resp
func (l *LoadBalancersServiceOp) AddDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) {
path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, dropletsPath)
req, err := l.client.NewRequest(ctx, "POST", path, &dropletIDsRequest{IDs: dropletIDs})
req, err := l.client.NewRequest(ctx, http.MethodPost, path, &dropletIDsRequest{IDs: dropletIDs})
if err != nil {
return nil, err
}
@ -243,7 +271,7 @@ func (l *LoadBalancersServiceOp) AddDroplets(ctx context.Context, lbID string, d
func (l *LoadBalancersServiceOp) RemoveDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) {
path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, dropletsPath)
req, err := l.client.NewRequest(ctx, "DELETE", path, &dropletIDsRequest{IDs: dropletIDs})
req, err := l.client.NewRequest(ctx, http.MethodDelete, path, &dropletIDsRequest{IDs: dropletIDs})
if err != nil {
return nil, err
}
@ -255,7 +283,7 @@ func (l *LoadBalancersServiceOp) RemoveDroplets(ctx context.Context, lbID string
func (l *LoadBalancersServiceOp) AddForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) {
path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, forwardingRulesPath)
req, err := l.client.NewRequest(ctx, "POST", path, &forwardingRulesRequest{Rules: rules})
req, err := l.client.NewRequest(ctx, http.MethodPost, path, &forwardingRulesRequest{Rules: rules})
if err != nil {
return nil, err
}
@ -267,7 +295,7 @@ func (l *LoadBalancersServiceOp) AddForwardingRules(ctx context.Context, lbID st
func (l *LoadBalancersServiceOp) RemoveForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) {
path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, forwardingRulesPath)
req, err := l.client.NewRequest(ctx, "DELETE", path, &forwardingRulesRequest{Rules: rules})
req, err := l.client.NewRequest(ctx, http.MethodDelete, path, &forwardingRulesRequest{Rules: rules})
if err != nil {
return nil, err
}

View File

@ -272,7 +272,7 @@ var lbUpdateJSONResponse = `
}
`
func TestLoadBlanacers_Get(t *testing.T) {
func TestLoadBalancers_Get(t *testing.T) {
setup()
defer teardown()
@ -280,7 +280,7 @@ func TestLoadBlanacers_Get(t *testing.T) {
loadBalancerId := "37e6be88-01ec-4ec7-9bc6-a514d4719057"
path = fmt.Sprintf("%s/%s", path, loadBalancerId)
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, lbGetJSONResponse)
})
@ -333,7 +333,7 @@ func TestLoadBlanacers_Get(t *testing.T) {
assert.Equal(t, expected, loadBalancer)
}
func TestLoadBlanacers_Create(t *testing.T) {
func TestLoadBalancers_Create(t *testing.T) {
setup()
defer teardown()
@ -377,7 +377,7 @@ func TestLoadBlanacers_Create(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
assert.Equal(t, createRequest, v)
fmt.Fprint(w, lbCreateJSONResponse)
@ -440,7 +440,7 @@ func TestLoadBlanacers_Create(t *testing.T) {
assert.Equal(t, expected, loadBalancer)
}
func TestLoadBlanacers_Update(t *testing.T) {
func TestLoadBalancers_Update(t *testing.T) {
setup()
defer teardown()
@ -547,13 +547,13 @@ func TestLoadBlanacers_Update(t *testing.T) {
assert.Equal(t, expected, loadBalancer)
}
func TestLoadBlanacers_List(t *testing.T) {
func TestLoadBalancers_List(t *testing.T) {
setup()
defer teardown()
path := "/v2/load_balancers"
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, lbListJSONResponse)
})
@ -608,13 +608,13 @@ func TestLoadBlanacers_List(t *testing.T) {
assert.Equal(t, expected, loadBalancers)
}
func TestLoadBlanacers_List_Pagination(t *testing.T) {
func TestLoadBalancers_List_Pagination(t *testing.T) {
setup()
defer teardown()
path := "/v2/load_balancers"
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
testFormValues(t, r, map[string]string{"page": "2"})
fmt.Fprint(w, lbListJSONResponse)
})
@ -630,7 +630,7 @@ func TestLoadBlanacers_List_Pagination(t *testing.T) {
assert.Equal(t, "http://localhost:3001/v2/load_balancers?page=3&per_page=1", resp.Links.Pages.Last)
}
func TestLoadBlanacers_Delete(t *testing.T) {
func TestLoadBalancers_Delete(t *testing.T) {
setup()
defer teardown()
@ -638,7 +638,7 @@ func TestLoadBlanacers_Delete(t *testing.T) {
path := "/v2/load_balancers"
path = fmt.Sprintf("%s/%s", path, lbID)
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.LoadBalancers.Delete(ctx, lbID)
@ -648,7 +648,7 @@ func TestLoadBlanacers_Delete(t *testing.T) {
}
}
func TestLoadBlanacers_AddDroplets(t *testing.T) {
func TestLoadBalancers_AddDroplets(t *testing.T) {
setup()
defer teardown()
@ -665,7 +665,7 @@ func TestLoadBlanacers_AddDroplets(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
assert.Equal(t, dropletIdsRequest, v)
fmt.Fprint(w, nil)
@ -678,7 +678,7 @@ func TestLoadBlanacers_AddDroplets(t *testing.T) {
}
}
func TestLoadBlanacers_RemoveDroplets(t *testing.T) {
func TestLoadBalancers_RemoveDroplets(t *testing.T) {
setup()
defer teardown()
@ -695,7 +695,7 @@ func TestLoadBlanacers_RemoveDroplets(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
assert.Equal(t, dropletIdsRequest, v)
fmt.Fprint(w, nil)
@ -708,7 +708,7 @@ func TestLoadBlanacers_RemoveDroplets(t *testing.T) {
}
}
func TestLoadBlanacers_AddForwardingRules(t *testing.T) {
func TestLoadBalancers_AddForwardingRules(t *testing.T) {
setup()
defer teardown()
@ -739,7 +739,7 @@ func TestLoadBlanacers_AddForwardingRules(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
assert.Equal(t, frr, v)
fmt.Fprint(w, nil)
@ -752,7 +752,7 @@ func TestLoadBlanacers_AddForwardingRules(t *testing.T) {
}
}
func TestLoadBlanacers_RemoveForwardingRules(t *testing.T) {
func TestLoadBalancers_RemoveForwardingRules(t *testing.T) {
setup()
defer teardown()
@ -782,7 +782,7 @@ func TestLoadBlanacers_RemoveForwardingRules(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
assert.Equal(t, frr, v)
fmt.Fprint(w, nil)
@ -794,3 +794,108 @@ func TestLoadBlanacers_RemoveForwardingRules(t *testing.T) {
t.Errorf("LoadBalancers.RemoveForwardingRules returned error: %v", err)
}
}
func TestLoadBalancers_AsRequest(t *testing.T) {
lb := &LoadBalancer{
ID: "37e6be88-01ec-4ec7-9bc6-a514d4719057",
Name: "test-loadbalancer",
IP: "10.0.0.1",
Algorithm: "least_connections",
Status: "active",
Created: "2011-06-24T12:00:00Z",
HealthCheck: &HealthCheck{
Protocol: "http",
Port: 80,
Path: "/ping",
CheckIntervalSeconds: 30,
ResponseTimeoutSeconds: 10,
HealthyThreshold: 3,
UnhealthyThreshold: 3,
},
StickySessions: &StickySessions{
Type: "cookies",
CookieName: "nomnom",
CookieTtlSeconds: 32,
},
Region: &Region{
Slug: "lon1",
},
RedirectHttpToHttps: true,
}
lb.DropletIDs = make([]int, 1, 2)
lb.DropletIDs[0] = 12345
lb.ForwardingRules = make([]ForwardingRule, 1, 2)
lb.ForwardingRules[0] = ForwardingRule{
EntryProtocol: "http",
EntryPort: 80,
TargetProtocol: "http",
TargetPort: 80,
}
want := &LoadBalancerRequest{
Name: "test-loadbalancer",
Algorithm: "least_connections",
Region: "lon1",
ForwardingRules: []ForwardingRule{ForwardingRule{
EntryProtocol: "http",
EntryPort: 80,
TargetProtocol: "http",
TargetPort: 80,
}},
HealthCheck: &HealthCheck{
Protocol: "http",
Port: 80,
Path: "/ping",
CheckIntervalSeconds: 30,
ResponseTimeoutSeconds: 10,
HealthyThreshold: 3,
UnhealthyThreshold: 3,
},
StickySessions: &StickySessions{
Type: "cookies",
CookieName: "nomnom",
CookieTtlSeconds: 32,
},
DropletIDs: []int{12345},
RedirectHttpToHttps: true,
}
r := lb.AsRequest()
assert.Equal(t, want, r)
assert.False(t, r.HealthCheck == lb.HealthCheck, "HealthCheck points to same struct")
assert.False(t, r.StickySessions == lb.StickySessions, "StickySessions points to same struct")
r.DropletIDs = append(r.DropletIDs, 54321)
r.ForwardingRules = append(r.ForwardingRules, ForwardingRule{
EntryProtocol: "https",
EntryPort: 443,
TargetProtocol: "https",
TargetPort: 443,
TlsPassthrough: true,
})
// Check that original LoadBalancer hasn't changed
lb.DropletIDs = append(lb.DropletIDs, 13579)
lb.ForwardingRules = append(lb.ForwardingRules, ForwardingRule{
EntryProtocol: "tcp",
EntryPort: 587,
TargetProtocol: "tcp",
TargetPort: 587,
})
assert.Equal(t, []int{12345, 54321}, r.DropletIDs)
assert.Equal(t, []ForwardingRule{
ForwardingRule{
EntryProtocol: "http",
EntryPort: 80,
TargetProtocol: "http",
TargetPort: 80,
},
ForwardingRule{
EntryProtocol: "https",
EntryPort: 443,
TargetProtocol: "https",
TargetPort: 443,
TlsPassthrough: true,
},
}, r.ForwardingRules)
}

View File

@ -1,6 +1,10 @@
package godo
import "github.com/digitalocean/godo/context"
import (
"net/http"
"github.com/digitalocean/godo/context"
)
// RegionsService is an interface for interfacing with the regions
// endpoints of the DigitalOcean API
@ -43,7 +47,7 @@ func (s *RegionsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Region
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -12,7 +12,7 @@ func TestRegions_List(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/regions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"regions":[{"slug":"1"},{"slug":"2"}]}`)
})
@ -32,7 +32,7 @@ func TestRegions_ListRegionsMultiplePages(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/regions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"regions": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/regions/?page=2"}}}`)
})
@ -62,7 +62,7 @@ func TestRegions_RetrievePageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/regions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})

View File

@ -1,6 +1,10 @@
package godo
import "github.com/digitalocean/godo/context"
import (
"net/http"
"github.com/digitalocean/godo/context"
)
// SizesService is an interface for interfacing with the size
// endpoints of the DigitalOcean API
@ -47,7 +51,7 @@ func (s *SizesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Size, *R
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -12,7 +12,7 @@ func TestSizes_List(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/sizes", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"sizes":[{"slug":"1"},{"slug":"2"}]}`)
})
@ -32,7 +32,7 @@ func TestSizes_ListSizesMultiplePages(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/sizes", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"sizes": [{"id":1},{"id":2}], "links":{"pages":{"next":"http://example.com/v2/sizes/?page=2"}}}`)
})
@ -62,7 +62,7 @@ func TestSizes_RetrievePageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/sizes", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -82,7 +83,7 @@ func (s *SnapshotsServiceOp) Get(ctx context.Context, snapshotID string) (*Snaps
func (s *SnapshotsServiceOp) Delete(ctx context.Context, snapshotID string) (*Response, error) {
path := fmt.Sprintf("%s/%s", snapshotBasePath, snapshotID)
req, err := s.client.NewRequest(ctx, "DELETE", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}
@ -96,7 +97,7 @@ func (s *SnapshotsServiceOp) Delete(ctx context.Context, snapshotID string) (*Re
func (s *SnapshotsServiceOp) get(ctx context.Context, ID string) (*Snapshot, *Response, error) {
path := fmt.Sprintf("%s/%s", snapshotBasePath, ID)
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -122,7 +123,7 @@ func (s *SnapshotsServiceOp) list(ctx context.Context, opt *ListOptions, listOpt
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -14,7 +14,7 @@ func TestSnapshots_List(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/snapshots", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"snapshots":[{"id":"1"},{"id":"2", "size_gigabytes": 4.84}]}`)
})
ctx := context.Background()
@ -34,7 +34,7 @@ func TestSnapshots_ListVolume(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/snapshots", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
expected := "volume"
actual := r.URL.Query().Get("resource_type")
if actual != expected {
@ -60,7 +60,7 @@ func TestSnapshots_ListDroplet(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/snapshots", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
expected := "droplet"
actual := r.URL.Query().Get("resource_type")
if actual != expected {
@ -87,7 +87,7 @@ func TestSnapshots_ListSnapshotsMultiplePages(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/snapshots", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"snapshots": [{"id":"1"},{"id":"2"}], "links":{"pages":{"next":"http://example.com/v2/snapshots/?page=2"}}}`)
})
@ -117,7 +117,7 @@ func TestSnapshots_RetrievePageByNumber(t *testing.T) {
}`
mux.HandleFunc("/v2/snapshots", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -136,7 +136,7 @@ func TestSnapshots_GetSnapshotByID(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/snapshots/12345", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, `{"snapshot":{"id":"12345"}}`)
})
@ -157,7 +157,7 @@ func TestSnapshots_Destroy(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/snapshots/12345", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
ctx := context.Background()

View File

@ -4,6 +4,8 @@ import (
"fmt"
"time"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -94,7 +96,7 @@ func (svc *StorageServiceOp) ListVolumes(ctx context.Context, params *ListVolume
}
}
req, err := svc.client.NewRequest(ctx, "GET", path, nil)
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -116,7 +118,7 @@ func (svc *StorageServiceOp) ListVolumes(ctx context.Context, params *ListVolume
func (svc *StorageServiceOp) CreateVolume(ctx context.Context, createRequest *VolumeCreateRequest) (*Volume, *Response, error) {
path := storageAllocPath
req, err := svc.client.NewRequest(ctx, "POST", path, createRequest)
req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createRequest)
if err != nil {
return nil, nil, err
}
@ -133,7 +135,7 @@ func (svc *StorageServiceOp) CreateVolume(ctx context.Context, createRequest *Vo
func (svc *StorageServiceOp) GetVolume(ctx context.Context, id string) (*Volume, *Response, error) {
path := fmt.Sprintf("%s/%s", storageAllocPath, id)
req, err := svc.client.NewRequest(ctx, "GET", path, nil)
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -151,7 +153,7 @@ func (svc *StorageServiceOp) GetVolume(ctx context.Context, id string) (*Volume,
func (svc *StorageServiceOp) DeleteVolume(ctx context.Context, id string) (*Response, error) {
path := fmt.Sprintf("%s/%s", storageAllocPath, id)
req, err := svc.client.NewRequest(ctx, "DELETE", path, nil)
req, err := svc.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}
@ -174,7 +176,7 @@ func (svc *StorageServiceOp) ListSnapshots(ctx context.Context, volumeID string,
return nil, nil, err
}
req, err := svc.client.NewRequest(ctx, "GET", path, nil)
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -196,7 +198,7 @@ func (svc *StorageServiceOp) ListSnapshots(ctx context.Context, volumeID string,
func (svc *StorageServiceOp) CreateSnapshot(ctx context.Context, createRequest *SnapshotCreateRequest) (*Snapshot, *Response, error) {
path := fmt.Sprintf("%s/%s/snapshots", storageAllocPath, createRequest.VolumeID)
req, err := svc.client.NewRequest(ctx, "POST", path, createRequest)
req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createRequest)
if err != nil {
return nil, nil, err
}
@ -213,7 +215,7 @@ func (svc *StorageServiceOp) CreateSnapshot(ctx context.Context, createRequest *
func (svc *StorageServiceOp) GetSnapshot(ctx context.Context, id string) (*Snapshot, *Response, error) {
path := fmt.Sprintf("%s/%s", storageSnapPath, id)
req, err := svc.client.NewRequest(ctx, "GET", path, nil)
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -231,7 +233,7 @@ func (svc *StorageServiceOp) GetSnapshot(ctx context.Context, id string) (*Snaps
func (svc *StorageServiceOp) DeleteSnapshot(ctx context.Context, id string) (*Response, error) {
path := fmt.Sprintf("%s/%s", storageSnapPath, id)
req, err := svc.client.NewRequest(ctx, "DELETE", path, nil)
req, err := svc.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -77,7 +78,7 @@ func (s *StorageActionsServiceOp) Resize(ctx context.Context, volumeID string, s
func (s *StorageActionsServiceOp) doAction(ctx context.Context, volumeID string, request *ActionRequest) (*Action, *Response, error) {
path := storageAllocationActionPath(volumeID)
req, err := s.client.NewRequest(ctx, "POST", path, request)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, request)
if err != nil {
return nil, nil, err
}
@ -92,7 +93,7 @@ func (s *StorageActionsServiceOp) doAction(ctx context.Context, volumeID string,
}
func (s *StorageActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) {
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -107,7 +108,7 @@ func (s *StorageActionsServiceOp) get(ctx context.Context, path string) (*Action
}
func (s *StorageActionsServiceOp) list(ctx context.Context, path string) ([]Action, *Response, error) {
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

View File

@ -28,7 +28,7 @@ func TestStoragesActions_Attach(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, attachRequest) {
t.Errorf("want=%#v", attachRequest)
t.Errorf("got=%#v", v)
@ -60,7 +60,7 @@ func TestStoragesActions_DetachByDropletID(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, detachByDropletIDRequest) {
t.Errorf("want=%#v", detachByDropletIDRequest)
t.Errorf("got=%#v", v)
@ -80,7 +80,7 @@ func TestStorageActions_Get(t *testing.T) {
volumeID := "98d414c6-295e-4e3a-ac58-eb9456c1e1d1"
mux.HandleFunc("/v2/volumes/"+volumeID+"/actions/456", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`)
})
@ -101,7 +101,7 @@ func TestStorageActions_List(t *testing.T) {
volumeID := "98d414c6-295e-4e3a-ac58-eb9456c1e1d1"
mux.HandleFunc("/v2/volumes/"+volumeID+"/actions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprintf(w, `{"actions":[{"status":"in-progress"}]}`)
})
@ -134,7 +134,7 @@ func TestStoragesActions_Resize(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, resizeRequest) {
t.Errorf("want=%#v", resizeRequest)
t.Errorf("got=%#v", v)

View File

@ -48,7 +48,7 @@ func TestStorageVolumes_ListStorageVolumes(t *testing.T) {
}`
mux.HandleFunc("/v2/volumes/", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -114,7 +114,7 @@ func TestStorageVolumes_Get(t *testing.T) {
}`
mux.HandleFunc("/v2/volumes/80d414c6-295e-4e3a-ac58-eb9456c1e1d1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -166,7 +166,7 @@ func TestStorageVolumes_ListVolumesByName(t *testing.T) {
if r.URL.Query().Get("name") != "myvolume" || r.URL.Query().Get("region") != "nyc3" {
t.Errorf("Storage.GetVolumeByName did not request the correct name or region")
}
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -222,7 +222,7 @@ func TestStorageVolumes_Create(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, createRequest) {
t.Errorf("Request body = %+v, expected %+v", v, createRequest)
}
@ -277,7 +277,7 @@ func TestStorageVolumes_CreateFromSnapshot(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, createRequest) {
t.Errorf("Request body = %+v, expected %+v", v, createRequest)
}
@ -299,7 +299,7 @@ func TestStorageVolumes_Destroy(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/volumes/80d414c6-295e-4e3a-ac58-eb9456c1e1d1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Storage.DeleteVolume(ctx, "80d414c6-295e-4e3a-ac58-eb9456c1e1d1")
@ -342,7 +342,7 @@ func TestStorageSnapshots_ListStorageSnapshots(t *testing.T) {
}`
mux.HandleFunc("/v2/volumes/98d414c6-295e-4e3a-ac58-eb9456c1e1d1/snapshots", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -402,7 +402,7 @@ func TestStorageSnapshots_Get(t *testing.T) {
}`
mux.HandleFunc("/v2/snapshots/80d414c6-295e-4e3a-ac58-eb9456c1e1d1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, jBlob)
})
@ -459,7 +459,7 @@ func TestStorageSnapshots_Create(t *testing.T) {
t.Fatal(err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, createRequest) {
t.Errorf("Request body = %+v, expected %+v", v, createRequest)
}
@ -481,7 +481,7 @@ func TestStorageSnapshots_Destroy(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/snapshots/80d414c6-295e-4e3a-ac58-eb9456c1e1d1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Storage.DeleteSnapshot(ctx, "80d414c6-295e-4e3a-ac58-eb9456c1e1d1")

View File

@ -2,6 +2,7 @@ package godo
import (
"fmt"
"net/http"
"github.com/digitalocean/godo/context"
)
@ -93,7 +94,7 @@ func (s *TagsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Tag, *Res
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -114,7 +115,7 @@ func (s *TagsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Tag, *Res
func (s *TagsServiceOp) Get(ctx context.Context, name string) (*Tag, *Response, error) {
path := fmt.Sprintf("%s/%s", tagsBasePath, name)
req, err := s.client.NewRequest(ctx, "GET", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
@ -134,7 +135,7 @@ func (s *TagsServiceOp) Create(ctx context.Context, createRequest *TagCreateRequ
return nil, nil, NewArgError("createRequest", "cannot be nil")
}
req, err := s.client.NewRequest(ctx, "POST", tagsBasePath, createRequest)
req, err := s.client.NewRequest(ctx, http.MethodPost, tagsBasePath, createRequest)
if err != nil {
return nil, nil, err
}
@ -155,7 +156,7 @@ func (s *TagsServiceOp) Delete(ctx context.Context, name string) (*Response, err
}
path := fmt.Sprintf("%s/%s", tagsBasePath, name)
req, err := s.client.NewRequest(ctx, "DELETE", path, nil)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, err
}
@ -176,7 +177,7 @@ func (s *TagsServiceOp) TagResources(ctx context.Context, name string, tagReques
}
path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name)
req, err := s.client.NewRequest(ctx, "POST", path, tagRequest)
req, err := s.client.NewRequest(ctx, http.MethodPost, path, tagRequest)
if err != nil {
return nil, err
}
@ -197,7 +198,7 @@ func (s *TagsServiceOp) UntagResources(ctx context.Context, name string, untagRe
}
path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name)
req, err := s.client.NewRequest(ctx, "DELETE", path, untagRequest)
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, untagRequest)
if err != nil {
return nil, err
}

View File

@ -169,7 +169,7 @@ func TestTags_List(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/tags", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, listJSON)
})
@ -190,7 +190,7 @@ func TestTags_ListEmpty(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/tags", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, listEmptyJSON)
})
@ -210,7 +210,7 @@ func TestTags_ListPaging(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/tags", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, listJSON)
})
@ -226,7 +226,7 @@ func TestTags_Get(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/tags/testing-1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testMethod(t, r, http.MethodGet)
fmt.Fprint(w, getJSON)
})
@ -263,7 +263,7 @@ func TestTags_Create(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, createRequest) {
t.Errorf("Request body = %+v, expected %+v", v, createRequest)
}
@ -287,7 +287,7 @@ func TestTags_Delete(t *testing.T) {
defer teardown()
mux.HandleFunc("/v2/tags/testing-1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
})
_, err := client.Tags.Delete(ctx, "testing-1")
@ -312,7 +312,7 @@ func TestTags_TagResource(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "POST")
testMethod(t, r, http.MethodPost)
if !reflect.DeepEqual(v, tagResourcesRequest) {
t.Errorf("Request body = %+v, expected %+v", v, tagResourcesRequest)
}
@ -341,7 +341,7 @@ func TestTags_UntagResource(t *testing.T) {
t.Fatalf("decode json: %v", err)
}
testMethod(t, r, "DELETE")
testMethod(t, r, http.MethodDelete)
if !reflect.DeepEqual(v, untagResourcesRequest) {
t.Errorf("Request body = %+v, expected %+v", v, untagResourcesRequest)
}

Some files were not shown because too many files have changed in this diff Show More