Skip to content

Commit fb18bec

Browse files
committed
Merge branch 'menai34-add_client_cache_for_rest_api_requests'
2 parents c97d5a1 + fcdb712 commit fb18bec

29 files changed

+1949
-25
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ website/node_modules
2222
*~
2323
.*.swp
2424
.idea
25+
.vscode
2526
*.iml
2627
*.test
2728
*.iml

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/terraform-providers/terraform-provider-powerdns
33
go 1.12
44

55
require (
6+
github.com/coocood/freecache v1.1.1
67
github.com/hashicorp/go-cleanhttp v0.5.1
78
github.com/hashicorp/terraform-plugin-sdk v1.1.0
89
github.com/stretchr/testify v1.3.0

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbf
99
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
1010
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
1111
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
12+
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
13+
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
1214
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
1315
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
1416
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
@@ -30,8 +32,12 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ
3032
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
3133
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
3234
github.com/bsm/go-vlq v0.0.0-20150828105119-ec6e8d4f5f4e/go.mod h1:N+BjUcTjSxc2mtRGSCPsat1kze3CUtvJN3/jTXlp29k=
35+
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
36+
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
3337
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
3438
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
39+
github.com/coocood/freecache v1.1.1 h1:uukNF7QKCZEdZ9gAV7WQzvh0SbjwdMF6m3x3rxEkaPc=
40+
github.com/coocood/freecache v1.1.1/go.mod h1:OKrEjkGVoxZhyWAJoeFi5BMLUJm2Tit0kpGkIr7NGYY=
3541
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3642
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3743
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -168,6 +174,8 @@ github.com/posener/complete v1.2.1 h1:LrvDIY//XNo65Lq84G/akBuMGlawHvGBABv8f/ZN6D
168174
github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E=
169175
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
170176
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
177+
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
178+
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
171179
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
172180
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
173181
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=

powerdns/client.go

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,37 @@ import (
66
"encoding/json"
77
"fmt"
88
"io"
9+
"log"
910
"net/http"
1011
"net/url"
1112
"strconv"
1213
"strings"
1314

15+
freecache "github.com/coocood/freecache"
1416
cleanhttp "github.com/hashicorp/go-cleanhttp"
1517
)
1618

1719
// DefaultSchema is the value used for the URL in case
1820
// no schema is explicitly defined
1921
var DefaultSchema = "https"
2022

23+
// DefaultCacheSize is client default cache size
24+
var DefaultCacheSize int
25+
2126
// Client is a PowerDNS client representation
2227
type Client struct {
2328
ServerURL string // Location of PowerDNS server to use
2429
ServerVersion string
2530
APIKey string // REST API Static authentication key
2631
APIVersion int // API version to use
2732
HTTP *http.Client
33+
CacheEnable bool // Enable/Disable chache for REST API requests
34+
Cache *freecache.Cache
35+
CacheTTL int
2836
}
2937

3038
// NewClient returns a new PowerDNS client
31-
func NewClient(serverURL string, apiKey string, configTLS *tls.Config) (*Client, error) {
39+
func NewClient(serverURL string, apiKey string, configTLS *tls.Config, cacheEnable bool, cacheSizeMB string, cacheTTL int) (*Client, error) {
3240

3341
cleanURL, err := sanitizeURL(serverURL)
3442

@@ -39,11 +47,22 @@ func NewClient(serverURL string, apiKey string, configTLS *tls.Config) (*Client,
3947
return nil, fmt.Errorf("Error while creating client: %s", err)
4048
}
4149

50+
if cacheEnable {
51+
cacheSize, err := strconv.Atoi(cacheSizeMB)
52+
if err != nil {
53+
return nil, fmt.Errorf("Error while creating client: %s", err)
54+
}
55+
DefaultCacheSize = cacheSize * 1024 * 1024
56+
}
57+
4258
client := Client{
43-
ServerURL: cleanURL,
44-
APIKey: apiKey,
45-
HTTP: httpClient,
46-
APIVersion: -1,
59+
ServerURL: cleanURL,
60+
APIKey: apiKey,
61+
HTTP: httpClient,
62+
APIVersion: -1,
63+
CacheEnable: cacheEnable,
64+
Cache: freecache.NewCache(DefaultCacheSize),
65+
CacheTTL: cacheTTL,
4766
}
4867

4968
if err := client.setServerVersion(); err != nil {
@@ -420,23 +439,62 @@ func (client *Client) DeleteZone(name string) error {
420439
return nil
421440
}
422441

442+
// GetZoneInfoFromCache return ZoneInfo struct
443+
func (client *Client) GetZoneInfoFromCache(zone string) (*ZoneInfo, error) {
444+
if client.CacheEnable {
445+
cacheZoneInfo, err := client.Cache.Get([]byte(zone))
446+
if err != nil {
447+
return nil, err
448+
}
449+
450+
zoneInfo := new(ZoneInfo)
451+
err = json.Unmarshal(cacheZoneInfo, &zoneInfo)
452+
if err != nil {
453+
return nil, err
454+
}
455+
456+
return zoneInfo, err
457+
}
458+
return nil, nil
459+
}
460+
423461
// ListRecords returns all records in Zone
424462
func (client *Client) ListRecords(zone string) ([]Record, error) {
425-
req, err := client.newRequest("GET", fmt.Sprintf("/servers/localhost/zones/%s", zone), nil)
463+
zoneInfo, err := client.GetZoneInfoFromCache(zone)
426464
if err != nil {
427-
return nil, err
465+
log.Printf("[WARN] module.freecache: %s: %s", zone, err)
428466
}
429467

430-
resp, err := client.HTTP.Do(req)
431-
if err != nil {
432-
return nil, err
433-
}
434-
defer resp.Body.Close()
468+
if zoneInfo == nil {
469+
req, err := client.newRequest("GET", fmt.Sprintf("/servers/localhost/zones/%s", zone), nil)
470+
if err != nil {
471+
return nil, err
472+
}
435473

436-
zoneInfo := new(ZoneInfo)
437-
err = json.NewDecoder(resp.Body).Decode(zoneInfo)
438-
if err != nil {
439-
return nil, err
474+
resp, err := client.HTTP.Do(req)
475+
if err != nil {
476+
return nil, err
477+
}
478+
defer resp.Body.Close()
479+
480+
zoneInfo = new(ZoneInfo)
481+
err = json.NewDecoder(resp.Body).Decode(zoneInfo)
482+
if err != nil {
483+
return nil, err
484+
}
485+
486+
if client.CacheEnable {
487+
cacheValue, err := json.Marshal(zoneInfo)
488+
if err != nil {
489+
return nil, err
490+
}
491+
492+
err = client.Cache.Set([]byte(zone), cacheValue, client.CacheTTL)
493+
if err != nil {
494+
return nil, fmt.Errorf("The cache for REST API requests is enabled but the size isn't enough: cacheSize: %db \n %s",
495+
DefaultCacheSize, err)
496+
}
497+
}
440498
}
441499

442500
records := zoneInfo.Records

powerdns/config.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@ import (
1111

1212
// Config describes de configuration interface of this provider
1313
type Config struct {
14-
ServerURL string
15-
APIKey string
16-
InsecureHTTPS bool
17-
CACertificate string
14+
ServerURL string
15+
APIKey string
16+
InsecureHTTPS bool
17+
CACertificate string
18+
CacheEnable bool
19+
CacheMemorySize string
20+
CacheTTL int
1821
}
1922

2023
// Client returns a new client for accessing PowerDNS
@@ -36,7 +39,7 @@ func (c *Config) Client() (*Client, error) {
3639

3740
tlsConfig.InsecureSkipVerify = c.InsecureHTTPS
3841

39-
client, err := NewClient(c.ServerURL, c.APIKey, tlsConfig)
42+
client, err := NewClient(c.ServerURL, c.APIKey, tlsConfig, c.CacheEnable, c.CacheMemorySize, c.CacheTTL)
4043

4144
if err != nil {
4245
return nil, fmt.Errorf("Error setting up PowerDNS client: %s", err)

powerdns/provider.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ func Provider() terraform.ResourceProvider {
3333
DefaultFunc: schema.EnvDefaultFunc("PDNS_CACERT", ""),
3434
Description: "Content or path of a Root CA to be used to verify PowerDNS's SSL certificate",
3535
},
36+
"cache_requests": {
37+
Type: schema.TypeBool,
38+
Optional: true,
39+
DefaultFunc: schema.EnvDefaultFunc("PDNS_CACHE_REQUESTS", false),
40+
Description: "Enable cache REST API requests",
41+
},
42+
"cache_mem_size": {
43+
Type: schema.TypeString,
44+
Optional: true,
45+
DefaultFunc: schema.EnvDefaultFunc("PDNS_CACHE_MEM_SIZE", "100"),
46+
Description: "Set cache memory size in MB",
47+
},
48+
"cache_ttl": {
49+
Type: schema.TypeInt,
50+
Optional: true,
51+
DefaultFunc: schema.EnvDefaultFunc("PDNS_CACHE_TTL", 30),
52+
Description: "Set cache TTL in seconds",
53+
},
3654
},
3755

3856
ResourcesMap: map[string]*schema.Resource{
@@ -46,10 +64,13 @@ func Provider() terraform.ResourceProvider {
4664

4765
func providerConfigure(data *schema.ResourceData) (interface{}, error) {
4866
config := Config{
49-
APIKey: data.Get("api_key").(string),
50-
ServerURL: data.Get("server_url").(string),
51-
InsecureHTTPS: data.Get("insecure_https").(bool),
52-
CACertificate: data.Get("ca_certificate").(string),
67+
APIKey: data.Get("api_key").(string),
68+
ServerURL: data.Get("server_url").(string),
69+
InsecureHTTPS: data.Get("insecure_https").(bool),
70+
CACertificate: data.Get("ca_certificate").(string),
71+
CacheEnable: data.Get("cache_requests").(bool),
72+
CacheMemorySize: data.Get("cache_mem_size").(string),
73+
CacheTTL: data.Get("cache_ttl").(int),
5374
}
5475

5576
return config.Client()

vendor/github.com/cespare/xxhash/LICENSE.txt

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/cespare/xxhash/README.md

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/cespare/xxhash/go.mod

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/cespare/xxhash/go.sum

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)