mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-12-09 13:46:07 +08:00
cf redirects work, but wrong order
This commit is contained in:
parent
76791cefc7
commit
98f4075bd7
11 changed files with 203 additions and 111 deletions
|
|
@ -225,3 +225,12 @@ func (dc *DomainConfig) GetPopulateCorrections(providerName string) []*Correctio
|
|||
defer dc.pendingCorrectionsMutex.Unlock()
|
||||
return dc.pendingPopulateCorrections[providerName]
|
||||
}
|
||||
|
||||
func MakeFakeDomainConfig(domain string) *DomainConfig {
|
||||
v := domaintags.MakeDomainNameVarieties(domain)
|
||||
return &DomainConfig{
|
||||
Name: v.NameIDN,
|
||||
NameRaw: v.NameRaw,
|
||||
NameUnicode: v.NameUnicode,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -527,6 +527,15 @@ func (rc *RecordConfig) GetSVCBValue() []dns.SVCBKeyValue {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (rc *RecordConfig) IsModernType() bool {
|
||||
//fmt.Printf("DEBUG: IsModernType rtype=%s\n", rc.Type)
|
||||
if rc.Type == "CLOUDFLAREAPI_SINGLE_REDIRECT" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Records is a list of *RecordConfig.
|
||||
type Records []*RecordConfig
|
||||
|
||||
|
|
@ -593,6 +602,10 @@ func PostProcessRecords(recs []*RecordConfig) {
|
|||
// Downcase converts all labels and targets to lowercase in a list of RecordConfig.
|
||||
func Downcase(recs []*RecordConfig) {
|
||||
for _, r := range recs {
|
||||
if r.IsModernType() {
|
||||
continue
|
||||
}
|
||||
|
||||
r.Name = strings.ToLower(r.Name)
|
||||
r.NameFQDN = strings.ToLower(r.NameFQDN)
|
||||
switch r.Type { // #rtype_variations
|
||||
|
|
@ -620,6 +633,11 @@ func CanonicalizeTargets(recs []*RecordConfig, origin string) {
|
|||
originFQDN := origin + "."
|
||||
|
||||
for _, r := range recs {
|
||||
|
||||
if r.IsModernType() {
|
||||
continue
|
||||
}
|
||||
|
||||
switch r.Type { // #rtype_variations
|
||||
case "ALIAS", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "PTR", "SRV":
|
||||
// Target is a hostname that might be a shortname. Turn it into a FQDN.
|
||||
|
|
|
|||
|
|
@ -245,7 +245,9 @@ func humanDiff(a, b targetConfig) string {
|
|||
}
|
||||
|
||||
// Just the TTLs are different:
|
||||
return fmt.Sprintf("%s ttl=(%d->%d)", a.comparableNoTTL, a.rec.TTL, b.rec.TTL)
|
||||
return fmt.Sprintf("ttl=(%d->%d) %s",
|
||||
a.rec.TTL, b.rec.TTL,
|
||||
a.comparableNoTTL)
|
||||
}
|
||||
|
||||
var echRe = regexp.MustCompile(`ech="?([\w+/=]+)"?`)
|
||||
|
|
|
|||
|
|
@ -14,20 +14,11 @@ func ImportRawRecords(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,
|
||||
Metadata: stringifyMetas(rawRec.Metas),
|
||||
//FilePos: models.FixPosition(rawRec.FilePos),
|
||||
}
|
||||
|
||||
setRecordNames(rec, dc, rawRec.Args[0].(string))
|
||||
|
||||
// Fill in the .F/.Fields* fields.
|
||||
err := Func[rawRec.Type].FromArgs(rec, rawRec.Args)
|
||||
rec, err := NewRecordConfigFromRaw(rawRec.Type, rawRec.Args, dc)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%s: %w", nil, err)
|
||||
// TODO(tlim): Fix FilePos
|
||||
//return fmt.Errorf("%s: %w", rawRec.FilePos, err)
|
||||
}
|
||||
|
||||
// Free memeory:
|
||||
|
|
@ -42,6 +33,35 @@ func ImportRawRecords(domains []*models.DomainConfig) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func NewRecordConfigFromRaw(t string, args []any, dc *models.DomainConfig) (*models.RecordConfig, error) {
|
||||
fmt.Printf("DEBUG: NewRecordConfigFromRaw t=%q args=%+v\n", t, args)
|
||||
if _, ok := Func[t]; !ok {
|
||||
return nil, fmt.Errorf("record type %q is not supported", t)
|
||||
}
|
||||
|
||||
// Create as much of the RecordConfig as we can now. Allow New() to fill in the reset.
|
||||
rec := &models.RecordConfig{
|
||||
Type: t,
|
||||
Name: args[0].(string), // May be fixed later.
|
||||
Metadata: map[string]string{},
|
||||
//FilePos: models.FixPosition(filePos),
|
||||
}
|
||||
|
||||
setRecordNames(rec, dc, args[0].(string))
|
||||
|
||||
if rec.Type == "" {
|
||||
panic("rtypecontrol: NewRecordConfigFromRaw: empty record type")
|
||||
}
|
||||
|
||||
// Fill in the .F/.Fields* fields.
|
||||
err := Func[t].FromArgs(dc, rec, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rec, nil
|
||||
}
|
||||
|
||||
func stringifyMetas(metas []map[string]any) map[string]string {
|
||||
result := make(map[string]string)
|
||||
for _, m := range metas {
|
||||
|
|
@ -60,13 +80,14 @@ func setRecordNames(rec *models.RecordConfig, dc *models.DomainConfig, n string)
|
|||
|
||||
if rec.SubDomain == "" {
|
||||
// Not _EXTEND() mode:
|
||||
if rec.Name == "@" {
|
||||
rec.NameRaw = rec.Name
|
||||
rec.Name = rec.Name
|
||||
if n == "@" {
|
||||
rec.Name = "@"
|
||||
rec.NameRaw = "@"
|
||||
rec.NameUnicode = "@"
|
||||
} else {
|
||||
rec.Name = domaintags.EfficientToASCII(n)
|
||||
rec.NameRaw = n
|
||||
rec.Name = domaintags.EfficientToUnicode(n)
|
||||
rec.NameUnicode = domaintags.EfficientToUnicode(n)
|
||||
}
|
||||
rec.NameFQDN = dnsutil.AddOrigin(rec.Name, dc.Name)
|
||||
rec.NameFQDNRaw = dnsutil.AddOrigin(rec.NameRaw, dc.NameRaw)
|
||||
|
|
@ -74,13 +95,17 @@ func setRecordNames(rec *models.RecordConfig, dc *models.DomainConfig, n string)
|
|||
} else {
|
||||
// _EXTEND() mode:
|
||||
// FIXME(tlim): Not implemented.
|
||||
if rec.Name == "@" {
|
||||
rec.NameRaw = rec.Name
|
||||
rec.Name = rec.Name
|
||||
sdRaw := rec.SubDomain
|
||||
sdIDN := domaintags.EfficientToASCII(rec.SubDomain)
|
||||
sdUnicode := domaintags.EfficientToUnicode(rec.SubDomain)
|
||||
if n == "@" {
|
||||
rec.Name = sdIDN
|
||||
rec.NameRaw = sdRaw
|
||||
rec.NameUnicode = sdUnicode
|
||||
} else {
|
||||
rec.Name = domaintags.EfficientToASCII(n)
|
||||
rec.NameRaw = n
|
||||
rec.Name = domaintags.EfficientToUnicode(n)
|
||||
rec.Name = domaintags.EfficientToASCII(n + "." + sdIDN)
|
||||
rec.NameRaw = n + "." + sdRaw
|
||||
rec.NameUnicode = domaintags.EfficientToUnicode(n + "." + sdUnicode)
|
||||
}
|
||||
rec.NameFQDN = dnsutil.AddOrigin(rec.Name, dc.Name)
|
||||
rec.NameFQDNRaw = dnsutil.AddOrigin(rec.NameRaw, dc.NameRaw)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ type RType interface {
|
|||
Name() string
|
||||
|
||||
// RecordConfig factory. Updates a RecordConfig's fields based on args.
|
||||
FromArgs(*models.RecordConfig, []any) error
|
||||
FromArgs(*models.DomainConfig, *models.RecordConfig, []any) error
|
||||
|
||||
// Returns a string representation of the record in RFC1038 format.
|
||||
// AsRFC1038String([]string) (string, error)
|
||||
|
|
|
|||
|
|
@ -137,13 +137,15 @@ func (c *cloudflareProvider) GetZoneRecords(domain string, meta map[string]strin
|
|||
}
|
||||
}
|
||||
|
||||
// if c.manageRedirects { // if old
|
||||
// prs, err := c.getPageRules(domainID, domain)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// records = append(records, prs...)
|
||||
// }
|
||||
if c.manageRedirects { // if old-style "page rules" are still being managed.
|
||||
fmt.Printf("DEBUG: Getting old-style page rules for %s???\n", domain)
|
||||
panic("stop")
|
||||
// prs, err := c.getPageRules(domainID, domain)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// records = append(records, prs...)
|
||||
}
|
||||
|
||||
if c.manageSingleRedirects { // if new xor old
|
||||
// Download the list of Single Redirects.
|
||||
|
|
@ -356,14 +358,19 @@ func (c *cloudflareProvider) mkChangeCorrection(oldrec, newrec *models.RecordCon
|
|||
func (c *cloudflareProvider) mkDeleteCorrection(recType string, origRec *models.RecordConfig, domainID string, msg string) []*models.Correction {
|
||||
var idTxt string
|
||||
switch recType {
|
||||
// case "PAGE_RULE":
|
||||
// idTxt = origRec.Original.(cloudflare.PageRule).ID
|
||||
case "PAGE_RULE":
|
||||
idTxt = origRec.Original.(cloudflare.PageRule).ID
|
||||
case "WORKER_ROUTE":
|
||||
idTxt = origRec.Original.(cloudflare.WorkerRoute).ID
|
||||
case "CLOUDFLAREAPI_SINGLE_REDIRECT":
|
||||
idTxt = origRec.Original.(cloudflare.RulesetRule).ID
|
||||
case "":
|
||||
fmt.Printf("DEBUG: %q origRec.Original type is %T\nrec=%+v\n\n", recType, origRec.Original, *origRec)
|
||||
idTxt = origRec.Original.(cloudflare.RulesetRule).ID
|
||||
default:
|
||||
idTxt = origRec.Original.(cloudflare.DNSRecord).ID
|
||||
//fmt.Printf("DEBUG: %q rec=%+v origRec.Original type is %T\n", recType, *origRec, origRec.Original)
|
||||
fmt.Printf("DEBUG: %q origRec.Original type is %T\n", recType, origRec.Original)
|
||||
//idTxt = origRec.Original.(cloudflare.DNSRecord).ID
|
||||
}
|
||||
msg = msg + color.RedString(" id=%v", idTxt)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"golang.org/x/net/idna"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/rtypecontrol"
|
||||
"github.com/StackExchange/dnscontrol/v4/providers/cloudflare/rtypes/cfsingleredirect"
|
||||
)
|
||||
|
||||
|
|
@ -289,9 +290,6 @@ func (c *cloudflareProvider) getSingleRedirects(id string, domain string) ([]*mo
|
|||
recs := []*models.RecordConfig{}
|
||||
for _, pr := range rules.Rules {
|
||||
thisPr := pr
|
||||
r := &models.RecordConfig{
|
||||
Original: thisPr,
|
||||
}
|
||||
|
||||
// Extract the valuables from the rule, use it to make the sr:
|
||||
srName := pr.Description
|
||||
|
|
@ -299,17 +297,25 @@ func (c *cloudflareProvider) getSingleRedirects(id string, domain string) ([]*mo
|
|||
srThen := pr.ActionParameters.FromValue.TargetURL.Expression
|
||||
code := uint16(pr.ActionParameters.FromValue.StatusCode)
|
||||
|
||||
if err := cfsingleredirect.MakeSingleRedirectFromAPI(r, code, srName, srWhen, srThen); err != nil {
|
||||
// if err := cfsingleredirect.MakeSingleRedirectFromAPI(r, code, srName, srWhen, srThen); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// r.SetLabel("@", domain)
|
||||
rec, err := rtypecontrol.NewRecordConfigFromRaw(
|
||||
"CLOUDFLAREAPI_SINGLE_REDIRECT",
|
||||
[]any{srName, code, srWhen, srThen},
|
||||
models.MakeFakeDomainConfig(domain))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.SetLabel("@", domain)
|
||||
rec.Original = thisPr
|
||||
|
||||
// Store the IDs
|
||||
sr := r.F.(*cfsingleredirect.SingleRedirectConfig)
|
||||
sr := rec.F.(*cfsingleredirect.SingleRedirectConfig)
|
||||
sr.SRRRulesetID = rules.ID
|
||||
sr.SRRRulesetRuleID = pr.ID
|
||||
|
||||
recs = append(recs, r)
|
||||
recs = append(recs, rec)
|
||||
}
|
||||
|
||||
return recs, nil
|
||||
|
|
|
|||
77
providers/cloudflare/rtypes/cfsingleredirect/cfredirect.go
Normal file
77
providers/cloudflare/rtypes/cfsingleredirect/cfredirect.go
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
package cfsingleredirect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/rtypecontrol"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rtypecontrol.Register(&CfRedirect{})
|
||||
rtypecontrol.Register(&CfTempRedirect{})
|
||||
}
|
||||
|
||||
type CfRedirect struct{}
|
||||
|
||||
// Name returns the text (all caps) name of the rtype.
|
||||
func (handle *CfRedirect) Name() string {
|
||||
return "CF_REDIRECT"
|
||||
}
|
||||
|
||||
func (handle *CfRedirect) FromArgs(dc *models.DomainConfig, rec *models.RecordConfig, args []any) error {
|
||||
fmt.Printf("DEBUG: CF_REDIRECT FromArgs called with args=%+v\n", args)
|
||||
return FromArgs_helper(dc, rec, args, 301)
|
||||
}
|
||||
|
||||
type CfTempRedirect struct{}
|
||||
|
||||
// Name returns the text (all caps) name of the rtype.
|
||||
func (handle *CfTempRedirect) Name() string {
|
||||
return "CF_TEMP_REDIRECT"
|
||||
}
|
||||
|
||||
var services = map[string]int{}
|
||||
var serviceMutex = sync.RWMutex{}
|
||||
|
||||
func inc(name string) {
|
||||
serviceMutex.Lock()
|
||||
defer serviceMutex.Unlock()
|
||||
|
||||
services[name]++
|
||||
}
|
||||
|
||||
func get(name string) int {
|
||||
serviceMutex.Lock()
|
||||
defer serviceMutex.Unlock()
|
||||
return services[name]
|
||||
}
|
||||
|
||||
func (handle *CfTempRedirect) FromArgs(dc *models.DomainConfig, rec *models.RecordConfig, args []any) error {
|
||||
fmt.Printf("DEBUG: CF_TEMP_REDIRECT FromArgs called with args=%+v\n", args)
|
||||
return FromArgs_helper(dc, rec, args, 302)
|
||||
}
|
||||
|
||||
func FromArgs_helper(dc *models.DomainConfig, rec *models.RecordConfig, args []any, code int) error {
|
||||
|
||||
// Pave the args to be the expected types.
|
||||
if err := rtypecontrol.PaveArgs(args, "ss"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert old-style patterns to new-style rules:
|
||||
prWhen := args[0].(string)
|
||||
prThen := args[1].(string)
|
||||
srWhen, srThen, err := makeRuleFromPattern(prWhen, prThen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
inc(dc.UniqueName)
|
||||
name := fmt.Sprintf("%03d,%03d,%s,%s", get(dc.UniqueName), code, prWhen, prThen)
|
||||
|
||||
sr := SingleRedirectConfig{}
|
||||
rec.Type = sr.Name() // This record is now a CLOUDFLAREAPI_SINGLE_REDIRECT
|
||||
return sr.FromArgs(dc, rec, []any{name, code, srWhen, srThen})
|
||||
}
|
||||
|
|
@ -35,7 +35,8 @@ func (handle *SingleRedirectConfig) Name() string {
|
|||
return "CLOUDFLAREAPI_SINGLE_REDIRECT"
|
||||
}
|
||||
|
||||
func (handle *SingleRedirectConfig) FromArgs(rec *models.RecordConfig, args []any) error {
|
||||
func (handle *SingleRedirectConfig) FromArgs(dc *models.DomainConfig, rec *models.RecordConfig, args []any) error {
|
||||
fmt.Printf("DEBUG: CLOUDFLAREAPI_SINGLE_REDIRECT FromArgs called with args=%+v\n", args)
|
||||
// Pave the args to be the expected types.
|
||||
if err := rtypecontrol.PaveArgs(args, "siss"); err != nil {
|
||||
return err
|
||||
|
|
@ -52,7 +53,9 @@ func (handle *SingleRedirectConfig) FromArgs(rec *models.RecordConfig, args []an
|
|||
}
|
||||
when = args[2].(string)
|
||||
then = args[3].(string)
|
||||
//fmt.Printf("\n\nDEBUG: targetFromRaw(name=%q code=%03d when=%q then=%q)\n", name, code, when, then)
|
||||
display := targetFromRaw(name, code, when, then)
|
||||
//fmt.Printf("DEBUG: targetFromRaw(name=%q code=%03d when=%q then=%q) display=%q\n\n\n", name, code, when, then, display)
|
||||
|
||||
rec.F = &SingleRedirectConfig{
|
||||
Code: code,
|
||||
|
|
@ -68,15 +71,24 @@ func (handle *SingleRedirectConfig) FromArgs(rec *models.RecordConfig, args []an
|
|||
SRDisplay: display,
|
||||
}
|
||||
|
||||
//rec.Name = name
|
||||
rec.Name = "@"
|
||||
rec.NameRaw = "@"
|
||||
rec.NameUnicode = "@"
|
||||
rec.NameFQDN = dc.Name
|
||||
rec.NameFQDNRaw = dc.NameRaw
|
||||
rec.NameFQDNUnicode = dc.NameUnicode
|
||||
rec.TTL = 1
|
||||
rec.Comparable = display
|
||||
rec.ZonefilePartial = display
|
||||
|
||||
_ = rec.SetTarget(display)
|
||||
return nil
|
||||
}
|
||||
|
||||
// targetFromRaw create the display text used for a normal Redirect.
|
||||
func targetFromRaw(name string, code uint16, when, then string) string {
|
||||
return fmt.Sprintf("%s code=(%03d) when=(%s) then=(%s)",
|
||||
return fmt.Sprintf("name=(%s) code=(%03d) when=(%s) then=(%s)",
|
||||
name,
|
||||
code,
|
||||
when,
|
||||
|
|
|
|||
|
|
@ -5,67 +5,8 @@ import (
|
|||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/rtypecontrol"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rtypecontrol.Register(&CfRedirect{})
|
||||
}
|
||||
|
||||
type CfRedirect struct{}
|
||||
|
||||
// Name returns the text (all caps) name of the rtype.
|
||||
func (handle *CfRedirect) Name() string {
|
||||
return "CF_REDIRECT"
|
||||
}
|
||||
|
||||
func (handle *CfRedirect) FromArgs(rec *models.RecordConfig, args []any) error {
|
||||
// Pave the args to be the expected types.
|
||||
if err := rtypecontrol.PaveArgs(args, "ss"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert old-style patterns to new-style rules:
|
||||
prWhen := args[0].(string)
|
||||
prThen := args[1].(string)
|
||||
srWhen, srThen, err := makeRuleFromPattern(prWhen, prThen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sr := SingleRedirectConfig{}
|
||||
rec.Type = sr.Name() // This record is now a CLOUDFLAREAPI_SINGLE_REDIRECT
|
||||
return sr.FromArgs(rec, []any{"@", 301, srWhen, srThen})
|
||||
}
|
||||
|
||||
type CfTempRedirect struct{}
|
||||
|
||||
// Name returns the text (all caps) name of the rtype.
|
||||
func (handle *CfTempRedirect) Name() string {
|
||||
return "CF_TEMP_REDIRECT"
|
||||
}
|
||||
|
||||
func (handle *CfTempRedirect) FromArgs(rec *models.RecordConfig, args []any) error {
|
||||
// Pave the args to be the expected types.
|
||||
if err := rtypecontrol.PaveArgs(args, "ss"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert old-style patterns to new-style rules:
|
||||
prWhen := args[0].(string)
|
||||
prThen := args[1].(string)
|
||||
srWhen, srThen, err := makeRuleFromPattern(prWhen, prThen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sr := SingleRedirectConfig{}
|
||||
rec.Type = sr.Name() // This record is now a CLOUDFLAREAPI_SINGLE_REDIRECT
|
||||
return sr.FromArgs(rec, []any{"@", 301, srWhen, srThen})
|
||||
}
|
||||
|
||||
// // TranscodePRtoSR takes a PAGE_RULE record, stores transcoded versions of the fields, and makes the record a CLOUDFLAREAPI_SINGLE_REDDIRECT.
|
||||
// func TranscodePRtoSR(rec *models.RecordConfig) error {
|
||||
// //rec.Type = SINGLEREDIRECT // This record is now a CLOUDFLAREAPI_SINGLE_REDIRECT
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
package cfsingleredirect
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/rtypecontrol"
|
||||
)
|
||||
|
||||
// // MakePageRule updates a RecordConfig to be a PAGE_RULE using PAGE_RULE data.
|
||||
// func MakePageRule(rc *models.RecordConfig, priority int, code uint16, when, then string) error {
|
||||
// if rc == nil {
|
||||
|
|
@ -34,9 +29,9 @@ import (
|
|||
// return fmt.Sprintf("%03d,%03d,%s,%s", priority, code, when, then)
|
||||
// }
|
||||
|
||||
func MakeSingleRedirectFromAPI(rc *models.RecordConfig, code uint16, name, when, then string) error {
|
||||
return rtypecontrol.Func["SINGLEREDIRECT"].FromArgs(rc, []any{name, code, when, then})
|
||||
}
|
||||
// func MakeSingleRedirectFromAPI(rc *models.RecordConfig, code uint16, name, when, then string) error {
|
||||
// return rtypecontrol.Func["CLOUDFLAREAPI_SINGLE_REDIRECT"].FromArgs(rc, []any{name, code, when, then})
|
||||
// }
|
||||
|
||||
// // MakeSingleRedirectFromAPI updatese a RecordConfig to be a SINGLEREDIRECT using data downloaded via the API.
|
||||
// func MakeSingleRedirectFromAPI(rc *models.RecordConfig, code uint16, name, when, then string) error {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue