forked from TrueCloudLab/lego
Add DNS Provider for IIJ (#606)
This commit is contained in:
parent
f3cfe4a24a
commit
725b6b816a
15 changed files with 1171 additions and 0 deletions
13
Gopkg.lock
generated
13
Gopkg.lock
generated
|
@ -202,6 +202,17 @@
|
||||||
revision = "d460ce9f8df2e77fb1ba55ca87fafed96c607494"
|
revision = "d460ce9f8df2e77fb1ba55ca87fafed96c607494"
|
||||||
version = "v1.0.0"
|
version = "v1.0.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
digest = "1:fed64c975620bacb8b3e531e31974149eef07fa0c4bc99185d35c4beaa6bd98a"
|
||||||
|
name = "github.com/iij/doapi"
|
||||||
|
packages = [
|
||||||
|
".",
|
||||||
|
"protocol",
|
||||||
|
]
|
||||||
|
pruneopts = "NUT"
|
||||||
|
revision = "afe9fa11fb27e5e8ab2dfc1675e91387aa63eaa2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:ac6d01547ec4f7f673311b4663909269bfb8249952de3279799289467837c3cc"
|
digest = "1:ac6d01547ec4f7f673311b4663909269bfb8249952de3279799289467837c3cc"
|
||||||
name = "github.com/jmespath/go-jmespath"
|
name = "github.com/jmespath/go-jmespath"
|
||||||
|
@ -506,6 +517,8 @@
|
||||||
"github.com/edeckers/auroradnsclient/records",
|
"github.com/edeckers/auroradnsclient/records",
|
||||||
"github.com/edeckers/auroradnsclient/zones",
|
"github.com/edeckers/auroradnsclient/zones",
|
||||||
"github.com/exoscale/egoscale",
|
"github.com/exoscale/egoscale",
|
||||||
|
"github.com/iij/doapi",
|
||||||
|
"github.com/iij/doapi/protocol",
|
||||||
"github.com/miekg/dns",
|
"github.com/miekg/dns",
|
||||||
"github.com/namedotcom/go/namecom",
|
"github.com/namedotcom/go/namecom",
|
||||||
"github.com/ovh/go-ovh/ovh",
|
"github.com/ovh/go-ovh/ovh",
|
||||||
|
|
1
cli.go
1
cli.go
|
@ -213,6 +213,7 @@ Here is an example bash command using the CloudFlare DNS provider:
|
||||||
fmt.Fprintln(w, "\tgandiv5:\tGANDIV5_API_KEY")
|
fmt.Fprintln(w, "\tgandiv5:\tGANDIV5_API_KEY")
|
||||||
fmt.Fprintln(w, "\tgcloud:\tGCE_PROJECT, GCE_SERVICE_ACCOUNT_FILE")
|
fmt.Fprintln(w, "\tgcloud:\tGCE_PROJECT, GCE_SERVICE_ACCOUNT_FILE")
|
||||||
fmt.Fprintln(w, "\tglesys:\tGLESYS_API_USER, GLESYS_API_KEY")
|
fmt.Fprintln(w, "\tglesys:\tGLESYS_API_USER, GLESYS_API_KEY")
|
||||||
|
fmt.Fprintln(w, "\tiij:\tIIJ_API_ACCESS_KEY, IIJ_API_SECRET_KEY, IIJ_DO_SERVICE_CODE")
|
||||||
fmt.Fprintln(w, "\tlinode:\tLINODE_API_KEY")
|
fmt.Fprintln(w, "\tlinode:\tLINODE_API_KEY")
|
||||||
fmt.Fprintln(w, "\tlightsail:\tAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, DNS_ZONE")
|
fmt.Fprintln(w, "\tlightsail:\tAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, DNS_ZONE")
|
||||||
fmt.Fprintln(w, "\tmanual:\tnone")
|
fmt.Fprintln(w, "\tmanual:\tnone")
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"github.com/xenolf/lego/providers/dns/gcloud"
|
"github.com/xenolf/lego/providers/dns/gcloud"
|
||||||
"github.com/xenolf/lego/providers/dns/glesys"
|
"github.com/xenolf/lego/providers/dns/glesys"
|
||||||
"github.com/xenolf/lego/providers/dns/godaddy"
|
"github.com/xenolf/lego/providers/dns/godaddy"
|
||||||
|
"github.com/xenolf/lego/providers/dns/iij"
|
||||||
"github.com/xenolf/lego/providers/dns/lightsail"
|
"github.com/xenolf/lego/providers/dns/lightsail"
|
||||||
"github.com/xenolf/lego/providers/dns/linode"
|
"github.com/xenolf/lego/providers/dns/linode"
|
||||||
"github.com/xenolf/lego/providers/dns/namecheap"
|
"github.com/xenolf/lego/providers/dns/namecheap"
|
||||||
|
@ -82,6 +83,8 @@ func NewDNSChallengeProviderByName(name string) (acme.ChallengeProvider, error)
|
||||||
return gcloud.NewDNSProvider()
|
return gcloud.NewDNSProvider()
|
||||||
case "godaddy":
|
case "godaddy":
|
||||||
return godaddy.NewDNSProvider()
|
return godaddy.NewDNSProvider()
|
||||||
|
case "iij":
|
||||||
|
return iij.NewDNSProvider()
|
||||||
case "lightsail":
|
case "lightsail":
|
||||||
return lightsail.NewDNSProvider()
|
return lightsail.NewDNSProvider()
|
||||||
case "linode":
|
case "linode":
|
||||||
|
|
211
providers/dns/iij/iij.go
Normal file
211
providers/dns/iij/iij.go
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
// Package iij implements a DNS provider for solving the DNS-01 challenge using IIJ DNS.
|
||||||
|
package iij
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/iij/doapi"
|
||||||
|
"github.com/iij/doapi/protocol"
|
||||||
|
"github.com/xenolf/lego/acme"
|
||||||
|
"github.com/xenolf/lego/platform/config/env"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config is used to configure the creation of the DNSProvider
|
||||||
|
type Config struct {
|
||||||
|
AccessKey string
|
||||||
|
SecretKey string
|
||||||
|
DoServiceCode string
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSProvider implements the acme.ChallengeProvider interface
|
||||||
|
type DNSProvider struct {
|
||||||
|
api *doapi.API
|
||||||
|
config *Config
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProvider returns a DNSProvider instance configured for IIJ DO
|
||||||
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
values, err := env.Get("IIJ_API_ACCESS_KEY", "IIJ_API_SECRET_KEY", "IIJ_DO_SERVICE_CODE")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("IIJ: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewDNSProviderConfig(&Config{
|
||||||
|
AccessKey: values["IIJ_API_ACCESS_KEY"],
|
||||||
|
SecretKey: values["IIJ_API_SECRET_KEY"],
|
||||||
|
DoServiceCode: values["IIJ_DO_SERVICE_CODE"],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProviderConfig takes a given config ans returns a custom configured
|
||||||
|
// DNSProvider instance
|
||||||
|
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
|
return &DNSProvider{
|
||||||
|
api: doapi.NewAPI(config.AccessKey, config.SecretKey),
|
||||||
|
config: config,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timeout returns the timeout and interval to use when checking for DNS propagation.
|
||||||
|
func (p *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
|
return time.Minute * 2, time.Second * 4
|
||||||
|
}
|
||||||
|
|
||||||
|
// Present creates a TXT record using the specified parameters
|
||||||
|
func (p *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
|
_, value, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
return p.addTxtRecord(domain, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CleanUp removes the TXT record matching the specified parameters
|
||||||
|
func (p *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
|
_, value, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
return p.deleteTxtRecord(domain, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DNSProvider) addTxtRecord(domain, value string) error {
|
||||||
|
zones, err := p.listZones()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
owner, zone, err := splitDomain(domain, zones)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
request := protocol.RecordAdd{
|
||||||
|
DoServiceCode: p.config.DoServiceCode,
|
||||||
|
ZoneName: zone,
|
||||||
|
Owner: owner,
|
||||||
|
TTL: "300",
|
||||||
|
RecordType: "TXT",
|
||||||
|
RData: value,
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &protocol.RecordAddResponse{}
|
||||||
|
|
||||||
|
if err := doapi.Call(*p.api, request, response); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DNSProvider) deleteTxtRecord(domain, value string) error {
|
||||||
|
zones, err := p.listZones()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
owner, zone, err := splitDomain(domain, zones)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := p.findTxtRecord(owner, zone, value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
request := protocol.RecordDelete{
|
||||||
|
DoServiceCode: p.config.DoServiceCode,
|
||||||
|
ZoneName: zone,
|
||||||
|
RecordID: id,
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &protocol.RecordDeleteResponse{}
|
||||||
|
|
||||||
|
if err := doapi.Call(*p.api, request, response); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DNSProvider) commit() error {
|
||||||
|
request := protocol.Commit{
|
||||||
|
DoServiceCode: p.config.DoServiceCode,
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &protocol.CommitResponse{}
|
||||||
|
|
||||||
|
return doapi.Call(*p.api, request, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DNSProvider) findTxtRecord(owner, zone, value string) (string, error) {
|
||||||
|
request := protocol.RecordListGet{
|
||||||
|
DoServiceCode: p.config.DoServiceCode,
|
||||||
|
ZoneName: zone,
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &protocol.RecordListGetResponse{}
|
||||||
|
|
||||||
|
if err := doapi.Call(*p.api, request, response); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var id string
|
||||||
|
|
||||||
|
for _, record := range response.RecordList {
|
||||||
|
if record.Owner == owner && record.RecordType == "TXT" && record.RData == "\""+value+"\"" {
|
||||||
|
id = record.Id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if id == "" {
|
||||||
|
return "", fmt.Errorf("%s record in %s not found", owner, zone)
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DNSProvider) listZones() ([]string, error) {
|
||||||
|
request := protocol.ZoneListGet{
|
||||||
|
DoServiceCode: p.config.DoServiceCode,
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &protocol.ZoneListGetResponse{}
|
||||||
|
|
||||||
|
if err := doapi.Call(*p.api, request, response); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.ZoneList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitDomain(domain string, zones []string) (string, string, error) {
|
||||||
|
parts := strings.Split(strings.Trim(domain, "."), ".")
|
||||||
|
|
||||||
|
var owner string
|
||||||
|
var zone string
|
||||||
|
|
||||||
|
for i := 0; i < len(parts)-1; i++ {
|
||||||
|
zone = strings.Join(parts[i:], ".")
|
||||||
|
if zoneContains(zone, zones) {
|
||||||
|
baseOwner := strings.Join(parts[0:i], ".")
|
||||||
|
if len(baseOwner) > 0 {
|
||||||
|
baseOwner = "." + baseOwner
|
||||||
|
}
|
||||||
|
owner = "_acme-challenge" + baseOwner
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(owner) == 0 {
|
||||||
|
return "", "", fmt.Errorf("%s not found", domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
return owner, zone, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func zoneContains(zone string, zones []string) bool {
|
||||||
|
for _, z := range zones {
|
||||||
|
if zone == z {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
132
providers/dns/iij/iij_test.go
Normal file
132
providers/dns/iij/iij_test.go
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
package iij
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
apiAccessKeyEnv string
|
||||||
|
apiSecretKeyEnv string
|
||||||
|
doServiceCodeEnv string
|
||||||
|
testDomain string
|
||||||
|
liveTest bool
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
apiAccessKeyEnv = os.Getenv("IIJ_API_ACCESS_KEY")
|
||||||
|
apiSecretKeyEnv = os.Getenv("IIJ_API_SECRET_KEY")
|
||||||
|
doServiceCodeEnv = os.Getenv("IIJ_DO_SERVICE_CODE")
|
||||||
|
|
||||||
|
testDomain = os.Getenv("IIJ_API_TESTDOMAIN")
|
||||||
|
|
||||||
|
if len(apiAccessKeyEnv) > 0 && len(apiSecretKeyEnv) > 0 && len(doServiceCodeEnv) > 0 && len(testDomain) > 0 {
|
||||||
|
liveTest = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func restoreEnv() {
|
||||||
|
os.Setenv("IIJ_API_ACCESS_KEY", apiAccessKeyEnv)
|
||||||
|
os.Setenv("IIJ_API_SECRET_KEY", apiSecretKeyEnv)
|
||||||
|
os.Setenv("IIJ_DO_SERVICE_CODE", doServiceCodeEnv)
|
||||||
|
os.Setenv("IIJ_API_TESTDOMAIN", testDomain)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSplitDomain(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
domain string
|
||||||
|
zones []string
|
||||||
|
expectedOwner string
|
||||||
|
expectedZone string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "domain equals zone",
|
||||||
|
domain: "domain.com",
|
||||||
|
zones: []string{"domain.com"},
|
||||||
|
expectedOwner: "_acme-challenge",
|
||||||
|
expectedZone: "domain.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "with a sub domain",
|
||||||
|
domain: "my.domain.com",
|
||||||
|
zones: []string{"domain.com"},
|
||||||
|
expectedOwner: "_acme-challenge.my",
|
||||||
|
expectedZone: "domain.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "with a sub domain in a zone",
|
||||||
|
domain: "my.sub.domain.com",
|
||||||
|
zones: []string{"sub.domain.com", "domain.com"},
|
||||||
|
expectedOwner: "_acme-challenge.my",
|
||||||
|
expectedZone: "sub.domain.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "with a sub sub domain",
|
||||||
|
domain: "my.sub.domain.com",
|
||||||
|
zones: []string{"domain1.com", "domain.com"},
|
||||||
|
expectedOwner: "_acme-challenge.my.sub",
|
||||||
|
expectedZone: "domain.com",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
owner, zone, err := splitDomain(test.domain, test.zones)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, test.expectedOwner, owner)
|
||||||
|
assert.Equal(t, test.expectedZone, zone)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewDNSProviderMissingCredErr(t *testing.T) {
|
||||||
|
defer restoreEnv()
|
||||||
|
os.Setenv("IIJ_API_ACCESS_KEY", "")
|
||||||
|
os.Setenv("IIJ_API_SECRET_KEY", "")
|
||||||
|
os.Setenv("IIJ_DO_SERVICE_CODE", "")
|
||||||
|
|
||||||
|
_, err := NewDNSProvider()
|
||||||
|
assert.EqualError(t, err, "IIJ: some credentials information are missing: IIJ_API_ACCESS_KEY,IIJ_API_SECRET_KEY,IIJ_DO_SERVICE_CODE")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewDNSProvider(t *testing.T) {
|
||||||
|
if !liveTest {
|
||||||
|
t.Skip("skipping live test")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := NewDNSProvider()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDNSProvider_Present(t *testing.T) {
|
||||||
|
if !liveTest {
|
||||||
|
t.Skip("skipping live test")
|
||||||
|
}
|
||||||
|
|
||||||
|
provider, err := NewDNSProvider()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = provider.Present(testDomain, "", "123d==")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDNSProvider_CleanUp(t *testing.T) {
|
||||||
|
if !liveTest {
|
||||||
|
t.Skip("skipping live test")
|
||||||
|
}
|
||||||
|
|
||||||
|
provider, err := NewDNSProvider()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = provider.CleanUp(testDomain, "", "123d==")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
164
vendor/github.com/iij/doapi/api.go
generated
vendored
Normal file
164
vendor/github.com/iij/doapi/api.go
generated
vendored
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
// Package doapi : DO APIクライアントモジュール
|
||||||
|
package doapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
HmacSHA1 = "HmacSHA1"
|
||||||
|
HmacSHA256 = "HmacSHA256"
|
||||||
|
SignatureVersion2 = "2"
|
||||||
|
APIVersion = "20140601"
|
||||||
|
EndpointJSON = "https://do.api.iij.jp/"
|
||||||
|
// EndpointJSON = "http://localhost:9999/"
|
||||||
|
TimeLayout = "2006-01-02T15:04:05Z"
|
||||||
|
PostContentType = "application/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// API の呼び出し先に関連する構造
|
||||||
|
type API struct {
|
||||||
|
AccessKey string
|
||||||
|
SecretKey string
|
||||||
|
Endpoint string
|
||||||
|
SignMethod string
|
||||||
|
Expires time.Duration
|
||||||
|
Insecure bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAPI API構造体のコンストラクタ
|
||||||
|
func NewAPI(accesskey, secretkey string) *API {
|
||||||
|
dur, _ := time.ParseDuration("1h")
|
||||||
|
return &API{AccessKey: accesskey,
|
||||||
|
SecretKey: secretkey,
|
||||||
|
Endpoint: EndpointJSON,
|
||||||
|
SignMethod: HmacSHA256,
|
||||||
|
Expires: dur,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func convert1(r byte) string {
|
||||||
|
passchar := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_~.-"
|
||||||
|
if strings.ContainsRune(passchar, rune(r)) {
|
||||||
|
return string(r)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%%%02X", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CustomEscape escape string
|
||||||
|
func CustomEscape(v string) string {
|
||||||
|
res := ""
|
||||||
|
for _, c := range []byte(v) {
|
||||||
|
res += convert1(c)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// String2Sign get string to calculate signature
|
||||||
|
func String2Sign(method string, header http.Header, param url.URL) string {
|
||||||
|
var keys []string
|
||||||
|
ctflag := false
|
||||||
|
for k := range header {
|
||||||
|
hdr := strings.ToLower(k)
|
||||||
|
if strings.HasPrefix(hdr, "x-iijapi-") {
|
||||||
|
keys = append(keys, hdr)
|
||||||
|
} else if hdr == "content-type" || hdr == "content-md5" {
|
||||||
|
keys = append(keys, hdr)
|
||||||
|
ctflag = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
var target []string
|
||||||
|
target = append(target, method)
|
||||||
|
target = append(target, "")
|
||||||
|
if !ctflag {
|
||||||
|
target = append(target, "")
|
||||||
|
}
|
||||||
|
for _, k := range keys {
|
||||||
|
if k == "content-type" || k == "content-md5" {
|
||||||
|
target = append(target, header.Get(k))
|
||||||
|
} else {
|
||||||
|
target = append(target, k+":"+header.Get(k))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target = append(target, param.Path)
|
||||||
|
return strings.Join(target, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign get signature string
|
||||||
|
func (a API) Sign(method string, header http.Header, param url.URL, signmethod string) http.Header {
|
||||||
|
header.Set("x-iijapi-Expire", time.Now().Add(a.Expires).UTC().Format(TimeLayout))
|
||||||
|
header.Set("x-iijapi-SignatureMethod", signmethod)
|
||||||
|
header.Set("x-iijapi-SignatureVersion", SignatureVersion2)
|
||||||
|
tgtstr := String2Sign(method, header, param)
|
||||||
|
var hfn func() hash.Hash
|
||||||
|
switch signmethod {
|
||||||
|
case HmacSHA1:
|
||||||
|
hfn = sha1.New
|
||||||
|
case HmacSHA256:
|
||||||
|
hfn = sha256.New
|
||||||
|
}
|
||||||
|
mac := hmac.New(hfn, []byte(a.SecretKey))
|
||||||
|
io.WriteString(mac, tgtstr)
|
||||||
|
macstr := mac.Sum(nil)
|
||||||
|
header.Set("Authorization", "IIJAPI "+a.AccessKey+":"+base64.StdEncoding.EncodeToString(macstr))
|
||||||
|
return header
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get : low-level Get
|
||||||
|
func (a API) Get(param url.URL) (resp *http.Response, err error) {
|
||||||
|
return a.PostSome("GET", param, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostSome : low-level Call
|
||||||
|
func (a API) PostSome(method string, param url.URL, body interface{}) (resp *http.Response, err error) {
|
||||||
|
cl := http.Client{}
|
||||||
|
if a.Insecure {
|
||||||
|
tr := &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
cl.Transport = tr
|
||||||
|
}
|
||||||
|
log.Debug("param", param)
|
||||||
|
var buf *bytes.Buffer
|
||||||
|
if body != nil {
|
||||||
|
var bufb []byte
|
||||||
|
bufb, err = json.Marshal(body)
|
||||||
|
if len(bufb) > 2 {
|
||||||
|
log.Debug("call with body", method, string(bufb))
|
||||||
|
buf = bytes.NewBuffer(bufb)
|
||||||
|
} else {
|
||||||
|
// string(bufb)=="{}"
|
||||||
|
log.Debug("call without body(empty)", method)
|
||||||
|
buf = bytes.NewBufferString("")
|
||||||
|
body = nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Debug("call without body(nil)", method)
|
||||||
|
buf = bytes.NewBufferString("")
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest(method, param.String(), buf)
|
||||||
|
if body != nil {
|
||||||
|
req.Header.Add("content-type", PostContentType)
|
||||||
|
}
|
||||||
|
req.Header = a.Sign(method, req.Header, param, HmacSHA256)
|
||||||
|
log.Debug("sign", req.Header)
|
||||||
|
resp, err = cl.Do(req)
|
||||||
|
return
|
||||||
|
}
|
267
vendor/github.com/iij/doapi/parse.go
generated
vendored
Normal file
267
vendor/github.com/iij/doapi/parse.go
generated
vendored
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
package doapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/iij/doapi/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
func execTemplate(name string, tmplstr string, arg interface{}) string {
|
||||||
|
tmpl, err := template.New(name).Parse(tmplstr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
if err = tmpl.Execute(buf, arg); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPath APIのURIのパス部分を求める
|
||||||
|
func GetPath(arg protocol.CommonArg) string {
|
||||||
|
return "/r/" + APIVersion + execTemplate(arg.APIName(), arg.URI(), arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetParam APIのクエリストリング部分を求める
|
||||||
|
func GetParam(api API, arg protocol.CommonArg) *url.URL {
|
||||||
|
param, err := url.Parse(api.Endpoint)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
param.Path = GetPath(arg)
|
||||||
|
q := param.Query()
|
||||||
|
_, toQuery, _ := ArgumentListType(arg)
|
||||||
|
typs := reflect.TypeOf(arg)
|
||||||
|
vals := reflect.ValueOf(arg)
|
||||||
|
for _, key := range toQuery {
|
||||||
|
if _, flag := typs.FieldByName(key); !flag {
|
||||||
|
log.Info("no field", key)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if val := vals.FieldByName(key).String(); len(val) != 0 {
|
||||||
|
q.Set(key, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param.RawQuery = q.Encode()
|
||||||
|
return param
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBody API呼び出しのリクエストボディ(JSON文字列)を求める
|
||||||
|
func GetBody(arg protocol.CommonArg) string {
|
||||||
|
b, err := json.Marshal(arg)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call API呼び出しを実行し、レスポンスを得る
|
||||||
|
func Call(api API, arg protocol.CommonArg, resp interface{}) (err error) {
|
||||||
|
if err = Validate(arg); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var res *http.Response
|
||||||
|
param := GetParam(api, arg)
|
||||||
|
log.Debug("method", arg.Method(), "param", param, "arg", arg)
|
||||||
|
if res, err = api.PostSome(arg.Method(), *param, arg); err != nil {
|
||||||
|
log.Error("PostSome", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Debug("res", res, "err", err)
|
||||||
|
var b []byte
|
||||||
|
if b, err = ioutil.ReadAll(res.Body); err != nil {
|
||||||
|
log.Error("ioutil.ReadAll", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Debug("data", string(b))
|
||||||
|
if err = json.Unmarshal(b, &resp); err != nil {
|
||||||
|
log.Error("json.Unmarshal", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var cresp = protocol.CommonResponse{}
|
||||||
|
err = json.Unmarshal(b, &cresp)
|
||||||
|
if err == nil && cresp.ErrorResponse.ErrorType != "" {
|
||||||
|
return fmt.Errorf("%s: %s", cresp.ErrorResponse.ErrorType, cresp.ErrorResponse.ErrorMessage)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate APIの必須引数が入っているかどうかをチェック
|
||||||
|
func Validate(arg protocol.CommonArg) error {
|
||||||
|
var res []string
|
||||||
|
typs := reflect.TypeOf(arg)
|
||||||
|
vals := reflect.ValueOf(arg)
|
||||||
|
for i := 0; i < typs.NumField(); i++ {
|
||||||
|
fld := typs.Field(i)
|
||||||
|
tagstrJSON := fld.Tag.Get("json")
|
||||||
|
tagstrP2 := fld.Tag.Get("p2pub")
|
||||||
|
if strings.Contains(tagstrJSON, "omitempty") {
|
||||||
|
// optional argument
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.Contains(tagstrP2, "query") {
|
||||||
|
// optional argument
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if val := vals.Field(i).String(); len(val) == 0 {
|
||||||
|
res = append(res, fld.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(res) != 0 {
|
||||||
|
return fmt.Errorf("missing arguments: %+v", res)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArgumentList API引数のリストを求める。必須とオプションに分類
|
||||||
|
func ArgumentList(arg protocol.CommonArg) (required, optional []string) {
|
||||||
|
typs := reflect.TypeOf(arg)
|
||||||
|
for i := 0; i < typs.NumField(); i++ {
|
||||||
|
fld := typs.Field(i)
|
||||||
|
tagstrJSON := fld.Tag.Get("json")
|
||||||
|
tagstrP2 := fld.Tag.Get("p2pub")
|
||||||
|
if strings.Contains(tagstrJSON, "omitempty") || strings.Contains(tagstrP2, "query") {
|
||||||
|
optional = append(optional, fld.Name)
|
||||||
|
} else {
|
||||||
|
required = append(required, fld.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArgumentListType API引数のリストを求める。URI埋め込み、クエリストリング、JSONに分類
|
||||||
|
func ArgumentListType(arg protocol.CommonArg) (toURI, toQuery, toJSON []string) {
|
||||||
|
typs := reflect.TypeOf(arg)
|
||||||
|
for i := 0; i < typs.NumField(); i++ {
|
||||||
|
fld := typs.Field(i)
|
||||||
|
tagstrJSON := fld.Tag.Get("json")
|
||||||
|
tagstrP2 := fld.Tag.Get("p2pub")
|
||||||
|
if strings.Contains(tagstrP2, "query") {
|
||||||
|
toQuery = append(toQuery, fld.Name)
|
||||||
|
} else if strings.HasPrefix(tagstrJSON, "-") {
|
||||||
|
toURI = append(toURI, fld.Name)
|
||||||
|
} else {
|
||||||
|
toJSON = append(toJSON, fld.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func argumentAltKeyList(arg protocol.CommonArg) (toAltQuery, toAltJSON map[string]string) {
|
||||||
|
toAltQuery = make(map[string]string)
|
||||||
|
toAltJSON = make(map[string]string)
|
||||||
|
typs := reflect.TypeOf(arg)
|
||||||
|
for i := 0; i < typs.NumField(); i++ {
|
||||||
|
fld := typs.Field(i)
|
||||||
|
tagstrJSON := fld.Tag.Get("json")
|
||||||
|
tagstrP2 := fld.Tag.Get("p2pub")
|
||||||
|
altKey := strings.Split(tagstrJSON, ",")[0]
|
||||||
|
if altKey == "" || altKey == "-" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.Contains(tagstrP2, "query") {
|
||||||
|
toAltQuery[fld.Name] = altKey
|
||||||
|
} else {
|
||||||
|
toAltJSON[fld.Name] = altKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateMap APIの必須引数が入っているかどうかをチェック
|
||||||
|
func ValidateMap(name string, data map[string]string) error {
|
||||||
|
var res []string
|
||||||
|
typs := protocol.TypeMap[name]
|
||||||
|
for i := 0; i < typs.NumField(); i++ {
|
||||||
|
fld := typs.Field(i)
|
||||||
|
tagstrJSON := fld.Tag.Get("json")
|
||||||
|
tagstrP2 := fld.Tag.Get("p2pub")
|
||||||
|
if strings.Contains(tagstrJSON, "omitempty") {
|
||||||
|
// optional argument
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.Contains(tagstrP2, "query") {
|
||||||
|
// optional argument
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if data[fld.Name] == "" {
|
||||||
|
res = append(res, fld.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(res) != 0 {
|
||||||
|
return fmt.Errorf("missing arguments: %+v", res)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallWithMap API呼び出しを実行する。引数と戻り値が構造体ではなくmap
|
||||||
|
func CallWithMap(api API, name string, data map[string]string, resp map[string]interface{}) error {
|
||||||
|
if err := ValidateMap(name, data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
argt := protocol.TypeMap[name]
|
||||||
|
arg := reflect.Zero(argt).Interface().(protocol.CommonArg)
|
||||||
|
var res *http.Response
|
||||||
|
param, err := url.Parse(api.Endpoint)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
param.Path = "/r/" + APIVersion + execTemplate(name, arg.URI(), data)
|
||||||
|
q := param.Query()
|
||||||
|
_, toQuery, toJSON := ArgumentListType(arg)
|
||||||
|
log.Debug("query", toQuery, "json", toJSON, "path", param.Path)
|
||||||
|
toAltQuery, toAltJSON := argumentAltKeyList(arg)
|
||||||
|
log.Debug("query altkey - ", toAltQuery, " json altkey - ", toAltJSON)
|
||||||
|
var jsonmap = map[string]interface{}{}
|
||||||
|
for _, v := range toJSON {
|
||||||
|
if len(data[v]) != 0 {
|
||||||
|
if altkey, ok := toAltJSON[v]; ok {
|
||||||
|
jsonmap[altkey] = data[v]
|
||||||
|
} else {
|
||||||
|
jsonmap[v] = data[v]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, v := range toQuery {
|
||||||
|
if len(data[v]) != 0 {
|
||||||
|
if altkey, ok := toAltQuery[v]; ok {
|
||||||
|
q.Set(altkey, data[v])
|
||||||
|
} else {
|
||||||
|
q.Set(v, data[v])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param.RawQuery = q.Encode()
|
||||||
|
if res, err = api.PostSome(arg.Method(), *param, jsonmap); err != nil {
|
||||||
|
log.Error("PostSome", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debug("res", res)
|
||||||
|
var b []byte
|
||||||
|
if b, err = ioutil.ReadAll(res.Body); err != nil {
|
||||||
|
log.Error("ioutil.ReadAll", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debug("data", string(b))
|
||||||
|
if err = json.Unmarshal(b, &resp); err != nil {
|
||||||
|
log.Error("json.Unmarshal", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if val, ok := resp["ErrorResponse"]; ok {
|
||||||
|
errstr := execTemplate("ErrorResponse", "{{.ErrorType}}: {{.ErrorMessage}}", val)
|
||||||
|
return errors.New(errstr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
44
vendor/github.com/iij/doapi/protocol/Commit.go
generated
vendored
Normal file
44
vendor/github.com/iij/doapi/protocol/Commit.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Commit
|
||||||
|
type Commit struct {
|
||||||
|
DoServiceCode string `json:"-"` // DO契約のサービスコード(do########)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URI /{{.DoServiceCode}}/commit.json
|
||||||
|
func (t Commit) URI() string {
|
||||||
|
return "/{{.DoServiceCode}}/commit.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIName Commit
|
||||||
|
func (t Commit) APIName() string {
|
||||||
|
return "Commit"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method PUT
|
||||||
|
func (t Commit) Method() string {
|
||||||
|
return "PUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://manual.iij.jp/dns/doapi/754632.html
|
||||||
|
func (t Commit) Document() string {
|
||||||
|
return "http://manual.iij.jp/dns/doapi/754632.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
// JPName PUT Commit
|
||||||
|
func (t Commit) JPName() string {
|
||||||
|
return "PUT commit"
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
APIlist = append(APIlist, Commit{})
|
||||||
|
TypeMap["Commit"] = reflect.TypeOf(Commit{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitResponse PUT Commitのレスポンス
|
||||||
|
type CommitResponse struct {
|
||||||
|
*CommonResponse
|
||||||
|
}
|
51
vendor/github.com/iij/doapi/protocol/RecordAdd.go
generated
vendored
Normal file
51
vendor/github.com/iij/doapi/protocol/RecordAdd.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RecordAdd POST record (同期)
|
||||||
|
// http://manual.iij.jp/dns/doapi/754517.html
|
||||||
|
type RecordAdd struct {
|
||||||
|
DoServiceCode string `json:"-"` // DO契約のサービスコード(do########)
|
||||||
|
ZoneName string `json:"-"` // Zone Name
|
||||||
|
Owner string // owner of record
|
||||||
|
TTL string // TTL of record
|
||||||
|
RecordType string // type of record
|
||||||
|
RData string // data of record
|
||||||
|
}
|
||||||
|
|
||||||
|
// URI /:GisServiceCode/fw-lbs/:IflServiceCode/filters/:IpVersion/:Direction.json
|
||||||
|
func (t RecordAdd) URI() string {
|
||||||
|
return "/{{.DoServiceCode}}/{{.ZoneName}}/record.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIName RecordAdd
|
||||||
|
func (t RecordAdd) APIName() string {
|
||||||
|
return "RecordAdd"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method POST
|
||||||
|
func (t RecordAdd) Method() string {
|
||||||
|
return "POST"
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://manual.iij.jp/dns/doapi/754517.html
|
||||||
|
func (t RecordAdd) Document() string {
|
||||||
|
return "http://manual.iij.jp/dns/doapi/754517.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
// JPName POST record
|
||||||
|
func (t RecordAdd) JPName() string {
|
||||||
|
return "POST record"
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
APIlist = append(APIlist, RecordAdd{})
|
||||||
|
TypeMap["RecordAdd"] = reflect.TypeOf(RecordAdd{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecordAddResponse POST recordのレスポンス
|
||||||
|
type RecordAddResponse struct {
|
||||||
|
*CommonResponse
|
||||||
|
Record ResourceRecord
|
||||||
|
}
|
47
vendor/github.com/iij/doapi/protocol/RecordDelete.go
generated
vendored
Normal file
47
vendor/github.com/iij/doapi/protocol/RecordDelete.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RecordDelete DELETE record
|
||||||
|
// http://manual.iij.jp/dns/doapi/754525.html
|
||||||
|
type RecordDelete struct {
|
||||||
|
DoServiceCode string `json:"-"` // DO契約のサービスコード(do########)
|
||||||
|
ZoneName string `json:"-"` // Zone Name
|
||||||
|
RecordID string `json:"-"` // Record ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// URI /{{.DoServiceCode}}/{{.ZoneName}}/record/{{.RecordID}}.json
|
||||||
|
func (t RecordDelete) URI() string {
|
||||||
|
return "/{{.DoServiceCode}}/{{.ZoneName}}/record/{{.RecordID}}.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIName RecordDelete
|
||||||
|
func (t RecordDelete) APIName() string {
|
||||||
|
return "RecordDelete"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method DELETE
|
||||||
|
func (t RecordDelete) Method() string {
|
||||||
|
return "DELETE"
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://manual.iij.jp/dns/doapi/754525.html
|
||||||
|
func (t RecordDelete) Document() string {
|
||||||
|
return "http://manual.iij.jp/dns/doapi/754525.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
// JPName DELETE record
|
||||||
|
func (t RecordDelete) JPName() string {
|
||||||
|
return "DELETE record"
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
APIlist = append(APIlist, RecordDelete{})
|
||||||
|
TypeMap["RecordDelete"] = reflect.TypeOf(RecordDelete{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecordDeleteResponse DELETE recordのレスポンス
|
||||||
|
type RecordDeleteResponse struct {
|
||||||
|
*CommonResponse
|
||||||
|
}
|
48
vendor/github.com/iij/doapi/protocol/RecordGet.go
generated
vendored
Normal file
48
vendor/github.com/iij/doapi/protocol/RecordGet.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GET records
|
||||||
|
// http://manual.iij.jp/dns/doapi/754619.html
|
||||||
|
type RecordGet struct {
|
||||||
|
DoServiceCode string `json:"-"` // DO契約のサービスコード(do########)
|
||||||
|
ZoneName string `json:"-"` // ゾーン名
|
||||||
|
RecordID string `json:"-"` //
|
||||||
|
}
|
||||||
|
|
||||||
|
// URI /{{.DoServiceCode}}/{{.ZoneName}}/record/{{.RecordID}}.json
|
||||||
|
func (t RecordGet) URI() string {
|
||||||
|
return "/{{.DoServiceCode}}/{{.ZoneName}}/record/{{.RecordID}}.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIName RecordGet
|
||||||
|
func (t RecordGet) APIName() string {
|
||||||
|
return "RecordGet"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method GET
|
||||||
|
func (t RecordGet) Method() string {
|
||||||
|
return "GET"
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://manual.iij.jp/dns/doapi/754503.html
|
||||||
|
func (t RecordGet) Document() string {
|
||||||
|
return "http://manual.iij.jp/dns/doapi/754503.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
// JPName GET record
|
||||||
|
func (t RecordGet) JPName() string {
|
||||||
|
return "GET record"
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
APIlist = append(APIlist, RecordGet{})
|
||||||
|
TypeMap["RecordGet"] = reflect.TypeOf(RecordGet{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecordGetResponse フィルタリングルール情報取得のレスポンス
|
||||||
|
type RecordGetResponse struct {
|
||||||
|
*CommonResponse
|
||||||
|
Record ResourceRecord
|
||||||
|
}
|
47
vendor/github.com/iij/doapi/protocol/RecordListGet.go
generated
vendored
Normal file
47
vendor/github.com/iij/doapi/protocol/RecordListGet.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GET records
|
||||||
|
type RecordListGet struct {
|
||||||
|
DoServiceCode string `json:"-"` // DO契約のサービスコード(do########)
|
||||||
|
ZoneName string `json:"-"` // ゾーン名
|
||||||
|
}
|
||||||
|
|
||||||
|
// URI /{{.DoServiceCode}}/{{.ZoneName}}/records/DETAIL.json
|
||||||
|
func (t RecordListGet) URI() string {
|
||||||
|
return "/{{.DoServiceCode}}/{{.ZoneName}}/records/DETAIL.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIName RecordListGet
|
||||||
|
func (t RecordListGet) APIName() string {
|
||||||
|
return "RecordListGet"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method GET
|
||||||
|
func (t RecordListGet) Method() string {
|
||||||
|
return "GET"
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://manual.iij.jp/dns/doapi/754619.html
|
||||||
|
func (t RecordListGet) Document() string {
|
||||||
|
return "http://manual.iij.jp/dns/doapi/754619.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
// JPName GET records
|
||||||
|
func (t RecordListGet) JPName() string {
|
||||||
|
return "GET records"
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
APIlist = append(APIlist, RecordListGet{})
|
||||||
|
TypeMap["RecordListGet"] = reflect.TypeOf(RecordListGet{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecordListGetResponse GET recordsのレスポンス
|
||||||
|
type RecordListGetResponse struct {
|
||||||
|
*CommonResponse
|
||||||
|
RecordList []ResourceRecord
|
||||||
|
StaticRecordList []ResourceRecord
|
||||||
|
}
|
45
vendor/github.com/iij/doapi/protocol/Reset.go
generated
vendored
Normal file
45
vendor/github.com/iij/doapi/protocol/Reset.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reset PUT reset (同期)
|
||||||
|
type Reset struct {
|
||||||
|
DoServiceCode string `json:"-"` // DO契約のサービスコード(do########)
|
||||||
|
ZoneName string `json:"-"` // Zone name
|
||||||
|
}
|
||||||
|
|
||||||
|
// URI /{{.DoServiceCode}}/{{.ZoneName}}/reset.json
|
||||||
|
func (t Reset) URI() string {
|
||||||
|
return "/{{.DoServiceCode}}/{{.ZoneName}}/reset.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIName Reset
|
||||||
|
func (t Reset) APIName() string {
|
||||||
|
return "Reset"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method PUT
|
||||||
|
func (t Reset) Method() string {
|
||||||
|
return "PUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://manual.iij.jp/dns/doapi/754610.html
|
||||||
|
func (t Reset) Document() string {
|
||||||
|
return "http://manual.iij.jp/dns/doapi/754610.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
// JPName PUT reset
|
||||||
|
func (t Reset) JPName() string {
|
||||||
|
return "PUT Reset"
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
APIlist = append(APIlist, Reset{})
|
||||||
|
TypeMap["Reset"] = reflect.TypeOf(Reset{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetResponse PUT resetのレスポンス
|
||||||
|
type ResetResponse struct {
|
||||||
|
*CommonResponse
|
||||||
|
}
|
45
vendor/github.com/iij/doapi/protocol/ZoneListGet.go
generated
vendored
Normal file
45
vendor/github.com/iij/doapi/protocol/ZoneListGet.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GET zones
|
||||||
|
type ZoneListGet struct {
|
||||||
|
DoServiceCode string `json:"-"` // DO契約のサービスコード(do########)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URI /{{.DoServiceCode}}/zones.json
|
||||||
|
func (t ZoneListGet) URI() string {
|
||||||
|
return "/{{.DoServiceCode}}/zones.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIName ZoneListGet
|
||||||
|
func (t ZoneListGet) APIName() string {
|
||||||
|
return "ZoneListGet"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method GET
|
||||||
|
func (t ZoneListGet) Method() string {
|
||||||
|
return "GET"
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://manual.iij.jp/dns/doapi/754466.html
|
||||||
|
func (t ZoneListGet) Document() string {
|
||||||
|
return "http://manual.iij.jp/dns/doapi/754466.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
// JPName GET zones
|
||||||
|
func (t ZoneListGet) JPName() string {
|
||||||
|
return "GET zones"
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
APIlist = append(APIlist, ZoneListGet{})
|
||||||
|
TypeMap["ZoneListGet"] = reflect.TypeOf(ZoneListGet{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ZoneListGetResponse GET zonesのレスポンス
|
||||||
|
type ZoneListGetResponse struct {
|
||||||
|
*CommonResponse
|
||||||
|
ZoneList []string
|
||||||
|
}
|
53
vendor/github.com/iij/doapi/protocol/common.go
generated
vendored
Normal file
53
vendor/github.com/iij/doapi/protocol/common.go
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
//go:generate python doc2struct.py
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommonArg interface {
|
||||||
|
APIName() string
|
||||||
|
Method() string
|
||||||
|
URI() string
|
||||||
|
Document() string
|
||||||
|
JPName() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommonResponse struct {
|
||||||
|
RequestId string
|
||||||
|
ErrorResponse struct {
|
||||||
|
RequestId string
|
||||||
|
ErrorType string
|
||||||
|
ErrorMessage string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var APIlist []CommonArg
|
||||||
|
|
||||||
|
var TypeMap = map[string]reflect.Type{}
|
||||||
|
|
||||||
|
type ResourceRecord struct {
|
||||||
|
Id string `json:",omitempty"`
|
||||||
|
Status string
|
||||||
|
Owner string
|
||||||
|
TTL string
|
||||||
|
RecordType string
|
||||||
|
RData string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ResourceRecord) String() string {
|
||||||
|
return fmt.Sprintf("%s %s IN %s %s", r.Owner, r.TTL, r.RecordType, r.RData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ResourceRecord) FQDN(zone string) string {
|
||||||
|
return fmt.Sprintf("%s.%s %s IN %s %s", r.Owner, zone, r.TTL, r.RecordType, r.RData)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
UNCAHNGED = "UNCHANGED"
|
||||||
|
ADDING = "ADDING"
|
||||||
|
DELETING = "DELETING"
|
||||||
|
DELETED = "DELETED"
|
||||||
|
)
|
Loading…
Reference in a new issue