Initial commit

This commit is contained in:
Jonathan Beliën 2025-05-18 22:36:43 +02:00
parent 7882326a8d
commit 27a155f7ec
No known key found for this signature in database
GPG key ID: 110F3BF6C41BF92F
4 changed files with 206 additions and 0 deletions

View file

@ -181,6 +181,11 @@
"TYPE": "HUAWEICLOUD",
"domain": "$HUAWEICLOUD_DOMAIN"
},
"INFOMANIAK": {
"TYPE": "INFOMANIAK",
"domain": "$INFOMANIAK_DOMAIN",
"token": "$INFOMANIAK_TOKEN"
},
"INWX": {
"TYPE": "INWX",
"domain": "$INWX_DOMAIN",

View file

@ -31,6 +31,7 @@ import (
_ "github.com/StackExchange/dnscontrol/v4/providers/hexonet"
_ "github.com/StackExchange/dnscontrol/v4/providers/hostingde"
_ "github.com/StackExchange/dnscontrol/v4/providers/huaweicloud"
_ "github.com/StackExchange/dnscontrol/v4/providers/infomaniak"
_ "github.com/StackExchange/dnscontrol/v4/providers/internetbs"
_ "github.com/StackExchange/dnscontrol/v4/providers/inwx"
_ "github.com/StackExchange/dnscontrol/v4/providers/linode"

143
providers/infomaniak/api.go Normal file
View file

@ -0,0 +1,143 @@
package infomaniak
import (
"encoding/json"
"fmt"
"net/http"
)
const baseURL = "https://api.infomaniak.com/2"
type dnssecRecord struct {
IsEnabled bool `json:"is_enabled"`
}
type dnsZoneResponse struct {
Result string `json:"result"`
Data dnsZone `json:"data"`
}
type dnsRecordResponse struct {
Result string `json:"result"`
Data []dnsRecord `json:"data"`
}
type boolResponse struct {
Result string `json:"result"`
Data bool `json:"data"`
}
type dnsZone struct {
ID int64 `json:"id,omitempty"`
FQDN string `json:"fqdn,omitempty"`
DNSSEC dnssecRecord `json:"dnssec,omitempty"`
Nameservers []string `json:"nameservers,omitempty"`
}
type dnsRecord struct {
ID string `json:"hostname,omitempty"`
Source string `json:"source,omitempty"`
Type string `json:"type,omitempty"`
TTL int64 `json:"ttl,omitempty"`
Target string `json:"target,omitempty"`
UpdatedAt int64 `json:"updated_at,omitempty"`
}
// See https://developer.infomaniak.com/docs/api/get/2/zones/%7Bzone%7D
func (p *infomaniakProvider) getDNSZone(zone string) (*dnsZone, error) {
reqURL := fmt.Sprintf("%s/zones/%s", baseURL, zone)
req, err := http.NewRequest(http.MethodGet, reqURL, nil)
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+p.apiToken)
req.Header.Add("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
response := &dnsZoneResponse{}
err = json.NewDecoder(res.Body).Decode(response)
if err != nil {
return nil, err
}
return &response.Data, nil
}
// See https://developer.infomaniak.com/docs/api/get/2/zones/%7Bzone%7D/records
func (p *infomaniakProvider) getDNSRecords(zone string) ([]dnsRecord, error) {
reqURL := fmt.Sprintf("%s/zones/%s/records", baseURL, zone)
req, err := http.NewRequest(http.MethodGet, reqURL, nil)
if err != nil {
return nil, err
}
req.Header.Add("Authorization", "Bearer "+p.apiToken)
req.Header.Add("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
response := &dnsRecordResponse{}
err = json.NewDecoder(res.Body).Decode(response)
if err != nil {
return nil, err
}
return response.Data, nil
}
func (p *infomaniakProvider) deleteDNSRecord(zone string, record string) error {
reqURL := fmt.Sprintf("%s/zones/%s/records/%s", baseURL, zone, record)
req, err := http.NewRequest(http.MethodDelete, reqURL, nil)
if err != nil {
return err
}
req.Header.Add("Authorization", "Bearer "+p.apiToken)
req.Header.Add("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
return nil
}
// func (p *infomaniakProvider) createDNSRecord(zoneID string, rec *dnsRecordCreate) (*dnsRecord, error) {
// reqURL := fmt.Sprintf("%s/dns_zones/%s/dns_records", baseURL, zoneID)
// data, err := json.Marshal(rec)
// if err != nil {
// return nil, err
// }
// req, err := http.NewRequest(http.MethodPost, reqURL, bytes.NewReader(data))
// if err != nil {
// return nil, err
// }
// req.Header.Add("Authorization", "Bearer "+n.apiToken)
// req.Header.Add("Content-Type", "application/json")
// res, err := http.DefaultClient.Do(req)
// if err != nil {
// return nil, err
// }
// defer res.Body.Close()
// record := &dnsRecord{}
// err = json.NewDecoder(res.Body).Decode(record)
// if err != nil {
// return nil, err
// }
// return record, nil
// }

View file

@ -0,0 +1,57 @@
package infomaniak
import (
"encoding/json"
"errors"
"github.com/StackExchange/dnscontrol/v4/models"
"github.com/StackExchange/dnscontrol/v4/providers"
)
// infomaniakProvider is the handle for operations.
type infomaniakProvider struct {
apiToken string // the account access token
}
var features = providers.DocumentationNotes{
// The default for unlisted capabilities is 'Cannot'.
// See providers/capabilities.go for the entire list of capabilities.
providers.CanGetZones: providers.Can(),
}
func newInfomaniak(m map[string]string, message json.RawMessage) (providers.DNSServiceProvider, error) {
api := &infomaniakProvider{}
api.apiToken = m["token"]
if api.apiToken == "" {
return nil, errors.New("missing Infomaniak personal access token")
}
return api, nil
}
func init() {
const providerName = "INFOMANIAK"
const providerMaintainer = "@jbelien"
fns := providers.DspFuncs{
Initializer: newInfomaniak,
}
providers.RegisterDomainServiceProviderType(providerName, fns, features)
providers.RegisterMaintainer(providerName, providerMaintainer)
}
func (p *infomaniakProvider) GetNameservers(domain string) ([]*models.Nameserver, error) {
zone, err := p.getDNSZone(domain)
if err != nil {
return nil, err
}
return models.ToNameservers(zone.Nameservers)
}
func (p *infomaniakProvider) GetZoneRecords(domain string, meta map[string]string) (models.Records, error) {
panic("GetZoneRecords not implemented")
}
func (p *infomaniakProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, int, error) {
panic("GetZoneRecordsCorrections not implemented")
}