mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
NEW PROVIDER: Oracle Cloud (#1021)
* feat: add Oracle provider * fix ALIAS and NS tests * return... else if -> return... if * fix assignment * remove extraneous blank lines Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
This commit is contained in:
1
OWNERS
1
OWNERS
@@ -21,6 +21,7 @@ providers/namecheap @captncraig
|
|||||||
# providers/namedotcom
|
# providers/namedotcom
|
||||||
providers/netcup @kordianbruck
|
providers/netcup @kordianbruck
|
||||||
providers/ns1 @captncraig
|
providers/ns1 @captncraig
|
||||||
|
providers/oracle @kallsyms
|
||||||
# providers/route53
|
# providers/route53
|
||||||
# providers/softlayer
|
# providers/softlayer
|
||||||
providers/vultr @pgaskin
|
providers/vultr @pgaskin
|
||||||
|
@@ -42,6 +42,7 @@ Currently supported DNS providers:
|
|||||||
- OVH
|
- OVH
|
||||||
- OctoDNS
|
- OctoDNS
|
||||||
- OpenSRS
|
- OpenSRS
|
||||||
|
- Oracle Cloud
|
||||||
- PowerDNS
|
- PowerDNS
|
||||||
- SoftLayer
|
- SoftLayer
|
||||||
- Vultr
|
- Vultr
|
||||||
|
43
docs/_providers/oracle.md
Normal file
43
docs/_providers/oracle.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
---
|
||||||
|
name: Oracle Cloud
|
||||||
|
title: Oracle Cloud Provider
|
||||||
|
layout: default
|
||||||
|
jsId: ORACLE
|
||||||
|
---
|
||||||
|
# Oracle Cloud Provider
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Create an API key through the Oracle Cloud portal, and provide the user OCID, tenancy OCID, key fingerprint, region, and the contents of the private key.
|
||||||
|
The OCID of the compartment DNS resources should be put in can also optionally be provided.
|
||||||
|
|
||||||
|
{% highlight json %}
|
||||||
|
{
|
||||||
|
"oracle": {
|
||||||
|
"user_ocid": "$ORACLE_USER_OCID",
|
||||||
|
"tenancy_ocid": "$ORACLE_TENANCY_OCID",
|
||||||
|
"fingerprint": "$ORACLE_FINGERPRINT",
|
||||||
|
"region": "$ORACLE_REGION",
|
||||||
|
"private_key": "$ORACLE_PRIVATE_KEY",
|
||||||
|
"compartment": "$ORACLE_COMPARTMENT"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
This provider does not recognize any special metadata fields unique to Oracle Cloud.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
Example Javascript:
|
||||||
|
|
||||||
|
{% highlight js %}
|
||||||
|
var REG_NONE = NewRegistrar('none', 'NONE')
|
||||||
|
var ORACLE = NewDnsProvider("oracle", "ORACLE");
|
||||||
|
|
||||||
|
D("example.tld", REG_NONE, DnsProvider(ORACLE),
|
||||||
|
NAMESERVER_TTL(86400),
|
||||||
|
|
||||||
|
A("test","1.2.3.4")
|
||||||
|
);
|
||||||
|
{% endhighlight %}
|
||||||
|
|
@@ -91,6 +91,7 @@ Maintainers of contributed providers:
|
|||||||
* `NS1` @captncraig
|
* `NS1` @captncraig
|
||||||
* `OCTODNS` @TomOnTime
|
* `OCTODNS` @TomOnTime
|
||||||
* `OPENSRS` @pierre-emmanuelJ
|
* `OPENSRS` @pierre-emmanuelJ
|
||||||
|
* `ORACLE` @kallsyms
|
||||||
* `OVH` @masterzen
|
* `OVH` @masterzen
|
||||||
* `POWERDNS` @jpbede
|
* `POWERDNS` @jpbede
|
||||||
* `SOFTLAYER`@jamielennox
|
* `SOFTLAYER`@jamielennox
|
||||||
|
1
go.mod
1
go.mod
@@ -47,6 +47,7 @@ require (
|
|||||||
github.com/mjibson/esc v0.2.0
|
github.com/mjibson/esc v0.2.0
|
||||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
||||||
github.com/nrdcg/goinwx v0.8.1
|
github.com/nrdcg/goinwx v0.8.1
|
||||||
|
github.com/oracle/oci-go-sdk/v32 v32.0.0
|
||||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
||||||
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d
|
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d
|
||||||
github.com/pierrec/lz4 v2.6.0+incompatible // indirect
|
github.com/pierrec/lz4 v2.6.0+incompatible // indirect
|
||||||
|
4
go.sum
4
go.sum
@@ -369,6 +369,10 @@ github.com/nrdcg/goinwx v0.8.1 h1:20EQ/JaGFnSKwiDH2JzjIpicffl3cPk6imJBDqVBVtU=
|
|||||||
github.com/nrdcg/goinwx v0.8.1/go.mod h1:tILVc10gieBp/5PMvbcYeXM6pVQ+c9jxDZnpaR1UW7c=
|
github.com/nrdcg/goinwx v0.8.1/go.mod h1:tILVc10gieBp/5PMvbcYeXM6pVQ+c9jxDZnpaR1UW7c=
|
||||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
|
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
|
||||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||||
|
github.com/oracle/oci-go-sdk v1.8.0 h1:4SO45bKV0I3/Mn1os3ANDZmV0eSE5z5CLdSUIkxtyzs=
|
||||||
|
github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=
|
||||||
|
github.com/oracle/oci-go-sdk/v32 v32.0.0 h1:SSbzrQO3WRcPJEZ8+b3SFPYsPtkFM96clqrp03lrwbU=
|
||||||
|
github.com/oracle/oci-go-sdk/v32 v32.0.0/go.mod h1:aZc4jC59IuNP3cr5y1nj555QvwojMX2nMJaBiozuuEs=
|
||||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 h1:37VE5TYj2m/FLA9SNr4z0+A0JefvTmR60Zwf8XSEV7c=
|
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/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ=
|
||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
|
@@ -677,7 +677,7 @@ func makeTests(t *testing.T) []*TestGroup {
|
|||||||
// Netcup: NS records not currently supported.
|
// Netcup: NS records not currently supported.
|
||||||
tc("NS for subdomain", ns("xyz", "ns2.foo.com.")),
|
tc("NS for subdomain", ns("xyz", "ns2.foo.com.")),
|
||||||
tc("Dual NS for subdomain", ns("xyz", "ns2.foo.com."), ns("xyz", "ns1.foo.com.")),
|
tc("Dual NS for subdomain", ns("xyz", "ns2.foo.com."), ns("xyz", "ns1.foo.com.")),
|
||||||
tc("NS Record pointing to @", ns("foo", "**current-domain**")),
|
tc("NS Record pointing to @", a("@", "1.2.3.4"), ns("foo", "**current-domain**")),
|
||||||
),
|
),
|
||||||
|
|
||||||
testgroup("IGNORE_NAME function",
|
testgroup("IGNORE_NAME function",
|
||||||
|
@@ -126,6 +126,15 @@
|
|||||||
"directory": "config",
|
"directory": "config",
|
||||||
"domain": "example.com"
|
"domain": "example.com"
|
||||||
},
|
},
|
||||||
|
"ORACLE": {
|
||||||
|
"user_ocid": "$ORACLE_USER_OCID",
|
||||||
|
"tenancy_ocid": "$ORACLE_TENANCY_OCID",
|
||||||
|
"fingerprint": "$ORACLE_FINGERPRINT",
|
||||||
|
"region": "$ORACLE_REGION",
|
||||||
|
"private_key": "$ORACLE_PRIVATE_KEY",
|
||||||
|
"compartment": "$ORACLE_COMPARTMENT",
|
||||||
|
"domain": "$ORACLE_DOMAIN"
|
||||||
|
},
|
||||||
"OVH": {
|
"OVH": {
|
||||||
"app-key": "$OVH_APP_KEY",
|
"app-key": "$OVH_APP_KEY",
|
||||||
"app-secret-key": "$OVH_APP_SECRET_KEY",
|
"app-secret-key": "$OVH_APP_SECRET_KEY",
|
||||||
|
@@ -30,6 +30,7 @@ import (
|
|||||||
_ "github.com/StackExchange/dnscontrol/v3/providers/ns1"
|
_ "github.com/StackExchange/dnscontrol/v3/providers/ns1"
|
||||||
_ "github.com/StackExchange/dnscontrol/v3/providers/octodns"
|
_ "github.com/StackExchange/dnscontrol/v3/providers/octodns"
|
||||||
_ "github.com/StackExchange/dnscontrol/v3/providers/opensrs"
|
_ "github.com/StackExchange/dnscontrol/v3/providers/opensrs"
|
||||||
|
_ "github.com/StackExchange/dnscontrol/v3/providers/oracle"
|
||||||
_ "github.com/StackExchange/dnscontrol/v3/providers/ovh"
|
_ "github.com/StackExchange/dnscontrol/v3/providers/ovh"
|
||||||
_ "github.com/StackExchange/dnscontrol/v3/providers/powerdns"
|
_ "github.com/StackExchange/dnscontrol/v3/providers/powerdns"
|
||||||
_ "github.com/StackExchange/dnscontrol/v3/providers/route53"
|
_ "github.com/StackExchange/dnscontrol/v3/providers/route53"
|
||||||
|
361
providers/oracle/oracleProvider.go
Normal file
361
providers/oracle/oracleProvider.go
Normal file
@@ -0,0 +1,361 @@
|
|||||||
|
package oracle
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/oracle/oci-go-sdk/v32/dns"
|
||||||
|
|
||||||
|
"github.com/oracle/oci-go-sdk/v32/common"
|
||||||
|
"github.com/oracle/oci-go-sdk/v32/example/helpers"
|
||||||
|
|
||||||
|
"github.com/StackExchange/dnscontrol/v3/models"
|
||||||
|
"github.com/StackExchange/dnscontrol/v3/pkg/diff"
|
||||||
|
"github.com/StackExchange/dnscontrol/v3/pkg/printer"
|
||||||
|
"github.com/StackExchange/dnscontrol/v3/providers"
|
||||||
|
)
|
||||||
|
|
||||||
|
var features = providers.DocumentationNotes{
|
||||||
|
providers.DocCreateDomains: providers.Can(),
|
||||||
|
providers.DocDualHost: providers.Can(),
|
||||||
|
providers.DocOfficiallySupported: providers.Cannot(),
|
||||||
|
|
||||||
|
providers.CanGetZones: providers.Can(),
|
||||||
|
providers.CanUseAlias: providers.Can(),
|
||||||
|
providers.CanUseCAA: providers.Can(),
|
||||||
|
providers.CanUseDS: providers.Cannot(), // should be supported, but getting 500s in tests
|
||||||
|
providers.CanUseNAPTR: providers.Can(),
|
||||||
|
providers.CanUsePTR: providers.Can(),
|
||||||
|
providers.CanUseSRV: providers.Can(),
|
||||||
|
providers.CanUseSSHFP: providers.Can(),
|
||||||
|
providers.CanUseTLSA: providers.Can(),
|
||||||
|
providers.CanUseTXTMulti: providers.Can(),
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
providers.RegisterDomainServiceProviderType("ORACLE", New, features)
|
||||||
|
}
|
||||||
|
|
||||||
|
type oracleProvider struct {
|
||||||
|
client dns.DnsClient
|
||||||
|
compartment string
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new provider for Oracle Cloud DNS
|
||||||
|
func New(settings map[string]string, _ json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||||
|
client, err := dns.NewDnsClientWithConfigurationProvider(common.NewRawConfigurationProvider(
|
||||||
|
settings["tenancy_ocid"],
|
||||||
|
settings["user_ocid"],
|
||||||
|
settings["region"],
|
||||||
|
settings["fingerprint"],
|
||||||
|
settings["private_key"],
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &oracleProvider{
|
||||||
|
client: client,
|
||||||
|
compartment: settings["compartment"],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListZones lists the zones on this account.
|
||||||
|
func (o *oracleProvider) ListZones() ([]string, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
listResp, err := o.client.ListZones(ctx, dns.ListZonesRequest{
|
||||||
|
CompartmentId: &o.compartment,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
zones := make([]string, len(listResp.Items))
|
||||||
|
for i, zone := range listResp.Items {
|
||||||
|
zones[i] = *zone.Name
|
||||||
|
}
|
||||||
|
return zones, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnsureDomainExists creates the domain if it does not exist.
|
||||||
|
func (o *oracleProvider) EnsureDomainExists(domain string) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
getResp, err := o.client.GetZone(ctx, dns.GetZoneRequest{
|
||||||
|
ZoneNameOrId: &domain,
|
||||||
|
CompartmentId: &o.compartment,
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err != nil && getResp.RawResponse.StatusCode != 404 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = o.client.CreateZone(ctx, dns.CreateZoneRequest{
|
||||||
|
CreateZoneDetails: dns.CreateZoneDetails{
|
||||||
|
CompartmentId: &o.compartment,
|
||||||
|
Name: &domain,
|
||||||
|
ZoneType: dns.CreateZoneDetailsZoneTypePrimary,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// poll until the zone is ready
|
||||||
|
pollUntilAvailable := func(r common.OCIOperationResponse) bool {
|
||||||
|
if converted, ok := r.Response.(dns.GetZoneResponse); ok {
|
||||||
|
return converted.LifecycleState != dns.ZoneLifecycleStateActive
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
_, err = o.client.GetZone(ctx, dns.GetZoneRequest{
|
||||||
|
ZoneNameOrId: &domain,
|
||||||
|
CompartmentId: &o.compartment,
|
||||||
|
RequestMetadata: helpers.GetRequestMetadataWithCustomizedRetryPolicy(pollUntilAvailable),
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *oracleProvider) GetNameservers(domain string) ([]*models.Nameserver, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
getResp, err := o.client.GetZone(ctx, dns.GetZoneRequest{
|
||||||
|
ZoneNameOrId: &domain,
|
||||||
|
CompartmentId: &o.compartment,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nss := make([]string, len(getResp.Zone.Nameservers))
|
||||||
|
for i, ns := range getResp.Zone.Nameservers {
|
||||||
|
nss[i] = *ns.Hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
return models.ToNameservers(nss)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *oracleProvider) GetZoneRecords(domain string) (models.Records, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
records := models.Records{}
|
||||||
|
|
||||||
|
request := dns.GetZoneRecordsRequest{
|
||||||
|
ZoneNameOrId: &domain,
|
||||||
|
CompartmentId: &o.compartment,
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
getResp, err := o.client.GetZoneRecords(ctx, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, record := range getResp.Items {
|
||||||
|
// Hide SOAs
|
||||||
|
if *record.Rtype == "SOA" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
rc := &models.RecordConfig{
|
||||||
|
Type: *record.Rtype,
|
||||||
|
TTL: uint32(*record.Ttl),
|
||||||
|
Original: record,
|
||||||
|
}
|
||||||
|
rc.SetLabelFromFQDN(*record.Domain, domain)
|
||||||
|
|
||||||
|
switch rc.Type {
|
||||||
|
case "ALIAS":
|
||||||
|
err = rc.SetTarget(*record.Rdata)
|
||||||
|
default:
|
||||||
|
err = rc.PopulateFromString(*record.Rtype, *record.Rdata, domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
records = append(records, rc)
|
||||||
|
}
|
||||||
|
|
||||||
|
if getResp.OpcNextPage == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Page = getResp.OpcNextPage
|
||||||
|
}
|
||||||
|
|
||||||
|
return records, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *oracleProvider) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
|
||||||
|
dc, err := dc.Copy()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dc.Punycode()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
domain := dc.Name
|
||||||
|
|
||||||
|
existingRecords, err := o.GetZoneRecords(domain)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize
|
||||||
|
models.PostProcessRecords(existingRecords)
|
||||||
|
|
||||||
|
filteredNewRecords := models.Records{}
|
||||||
|
|
||||||
|
// Ensure we don't emit changes for attempted modification of built-in apex NSs
|
||||||
|
for _, rec := range dc.Records {
|
||||||
|
if rec.Type != "NS" {
|
||||||
|
filteredNewRecords = append(filteredNewRecords, rec)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
recNS := rec.GetTargetField()
|
||||||
|
if rec.GetLabel() == "@" && strings.HasSuffix(recNS, "dns.oraclecloud.com.") {
|
||||||
|
printer.Warnf("Oracle Cloud does not allow changes to built-in apex NS records. Ignoring change to %s...\n", recNS)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if rec.TTL != 86400 {
|
||||||
|
printer.Warnf("Oracle Cloud forces TTL=86400 for NS records. Ignoring configured TTL of %d for %s\n", rec.TTL, recNS)
|
||||||
|
rec.TTL = 86400
|
||||||
|
}
|
||||||
|
filteredNewRecords = append(filteredNewRecords, rec)
|
||||||
|
}
|
||||||
|
|
||||||
|
differ := diff.New(dc)
|
||||||
|
_, create, dels, modify, err := differ.IncrementalDiff(existingRecords)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Oracle's API doesn't have a way to update an existing record.
|
||||||
|
You can either update an existing RRSet, Domain (FQDN), or Zone in which you have to supply
|
||||||
|
the entire desired state, or you can patch specifying ADD/REMOVE actions.
|
||||||
|
Oracle's API is also increadibly slow, so updating individual RRSets is unbearably slow
|
||||||
|
for any size zone.
|
||||||
|
*/
|
||||||
|
|
||||||
|
corrections := []*models.Correction{}
|
||||||
|
|
||||||
|
if len(create) > 0 {
|
||||||
|
createRecords := models.Records{}
|
||||||
|
desc := ""
|
||||||
|
for _, d := range create {
|
||||||
|
createRecords = append(createRecords, d.Desired)
|
||||||
|
desc += d.String() + "\n"
|
||||||
|
}
|
||||||
|
desc = desc[:len(desc)-1]
|
||||||
|
|
||||||
|
corrections = append(corrections, &models.Correction{
|
||||||
|
Msg: desc,
|
||||||
|
F: func() error {
|
||||||
|
return o.patch(createRecords, nil, domain)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(dels) > 0 {
|
||||||
|
deleteRecords := models.Records{}
|
||||||
|
desc := ""
|
||||||
|
for _, d := range dels {
|
||||||
|
deleteRecords = append(deleteRecords, d.Existing)
|
||||||
|
desc += d.String() + "\n"
|
||||||
|
}
|
||||||
|
desc = desc[:len(desc)-1]
|
||||||
|
|
||||||
|
corrections = append(corrections, &models.Correction{
|
||||||
|
Msg: desc,
|
||||||
|
F: func() error {
|
||||||
|
return o.patch(nil, deleteRecords, domain)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(modify) > 0 {
|
||||||
|
createRecords := models.Records{}
|
||||||
|
deleteRecords := models.Records{}
|
||||||
|
desc := ""
|
||||||
|
for _, d := range modify {
|
||||||
|
createRecords = append(createRecords, d.Desired)
|
||||||
|
deleteRecords = append(deleteRecords, d.Existing)
|
||||||
|
desc += d.String() + "\n"
|
||||||
|
}
|
||||||
|
desc = desc[:len(desc)-1]
|
||||||
|
|
||||||
|
corrections = append(corrections, &models.Correction{
|
||||||
|
Msg: desc,
|
||||||
|
F: func() error {
|
||||||
|
return o.patch(createRecords, deleteRecords, domain)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return corrections, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *oracleProvider) patch(createRecords, deleteRecords models.Records, domain string) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
patchReq := dns.PatchZoneRecordsRequest{
|
||||||
|
ZoneNameOrId: &domain,
|
||||||
|
CompartmentId: &o.compartment,
|
||||||
|
}
|
||||||
|
|
||||||
|
ops := make([]dns.RecordOperation, 0, len(createRecords)+len(deleteRecords))
|
||||||
|
|
||||||
|
for _, rec := range deleteRecords {
|
||||||
|
ops = append(ops, convertToRecordOperation(rec, dns.RecordOperationOperationRemove))
|
||||||
|
}
|
||||||
|
for _, rec := range createRecords {
|
||||||
|
ops = append(ops, convertToRecordOperation(rec, dns.RecordOperationOperationAdd))
|
||||||
|
}
|
||||||
|
|
||||||
|
for batchStart := 0; batchStart < len(ops); batchStart += 100 {
|
||||||
|
batchEnd := batchStart + 100
|
||||||
|
if batchEnd > len(ops) {
|
||||||
|
batchEnd = len(ops)
|
||||||
|
}
|
||||||
|
patchReq.Items = ops[batchStart:batchEnd]
|
||||||
|
_, err := o.client.PatchZoneRecords(ctx, patchReq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToRecordOperation(rec *models.RecordConfig, op dns.RecordOperationOperationEnum) dns.RecordOperation {
|
||||||
|
fqdn := rec.GetLabelFQDN()
|
||||||
|
rtype := rec.Type
|
||||||
|
rdata := rec.GetTargetCombined()
|
||||||
|
ttl := int(rec.TTL)
|
||||||
|
return dns.RecordOperation{
|
||||||
|
Domain: &fqdn,
|
||||||
|
Rtype: &rtype,
|
||||||
|
Rdata: &rdata,
|
||||||
|
Ttl: &ttl,
|
||||||
|
Operation: op,
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user