mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-12-11 22:56:09 +08:00
wip!
This commit is contained in:
parent
633c9ecacc
commit
4b7da682a4
6 changed files with 197 additions and 108 deletions
|
|
@ -107,9 +107,13 @@ type RecordConfig struct {
|
|||
FieldsAsRaw []string // Fields as received from the dnsconfig.js file.
|
||||
FieldsAsUnicode []string // fields with IDN fields converted to Unicode.
|
||||
|
||||
// Legacy fields we hope to remove someday
|
||||
|
||||
SubDomain string `json:"subdomain,omitempty"`
|
||||
|
||||
// Cloudflare-specific fields:
|
||||
// When these are used, .target is set to a human-readable version (only to be used for display purposes).
|
||||
//CloudflareRedirect *CloudflareSingleRedirectConfig `json:"cloudflareapi_redirect,omitempty"`
|
||||
CloudflareRedirect *CloudflareSingleRedirectConfig `json:"cloudflareapi_redirect,omitempty"`
|
||||
|
||||
Metadata map[string]string `json:"meta,omitempty"` // Metadata added to record via dnsconfig.js
|
||||
FilePos string `json:"filepos"` // filename:line:char source
|
||||
|
|
@ -166,7 +170,14 @@ type RecordConfig struct {
|
|||
UnknownTypeName string `json:"unknown_type_name,omitempty"`
|
||||
}
|
||||
|
||||
// func NewRecordConfig(argsRaw):
|
||||
func NewRecordConfig(rtype string, ttl uint32, argsRaw []string) *RecordConfig {
|
||||
rc := &RecordConfig{
|
||||
Type: rtype,
|
||||
TTL: ttl,
|
||||
}
|
||||
return rc
|
||||
}
|
||||
|
||||
// .Type = type
|
||||
// .TTL = ttl
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ func (rc *RecordConfig) SetTargetCAA(flag uint8, tag string, target string) erro
|
|||
// Per: https://www.iana.org/assignments/pkix-parameters/pkix-parameters.xhtml#caa-properties excluding reserved tags
|
||||
allowedTags := []string{"issue", "issuewild", "iodef", "contactemail", "contactphone", "issuemail", "issuevmc"}
|
||||
if !slices.Contains(allowedTags, tag) {
|
||||
return fmt.Errorf("CAA tag (%v) is not one of the valid types.", tag)
|
||||
return fmt.Errorf("CAA tag (%v) is not one of the valid types", tag)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -2477,3 +2477,4 @@ function rawrecordBuilder(type) {
|
|||
|
||||
// CLOUDFLAREAPI:
|
||||
var CF_SINGLE_REDIRECT = rawrecordBuilder('CLOUDFLAREAPI_SINGLE_REDIRECT');
|
||||
var RP = rawrecordBuilder('RP');
|
||||
|
|
|
|||
|
|
@ -1,21 +1,43 @@
|
|||
package rtypecontrol
|
||||
|
||||
import "github.com/StackExchange/dnscontrol/v4/providers"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/providers"
|
||||
)
|
||||
|
||||
// backwards compatibility:
|
||||
var validTypes = map[string]struct{}{}
|
||||
|
||||
func Register(t string) {
|
||||
// Does this already exist?
|
||||
if _, ok := validTypes[t]; ok {
|
||||
panic("rtype %q already registered. Can't register it a second time!")
|
||||
type RType interface {
|
||||
// Returns the name of the rtype ("A", "MX", etc.)
|
||||
Name() string
|
||||
|
||||
// RecordConfig factory. Updates a RecordConfig's fields based on args.
|
||||
FromArgs(*models.RecordConfig, args []any) (*models.RecordConfig, error) //
|
||||
|
||||
// Returns a string representation of the record in RFC1038 format.
|
||||
// AsRFC1038String([]string) (string, error)
|
||||
}
|
||||
|
||||
validTypes[t] = struct{}{}
|
||||
// Map of registered rtypes.
|
||||
var Iface map[string]RType = map[string]RType{}
|
||||
|
||||
func Register(typeName string, t RType) {
|
||||
name := t.Name()
|
||||
if _, ok := Iface[name]; ok {
|
||||
panic(fmt.Sprintf("rtype %q already registered. Can't register it a second time!", name))
|
||||
}
|
||||
// Store the interface
|
||||
Iface[name] = t
|
||||
|
||||
// For compatibility with legacy systems:
|
||||
providers.RegisterCustomRecordType(name, "", "")
|
||||
|
||||
providers.RegisterCustomRecordType(t, "", "")
|
||||
}
|
||||
|
||||
func IsValid(t string) bool {
|
||||
_, ok := validTypes[t]
|
||||
func IsValid(name string) bool {
|
||||
_, ok := Iface[name]
|
||||
return ok
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
package rtypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/providers/cloudflare/rtypes/cfsingleredirect"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/rtypecontrol"
|
||||
)
|
||||
|
||||
func PostProcess(domains []*models.DomainConfig) error {
|
||||
|
|
@ -12,37 +10,54 @@ func PostProcess(domains []*models.DomainConfig) error {
|
|||
|
||||
for _, dc := range domains {
|
||||
for _, rawRec := range dc.RawRecords {
|
||||
|
||||
// Create as much of the RecordConfig as we can now. Allow New() to fill in the reset.
|
||||
rec := &models.RecordConfig{
|
||||
Type: rawRec.Type,
|
||||
TTL: rawRec.TTL,
|
||||
Name: rawRec.Args[0].(string),
|
||||
Metadata: map[string]string{},
|
||||
Metadata: stringifyMetas(rawRec.Metas),
|
||||
}
|
||||
//rec.Name, rec.NameRaw, rec.NameUnicode := normalizeName(rawRec.Args[0].(string), dc.Name, dc.SubDomain)
|
||||
//rec.NameFQDN, rec.NameFQDNRaw, rec.NameFQDNUnicode := normalizeNameFQDN(rawRec.Args[0].(string), dc.Name, dc.SubDomain)
|
||||
// Name:
|
||||
// * Convert to lowercase.
|
||||
// * Convert to IDN and UNI.
|
||||
//
|
||||
// IDN: name + subdomain + domain
|
||||
|
||||
// Copy the metadata (convert everything to string)
|
||||
for _, m := range rawRec.Metas {
|
||||
for mk, mv := range m {
|
||||
if v, ok := mv.(string); ok {
|
||||
rec.Metadata[mk] = v // Already a string. No new malloc.
|
||||
} else {
|
||||
rec.Metadata[mk] = fmt.Sprintf("%v", mv)
|
||||
}
|
||||
}
|
||||
}
|
||||
rtypecontrol.Iface[rawRec.Type].FromArgs(rec, rawRec.Args)
|
||||
|
||||
// Call the proper initialize function.
|
||||
// TODO(tlim): Good candidate for an interface or a lookup table.
|
||||
switch rawRec.Type {
|
||||
case "CLOUDFLAREAPI_SINGLE_REDIRECT":
|
||||
err = cfsingleredirect.FromRaw(rec, rawRec.Args)
|
||||
rec.SetLabel("@", dc.Name)
|
||||
// rec := &models.RecordConfig{
|
||||
// Type: rawRec.Type,
|
||||
// TTL: rawRec.TTL,
|
||||
// Name: rawRec.Args[0].(string),
|
||||
// Metadata: map[string]string{},
|
||||
// }
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("unknown rawrec type=%q", rawRec.Type)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s (%q, %q) record error: %w", rawRec.Type, rec.Name, dc.Name, err)
|
||||
}
|
||||
// // Copy the metadata (convert everything to string)
|
||||
// for _, m := range rawRec.Metas {
|
||||
// for mk, mv := range m {
|
||||
// if v, ok := mv.(string); ok {
|
||||
// rec.Metadata[mk] = v // Already a string. No new malloc.
|
||||
// } else {
|
||||
// rec.Metadata[mk] = fmt.Sprintf("%v", mv)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Call the proper initialize function.
|
||||
// // TODO(tlim): Good candidate for an interface or a lookup table.
|
||||
// switch rawRec.Type {
|
||||
// case "CLOUDFLAREAPI_SINGLE_REDIRECT":
|
||||
// err = cfsingleredirect.FromRaw(rec, rawRec.Args)
|
||||
// rec.SetLabel("@", dc.Name)
|
||||
|
||||
// default:
|
||||
// err = fmt.Errorf("unknown rawrec type=%q", rawRec.Type)
|
||||
// }
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("%s (%q, %q) record error: %w", rawRec.Type, rec.Name, dc.Name, err)
|
||||
// }
|
||||
|
||||
// Free memeory:
|
||||
clear(rawRec.Args)
|
||||
|
|
|
|||
|
|
@ -1,37 +1,77 @@
|
|||
package cfsingleredirect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/rtypecontrol"
|
||||
)
|
||||
|
||||
// SINGLEREDIRECT is the string name for this rType.
|
||||
const SINGLEREDIRECT = "CLOUDFLAREAPI_SINGLE_REDIRECT"
|
||||
// "github.com/StackExchange/dnscontrol/v4/models"
|
||||
// "github.com/StackExchange/dnscontrol/v4/pkg/rtypecontrol"
|
||||
|
||||
func init() {
|
||||
rtypecontrol.Register(SINGLEREDIRECT)
|
||||
rtypecontrol.Register(SingleRedirect{})
|
||||
}
|
||||
|
||||
// FromRaw convert RecordConfig using data from a RawRecordConfig's parameters.
|
||||
func FromRaw(rc *models.RecordConfig, items []any) error {
|
||||
// Validate types.
|
||||
if err := rtypecontrol.PaveArgs(items, "siss"); err != nil {
|
||||
return err
|
||||
type SingleRedirect struct{}
|
||||
|
||||
func (handle *SingleRedirect) Name() string {
|
||||
return "CLOUDFLAREAPI_SINGLE_REDIRECT"
|
||||
}
|
||||
|
||||
// Unpack the args:
|
||||
var name, when, then string
|
||||
var code uint16
|
||||
// func MakeSingleRedirect() SingleRedirect { return SingleRedirect{} }
|
||||
func (handle *SingleRedirect) FromArgs([]any) (*models.RecordConfig, error) {
|
||||
rec := &models.RecordConfig{
|
||||
Type: handle.Name(),
|
||||
TTL: ttl,
|
||||
|
||||
name = items[0].(string)
|
||||
code = items[1].(uint16)
|
||||
if code != 301 && code != 302 && code != 303 && code != 307 && code != 308 {
|
||||
return fmt.Errorf("%s: code (%03d) is not 301,302,303,307,308", rc.FilePos, code)
|
||||
//FilePos = FixFilePos(handle.FilePos)
|
||||
}
|
||||
when = items[2].(string)
|
||||
then = items[3].(string)
|
||||
return rec, nil
|
||||
}
|
||||
// // Validate types.
|
||||
// if err := rtypecontrol.PaveArgs(items, "siss"); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
return makeSingleRedirectFromRawRec(rc, code, name, when, then)
|
||||
// // Unpack the args:
|
||||
// var name, when, then string
|
||||
// var code uint16
|
||||
|
||||
// name = items[0].(string)
|
||||
// code = items[1].(uint16)
|
||||
// if code != 301 && code != 302 && code != 303 && code != 307 && code != 308 {
|
||||
// return fmt.Errorf("%s: code (%03d) is not 301,302,303,307,308", rc.FilePos, code)
|
||||
// }
|
||||
// when = items[2].(string)
|
||||
// then = items[3].(string)
|
||||
|
||||
// return makeSingleRedirectFromRawRec(rc, code, name, when, then)
|
||||
return &models.RecordConfig{}, nil
|
||||
}
|
||||
|
||||
//func (handle *SingleRedirect) IDNFields(argsRaw) (argsIDN, argsUnicode, error) {}
|
||||
//func (handle *SingleRedirect) AsRFC1038String(*models.RecordConfig) string {}
|
||||
//func (handle *SingleRedirect) CopyToLegacyFields(*models.RecordConfig) {}
|
||||
//func (handle *SingleRedirect) CopyFromLegacyFields(*models.RecordConfig) {}
|
||||
|
||||
// // FromRaw convert RecordConfig using data from a RawRecordConfig's parameters.
|
||||
// func FromRaw(rc *models.RecordConfig, items []any) error {
|
||||
// // Validate types.
|
||||
// if err := rtypecontrol.PaveArgs(items, "siss"); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// // Unpack the args:
|
||||
// var name, when, then string
|
||||
// var code uint16
|
||||
|
||||
// name = items[0].(string)
|
||||
// code = items[1].(uint16)
|
||||
// if code != 301 && code != 302 && code != 303 && code != 307 && code != 308 {
|
||||
// return fmt.Errorf("%s: code (%03d) is not 301,302,303,307,308", rc.FilePos, code)
|
||||
// }
|
||||
// when = items[2].(string)
|
||||
// then = items[3].(string)
|
||||
|
||||
// return makeSingleRedirectFromRawRec(rc, code, name, when, then)
|
||||
// }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue