Skip to content

Commit

Permalink
Merge pull request #81 from dwango/feature/issue-74
Browse files Browse the repository at this point in the history
Implement cache
  • Loading branch information
s-dwinter authored May 27, 2024
2 parents dd21a1c + c4cef51 commit 2e401b4
Show file tree
Hide file tree
Showing 24 changed files with 1,019 additions and 54 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ go.work

# goreleaser
dist/

# temporary files
tmp/
6 changes: 3 additions & 3 deletions alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import (
// Engine initializes external store client and template.
type Engine = engine.Engine

var (
// NewConfigFromFile returns a new Config from file.
NewConfigFromFile = config.NewFromFile
// Config is the configuration for this library.
type Config = config.Config

var (
// NewEngine returns a new Engine.
NewEngine = engine.New
)
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.29.1
github.com/aws/aws-sdk-go-v2/service/ssm v1.50.4
github.com/spf13/cobra v1.8.0
golang.org/x/crypto v0.3.0
sigs.k8s.io/yaml v1.4.0
)

Expand Down Expand Up @@ -36,6 +37,5 @@ require (
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/crypto v0.3.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
5 changes: 3 additions & 2 deletions internal/client/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
kmsTypes "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
"github.com/aws/aws-sdk-go-v2/service/ssm"
ssmTypes "github.com/aws/aws-sdk-go-v2/service/ssm/types"
"github.com/dwango/yashiro/internal/values"
"github.com/dwango/yashiro/pkg/config"
)

Expand Down Expand Up @@ -56,8 +57,8 @@ func newAwsClient(cfg *config.AwsConfig) (Client, error) {
}, nil
}

func (c awsClient) GetValues(ctx context.Context, ignoreNotFound bool) (Values, error) {
values := make(Values, len(c.parameterStoreValue)+len(c.secretsManagerValue))
func (c awsClient) GetValues(ctx context.Context, ignoreNotFound bool) (values.Values, error) {
values := make(values.Values, len(c.parameterStoreValue)+len(c.secretsManagerValue))

for _, v := range c.parameterStoreValue {
output, err := c.ssmClient.GetParameter(ctx, &ssm.GetParameterInput{
Expand Down
9 changes: 5 additions & 4 deletions internal/client/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
kmsTypes "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
"github.com/aws/aws-sdk-go-v2/service/ssm"
ssmTypes "github.com/aws/aws-sdk-go-v2/service/ssm/types"
"github.com/dwango/yashiro/internal/values"
"github.com/dwango/yashiro/pkg/config"
)

Expand Down Expand Up @@ -109,7 +110,7 @@ func Test_awsClient_GetValues(t *testing.T) {
name string
fields fields
args args
want Values
want values.Values
wantErr bool
}{
{
Expand All @@ -128,7 +129,7 @@ func Test_awsClient_GetValues(t *testing.T) {
ctx: context.Background(),
ignoreNotFound: false,
},
want: Values{"ssmKey": "test", "kmsKey": "test"},
want: values.Values{"ssmKey": "test", "kmsKey": "test"},
},
{
name: "ok: json",
Expand Down Expand Up @@ -156,7 +157,7 @@ func Test_awsClient_GetValues(t *testing.T) {
ctx: context.Background(),
ignoreNotFound: false,
},
want: Values{"ssmKey": map[string]any{"key": "value"}, "kmsKey": map[string]any{"key": "value"}},
want: values.Values{"ssmKey": map[string]any{"key": "value"}, "kmsKey": map[string]any{"key": "value"}},
},
{
name: "ok: ignore not found error",
Expand All @@ -174,7 +175,7 @@ func Test_awsClient_GetValues(t *testing.T) {
ctx: context.Background(),
ignoreNotFound: true,
},
want: Values{},
want: values.Values{},
},
{
name: "error: return not found from ssm",
Expand Down
60 changes: 60 additions & 0 deletions internal/client/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright 2024 DWANGO Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package client

import (
"context"

"github.com/dwango/yashiro/internal/client/cache"
"github.com/dwango/yashiro/internal/values"
)

type clientWithCache struct {
client Client
cache cache.Cache
}

func newClientWithCache(client Client, cache cache.Cache) Client {
return &clientWithCache{
client: client,
cache: cache,
}
}

// GetValues implements Client.
func (c *clientWithCache) GetValues(ctx context.Context, ignoreNotFound bool) (values.Values, error) {
val, expired, err := c.cache.Load(ctx)
if err != nil {
return nil, err
}

// if cache is empty, get values from external store.
if len(val) == 0 || expired {
val, err = c.client.GetValues(ctx, ignoreNotFound)
if err != nil {
return nil, err
}
}

// save values to cache
if expired {
if err := c.cache.Save(ctx, val); err != nil {
return nil, err
}
}

return val, nil
}
49 changes: 49 additions & 0 deletions internal/client/cache/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Copyright 2024 DWANGO Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cache

import (
"context"
"errors"
"fmt"

"github.com/dwango/yashiro/internal/values"
"github.com/dwango/yashiro/pkg/config"
)

var (
ErrInvalidCacheType = errors.New("invalid cache type")
)

type Cache interface {
// Load returns values from cache and whether or not cache is expired. If cache is empty,
// returned values is empty and expired=true.
Load(ctx context.Context) (values.Values, bool, error)

// Save saves values to cache.
Save(ctx context.Context, val values.Values) error
}

func New(cfg config.CacheConfig) (Cache, error) {
switch cfg.Type {
case config.CacheTypeUnspecified, config.CacheTypeMemory:
return newMemoryCache()
case config.CacheTypeFile:
return newFileCache(cfg.File)
default:
return nil, fmt.Errorf("%w: %s", ErrInvalidCacheType, cfg.Type)
}
}
Loading

0 comments on commit 2e401b4

Please sign in to comment.