Implement OVH API source
This commit is contained in:
parent
0f31d26875
commit
dd12314385
2
go.mod
2
go.mod
|
@ -6,5 +6,7 @@ require (
|
|||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/miekg/dns v1.1.29
|
||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
gopkg.in/ini.v1 v1.55.0 // indirect
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -12,6 +12,8 @@ github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7
|
|||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 h1:37VE5TYj2m/FLA9SNr4z0+A0JefvTmR60Zwf8XSEV7c=
|
||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
|
@ -36,5 +38,7 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK
|
|||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.55.0 h1:E8yzL5unfpW3M6fz/eB7Cb5MQAYSZ7GKo4Qth+N2sgQ=
|
||||
gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
1
main.go
1
main.go
|
@ -15,6 +15,7 @@ import (
|
|||
leveldb "git.happydns.org/happydns/storage/leveldb"
|
||||
|
||||
_ "git.happydns.org/happydns/sources/ddns"
|
||||
_ "git.happydns.org/happydns/sources/ovh"
|
||||
)
|
||||
|
||||
type ResponseWriterPrefix struct {
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,175 @@
|
|||
package ovh // import "happydns.org/sources/ovh"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/ovh/go-ovh/ovh"
|
||||
|
||||
"git.happydns.org/happydns/model"
|
||||
"git.happydns.org/happydns/sources"
|
||||
)
|
||||
|
||||
type OVHAPI struct {
|
||||
Endpoint string `json:"endpoint,omitempty" happydns:"label=Endpoint,default=ovh-eu,choices=ovh-eu;ovh-us;ovh-ca;soyoustart-eu;soyoustart-ca;kimsufi-eu;kimsufi-ca,required"`
|
||||
AppKey string `json:"appkey,omitempty" happydns:"label=Application Key,placeholder=xxxxxxxxxx,required"`
|
||||
AppSecret string `json:"appsecret,omitempty" happydns:"label=Application Secret,placeholder=xxxxxxxxxx,required,secret"`
|
||||
ConsumerKey string `json:"consumerkey,omitempty" happydns:"label=Consumer Key,placeholder=xxxxxxxxxx,required"`
|
||||
}
|
||||
|
||||
func (s *OVHAPI) newClient() (*ovh.Client, error) {
|
||||
return ovh.NewClient(
|
||||
s.Endpoint,
|
||||
s.AppKey,
|
||||
s.AppSecret,
|
||||
s.ConsumerKey,
|
||||
)
|
||||
}
|
||||
|
||||
func (s *OVHAPI) Validate() error {
|
||||
client, err := s.newClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
me := struct {
|
||||
State string `json:"state"`
|
||||
}{}
|
||||
|
||||
err = client.Get("/me", &me)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if me.State != "complete" {
|
||||
return fmt.Errorf("API state returns is %q, expected \"complete\"", me.State)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OVHAPI) ImportZone(dn *happydns.Domain) (rrs []dns.RR, err error) {
|
||||
var client *ovh.Client
|
||||
client, err = s.newClient()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var zone string
|
||||
|
||||
err = client.Get(fmt.Sprintf("/domain/zone/%s/export", strings.TrimSuffix(dn.DomainName, ".")), &zone)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
zp := dns.NewZoneParser(strings.NewReader(zone), dn.DomainName, "")
|
||||
|
||||
for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
|
||||
rrs = append(rrs, rr)
|
||||
}
|
||||
|
||||
if err = zp.Err(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type OVHRecord struct {
|
||||
Id int64 `json:"id,omitempty"`
|
||||
FieldType string `json:"fieldType"`
|
||||
TTL uint32 `json:"ttl"`
|
||||
Target string `json:"target"`
|
||||
Zone string `json:"zone,omitempty"`
|
||||
SubDomain string `json:"subDomain"`
|
||||
}
|
||||
|
||||
func (s *OVHAPI) AddRR(dn *happydns.Domain, rr dns.RR) (err error) {
|
||||
var client *ovh.Client
|
||||
client, err = s.newClient()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sup := OVHRecord{
|
||||
SubDomain: ovhSubdomain(dn, rr),
|
||||
FieldType: dns.Type(rr.Header().Rrtype).String(),
|
||||
TTL: rr.Header().Ttl,
|
||||
Target: strings.TrimPrefix(rr.String(), rr.Header().String()),
|
||||
}
|
||||
|
||||
var res OVHRecord
|
||||
|
||||
err = client.Post(
|
||||
fmt.Sprintf("/domain/zone/%s/record", strings.TrimSuffix(dn.DomainName, ".")),
|
||||
sup, &res)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = client.Post(fmt.Sprintf("/domain/zone/%s/refresh", strings.TrimSuffix(dn.DomainName, ".")), nil, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ovhSubdomain(dn *happydns.Domain, rr dns.RR) string {
|
||||
return strings.TrimSuffix(strings.TrimSuffix(rr.Header().Name, dn.DomainName), ".")
|
||||
}
|
||||
|
||||
func (s *OVHAPI) DeleteRR(dn *happydns.Domain, rr dns.RR) (err error) {
|
||||
var client *ovh.Client
|
||||
client, err = s.newClient()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Get all matching IDs
|
||||
var ids []int64
|
||||
err = client.Get(
|
||||
fmt.Sprintf("/domain/zone/%s/record?fieldType=%s&subDomain=%s", strings.TrimSuffix(dn.DomainName, "."), dns.Type(rr.Header().Rrtype).String(), ovhSubdomain(dn, rr)),
|
||||
&ids)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Find the right ID
|
||||
for _, id := range ids {
|
||||
var rec OVHRecord
|
||||
|
||||
err = client.Get(
|
||||
fmt.Sprintf("/domain/zone/%s/record/%d", strings.TrimSuffix(dn.DomainName, "."), id),
|
||||
&rec)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if rec.Target == strings.TrimPrefix(rr.String(), rr.Header().String()) {
|
||||
err = client.Delete(fmt.Sprintf("/domain/zone/%s/record/%d", strings.TrimSuffix(dn.DomainName, "."), id), nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = client.Post(fmt.Sprintf("/domain/zone/%s/refresh", strings.TrimSuffix(dn.DomainName, ".")), nil, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func init() {
|
||||
sources.RegisterSource("git.happydns.org/happydns/sources/ovh/OVHAPI", func() happydns.Source {
|
||||
return &OVHAPI{}
|
||||
}, sources.SourceInfos{
|
||||
Name: "OVH",
|
||||
Description: "Hosting",
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue