@@ -8,15 +8,18 @@ import (
88 "sync"
99 "time"
1010
11- cf "github.com/cloudflare/cloudflare-go"
11+ cf "github.com/cloudflare/cloudflare-go/v6"
12+ cfdns "github.com/cloudflare/cloudflare-go/v6/dns"
13+ cfopt "github.com/cloudflare/cloudflare-go/v6/option"
14+ cfzones "github.com/cloudflare/cloudflare-go/v6/zones"
1215
1316 "github.com/0xJacky/Nginx-UI/internal/dns"
1417)
1518
1619const defaultTimeout = 10 * time .Second
1720
1821type provider struct {
19- client * cf.API
22+ client * cf.Client
2023 zoneCache sync.Map
2124}
2225
@@ -27,15 +30,15 @@ func init() {
2730func newProvider (cred * dns.Credential ) (dns.Provider , error ) {
2831 httpClient := & http.Client {Timeout : defaultTimeout }
2932
30- opts := []cf. Option {
31- cf . HTTPClient (httpClient ),
33+ opts := []cfopt. RequestOption {
34+ cfopt . WithHTTPClient (httpClient ),
3235 }
3336
3437 if baseURL := firstNonEmpty (
3538 cred .Additional ["CLOUDFLARE_BASE_URL" ],
3639 cred .Additional ["CF_BASE_URL" ],
3740 ); baseURL != "" {
38- opts = append (opts , cf . BaseURL (baseURL ))
41+ opts = append (opts , cfopt . WithBaseURL (baseURL ))
3942 }
4043
4144 token := firstNonEmpty (
@@ -45,13 +48,10 @@ func newProvider(cred *dns.Credential) (dns.Provider, error) {
4548 cred .Values ["CF_API_TOKEN" ],
4649 )
4750
48- var (
49- api * cf.API
50- err error
51- )
51+ var api * cf.Client
5252
5353 if token != "" {
54- api , err = cf .NewWithAPIToken ( token , opts ... )
54+ api = cf .NewClient ( append ( opts , cfopt . WithAPIToken ( token )) ... )
5555 } else {
5656 email := firstNonEmpty (
5757 cred .Values ["CLOUDFLARE_EMAIL" ],
@@ -64,11 +64,7 @@ func newProvider(cred *dns.Credential) (dns.Provider, error) {
6464 if email == "" || key == "" {
6565 return nil , fmt .Errorf ("cloudflare: missing API credentials" )
6666 }
67- api , err = cf .New (key , email , opts ... )
68- }
69-
70- if err != nil {
71- return nil , fmt .Errorf ("cloudflare: %w" , err )
67+ api = cf .NewClient (append (opts , cfopt .WithAPIKey (key ), cfopt .WithAPIEmail (email ))... )
7268 }
7369
7470 return & provider {
@@ -77,141 +73,169 @@ func newProvider(cred *dns.Credential) (dns.Provider, error) {
7773}
7874
7975func (p * provider ) ListRecords (ctx context.Context , domain string , filter dns.RecordFilter ) ([]dns.Record , error ) {
80- zoneID , err := p .zoneID (domain )
76+ zoneID , err := p .zoneID (ctx , domain )
8177 if err != nil {
8278 return nil , err
8379 }
8480
85- params := cf. ListDNSRecordsParams {
86- Type : strings . ToUpper ( strings . TrimSpace ( filter . Type ) ),
81+ params := cfdns. RecordListParams {
82+ ZoneID : cf . F ( zoneID ),
8783 }
8884
89- if params .Type == "" {
90- params .Type = ""
85+ recordType := strings .ToUpper (strings .TrimSpace (filter .Type ))
86+ if recordType != "" {
87+ params .Type = cf .F (cfdns .RecordListParamsType (recordType ))
9188 }
9289
93- if filter .Name != "" {
94- params .Name = buildFQDN (domain , filter .Name )
90+ if name := strings .TrimSpace (filter .Name ); name != "" {
91+ params .Name = cf .F (cfdns.RecordListParamsName {
92+ Exact : cf .F (buildFQDN (domain , name )),
93+ })
9594 }
9695
97- records , _ , err := p .client .ListDNSRecords (ctx , cf .ZoneIdentifier (zoneID ), params )
98- if err != nil {
99- return nil , fmt .Errorf ("cloudflare: list records: %w" , err )
100- }
96+ pager := p .client .DNS .Records .ListAutoPaging (ctx , params )
10197
102- result := make ([]dns.Record , 0 , len (records ))
103- for _ , record := range records {
98+ result := make ([]dns.Record , 0 )
99+ for pager .Next () {
100+ record := pager .Current ()
101+ proxied := record .Proxied
104102 result = append (result , dns.Record {
105103 ID : record .ID ,
106- Type : record .Type ,
104+ Type : string ( record .Type ) ,
107105 Name : toRelativeName (record .Name , domain ),
108106 Content : record .Content ,
109- TTL : record .TTL ,
110- Priority : toOptionalInt (record .Priority ),
111- Proxied : record . Proxied ,
107+ TTL : int ( record .TTL ) ,
108+ Priority : toOptionalPriority (record .Priority ),
109+ Proxied : & proxied ,
112110 })
113111 }
114112
113+ if err := pager .Err (); err != nil {
114+ return nil , fmt .Errorf ("cloudflare: list records: %w" , err )
115+ }
116+
115117 return result , nil
116118}
117119
118120func (p * provider ) CreateRecord (ctx context.Context , domain string , input dns.RecordInput ) (dns.Record , error ) {
119- zoneID , err := p .zoneID (domain )
121+ zoneID , err := p .zoneID (ctx , domain )
120122 if err != nil {
121123 return dns.Record {}, err
122124 }
123125
124- params := cf.CreateDNSRecordParams {
125- Type : strings .ToUpper (strings .TrimSpace (input .Type )),
126- Name : buildFQDN (domain , input .Name ),
127- Content : strings .TrimSpace (input .Content ),
128- TTL : input .TTL ,
129- Proxied : input .Proxied ,
126+ body := cfdns.RecordNewParamsBody {
127+ Type : cf .F (cfdns .RecordNewParamsBodyType (strings .ToUpper (strings .TrimSpace (input .Type )))),
128+ Name : cf .F (buildFQDN (domain , input .Name )),
129+ Content : cf .F (strings .TrimSpace (input .Content )),
130+ TTL : cf .F (cfdns .TTL (normalizeTTL (input .TTL ))),
131+ }
132+
133+ if input .Proxied != nil {
134+ body .Proxied = cf .F (* input .Proxied )
130135 }
131136
132137 if input .Priority != nil {
133- value := uint16 (max (* input .Priority , 0 ))
134- params .Priority = & value
138+ value := float64 (max (* input .Priority , 0 ))
139+ body .Priority = cf . F ( value )
135140 }
136141
137- record , err := p .client .CreateDNSRecord (ctx , cf .ZoneIdentifier (zoneID ), params )
142+ record , err := p .client .DNS .Records .New (ctx , cfdns.RecordNewParams {
143+ ZoneID : cf .F (zoneID ),
144+ Body : body ,
145+ })
138146 if err != nil {
139147 return dns.Record {}, fmt .Errorf ("cloudflare: create record: %w" , err )
140148 }
141149
142150 return dns.Record {
143151 ID : record .ID ,
144- Type : record .Type ,
152+ Type : string ( record .Type ) ,
145153 Name : toRelativeName (record .Name , domain ),
146154 Content : record .Content ,
147- TTL : record .TTL ,
148- Priority : toOptionalInt (record .Priority ),
149- Proxied : record .Proxied ,
155+ TTL : int ( record .TTL ) ,
156+ Priority : toOptionalPriority (record .Priority ),
157+ Proxied : boolPtr ( record .Proxied ) ,
150158 }, nil
151159}
152160
153161func (p * provider ) UpdateRecord (ctx context.Context , domain string , recordID string , input dns.RecordInput ) (dns.Record , error ) {
154- zoneID , err := p .zoneID (domain )
162+ zoneID , err := p .zoneID (ctx , domain )
155163 if err != nil {
156164 return dns.Record {}, err
157165 }
158166
159- params := cf.UpdateDNSRecordParams {
160- ID : recordID ,
161- Type : strings .ToUpper (strings .TrimSpace (input .Type )),
162- Name : buildFQDN (domain , input .Name ),
163- Content : strings .TrimSpace (input .Content ),
164- TTL : input .TTL ,
165- Proxied : input .Proxied ,
167+ body := cfdns.RecordUpdateParamsBody {
168+ Type : cf .F (cfdns .RecordUpdateParamsBodyType (strings .ToUpper (strings .TrimSpace (input .Type )))),
169+ Name : cf .F (buildFQDN (domain , input .Name )),
170+ Content : cf .F (strings .TrimSpace (input .Content )),
171+ TTL : cf .F (cfdns .TTL (normalizeTTL (input .TTL ))),
172+ }
173+
174+ if input .Proxied != nil {
175+ body .Proxied = cf .F (* input .Proxied )
166176 }
167177
168178 if input .Priority != nil {
169- value := uint16 (max (* input .Priority , 0 ))
170- params .Priority = & value
179+ value := float64 (max (* input .Priority , 0 ))
180+ body .Priority = cf . F ( value )
171181 }
172182
173- record , err := p .client .UpdateDNSRecord (ctx , cf .ZoneIdentifier (zoneID ), params )
183+ record , err := p .client .DNS .Records .Update (ctx , recordID , cfdns.RecordUpdateParams {
184+ ZoneID : cf .F (zoneID ),
185+ Body : body ,
186+ })
174187 if err != nil {
175188 return dns.Record {}, fmt .Errorf ("cloudflare: update record: %w" , err )
176189 }
177190
178191 return dns.Record {
179192 ID : record .ID ,
180- Type : record .Type ,
193+ Type : string ( record .Type ) ,
181194 Name : toRelativeName (record .Name , domain ),
182195 Content : record .Content ,
183- TTL : record .TTL ,
184- Priority : toOptionalInt (record .Priority ),
185- Proxied : record .Proxied ,
196+ TTL : int ( record .TTL ) ,
197+ Priority : toOptionalPriority (record .Priority ),
198+ Proxied : boolPtr ( record .Proxied ) ,
186199 }, nil
187200}
188201
189202func (p * provider ) DeleteRecord (ctx context.Context , domain string , recordID string ) error {
190- zoneID , err := p .zoneID (domain )
203+ zoneID , err := p .zoneID (ctx , domain )
191204 if err != nil {
192205 return err
193206 }
194207
195- if err := p .client .DeleteDNSRecord (ctx , cf .ZoneIdentifier (zoneID ), recordID ); err != nil {
208+ if _ , err := p .client .DNS .Records .Delete (ctx , recordID , cfdns.RecordDeleteParams {
209+ ZoneID : cf .F (zoneID ),
210+ }); err != nil {
196211 return fmt .Errorf ("cloudflare: delete record: %w" , err )
197212 }
198213
199214 return nil
200215}
201216
202- func (p * provider ) zoneID (domain string ) (string , error ) {
217+ func (p * provider ) zoneID (ctx context. Context , domain string ) (string , error ) {
203218 normalized := strings .TrimSuffix (strings .ToLower (strings .TrimSpace (domain )), "." )
204219 if zoneID , ok := p .zoneCache .Load (normalized ); ok {
205220 return zoneID .(string ), nil
206221 }
207222
208- id , err := p .client .ZoneIDByName (normalized )
209- if err != nil {
223+ pager := p .client .Zones .ListAutoPaging (ctx , cfzones.ZoneListParams {
224+ Name : cf .F (normalized ),
225+ })
226+ for pager .Next () {
227+ zone := pager .Current ()
228+ if strings .EqualFold (strings .TrimSuffix (zone .Name , "." ), normalized ) {
229+ p .zoneCache .Store (normalized , zone .ID )
230+ return zone .ID , nil
231+ }
232+ }
233+
234+ if err := pager .Err (); err != nil {
210235 return "" , fmt .Errorf ("cloudflare: resolve zone id: %w" , err )
211236 }
212237
213- p .zoneCache .Store (normalized , id )
214- return id , nil
238+ return "" , fmt .Errorf ("cloudflare: resolve zone id: not found" )
215239}
216240
217241func firstNonEmpty (values ... string ) string {
@@ -250,17 +274,28 @@ func toRelativeName(fqdn, domain string) string {
250274 return fqdn
251275}
252276
253- func toOptionalInt (value * uint16 ) * int {
254- if value == nil {
277+ func toOptionalPriority (value float64 ) * int {
278+ if value == 0 {
255279 return nil
256280 }
257- v := int (* value )
281+ v := int (value )
258282 return & v
259283}
260284
285+ func normalizeTTL (ttl int ) int {
286+ if ttl <= 0 {
287+ return 1
288+ }
289+ return ttl
290+ }
291+
261292func max (a , b int ) int {
262293 if a > b {
263294 return a
264295 }
265296 return b
266297}
298+
299+ func boolPtr (v bool ) * bool {
300+ return & v
301+ }
0 commit comments