-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #878 from erkanzsy/main
New Storage Driver: Etcd
- Loading branch information
Showing
12 changed files
with
560 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
name-template: 'Etcd - v$RESOLVED_VERSION' | ||
tag-template: 'etcd/v$RESOLVED_VERSION' | ||
tag-prefix: etcd/v | ||
include-paths: | ||
- etcd | ||
categories: | ||
- title: '🚀 New' | ||
labels: | ||
- '✏️ Feature' | ||
- title: '🧹 Updates' | ||
labels: | ||
- '🧹 Updates' | ||
- '🤖 Dependencies' | ||
- title: '🐛 Fixes' | ||
labels: | ||
- '☢️ Bug' | ||
- title: '📚 Documentation' | ||
labels: | ||
- '📒 Documentation' | ||
change-template: '- $TITLE (#$NUMBER)' | ||
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. | ||
version-resolver: | ||
major: | ||
labels: | ||
- 'major' | ||
minor: | ||
labels: | ||
- 'minor' | ||
- '✏️ Feature' | ||
patch: | ||
labels: | ||
- 'patch' | ||
- '📒 Documentation' | ||
- '☢️ Bug' | ||
- '🤖 Dependencies' | ||
- '🧹 Updates' | ||
default: patch | ||
template: | | ||
$CHANGES | ||
**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...etcd/v$RESOLVED_VERSION | ||
Thank you $CONTRIBUTORS for making this update possible. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
name: Release Drafter Etcd | ||
on: | ||
push: | ||
# branches to consider in the event; optional, defaults to all | ||
branches: | ||
- master | ||
- main | ||
paths: | ||
- 'etcd/**' | ||
jobs: | ||
draft_release_etcd: | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 30 | ||
steps: | ||
- uses: release-drafter/release-drafter@v5 | ||
with: | ||
config-name: release-drafter-etcd.yml | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
on: | ||
push: | ||
branches: | ||
- master | ||
- main | ||
paths: | ||
- 'etcd/**' | ||
pull_request: | ||
paths: | ||
- 'etcd/**' | ||
name: "Tests Etcd" | ||
jobs: | ||
Tests: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
go-version: | ||
- 1.19.x | ||
- 1.20.x | ||
steps: | ||
- name: Fetch Repository | ||
uses: actions/checkout@v3 | ||
- name: Install etcd | ||
run: | | ||
docker run -d --name Etcd-server \ | ||
--publish 2379:2379 \ | ||
--publish 2380:2380 \ | ||
--env ALLOW_NONE_AUTHENTICATION=yes \ | ||
--env ETCD_ADVERTISE_CLIENT_URLS=http://etcd-server:2379 \ | ||
bitnami/etcd:latest | ||
- name: Install Go | ||
uses: actions/setup-go@v4 | ||
with: | ||
go-version: '${{ matrix.go-version }}' | ||
- name: Run Test | ||
run: cd ./etcd && go test ./... -v -race |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# Etcd | ||
|
||
A Etcd storage driver using [`etcd-io/etcd`](https://github.com/etcd-io/etcd). | ||
|
||
### Table of Contents | ||
- [Signatures](#signatures) | ||
- [Installation](#installation) | ||
- [Examples](#examples) | ||
- [Config](#config) | ||
- [Default Config](#default-config) | ||
|
||
### Signatures | ||
```go | ||
func New(config ...Config) *Storage | ||
func (s *Storage) Get(key string) ([]byte, error) | ||
func (s *Storage) Set(key string, val []byte, exp time.Duration) error | ||
func (s *Storage) Delete(key string) error | ||
func (s *Storage) Reset() error | ||
func (s *Storage) Close() error | ||
func (s *Storage) Conn() *clientv3.Client | ||
``` | ||
|
||
### Installation | ||
Etcd is tested on the 2 last [Go versions](https://golang.org/dl/) with support for modules. So make sure to initialize one first if you didn't do that yet: | ||
```bash | ||
go mod init github.com/<user>/<repo> | ||
``` | ||
And then install the etcd implementation: | ||
```bash | ||
go get github.com/gofiber/storage/etcd | ||
``` | ||
|
||
### Examples | ||
Import the storage package. | ||
```go | ||
import "github.com/gofiber/storage/etcd" | ||
``` | ||
|
||
You can use the following possibilities to create a storage: | ||
```go | ||
// Initialize default config | ||
store := etcd.New() | ||
|
||
// Initialize custom config | ||
store := etcd.New(Config{ | ||
Endpoints: []string{"localhost:2379"}, | ||
}) | ||
|
||
``` | ||
|
||
### Config | ||
```go | ||
type Config struct { | ||
// Endpoints is a list of URLs. | ||
Endpoints []string | ||
// DialTimeout is the timeout for failing to establish a connection. | ||
DialTimeout time.Duration | ||
// Username is a username for authentication. | ||
Username string | ||
// Password is a password for authentication. | ||
Password string | ||
// TLS holds the client secure credentials, if any. | ||
TLS *tls.Config | ||
} | ||
``` | ||
|
||
### Default Config | ||
```go | ||
var ConfigDefault = Config{ | ||
Endpoints: []string{"localhost:2379"}, | ||
DialTimeout: 2 * time.Second, | ||
Username: "", | ||
Password: "", | ||
TLS: nil, | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package etcd | ||
|
||
import ( | ||
"crypto/tls" | ||
"time" | ||
) | ||
|
||
// Config defines the config for storage. | ||
type Config struct { | ||
// Endpoints is a list of URLs. | ||
Endpoints []string | ||
// DialTimeout is the timeout for failing to establish a connection. | ||
DialTimeout time.Duration | ||
// Username is a username for authentication. | ||
Username string | ||
// Password is a password for authentication. | ||
Password string | ||
// TLS holds the client secure credentials, if any. | ||
TLS *tls.Config | ||
} | ||
|
||
// ConfigDefault is the default config | ||
var ConfigDefault = Config{ | ||
Endpoints: []string{"localhost:2379"}, | ||
DialTimeout: 2 * time.Second, | ||
Username: "", | ||
Password: "", | ||
TLS: nil, | ||
} | ||
|
||
// Helper function to set default values | ||
func configDefault(config ...Config) Config { | ||
// Return default config if nothing provided | ||
if len(config) < 1 { | ||
return ConfigDefault | ||
} | ||
|
||
// Override default config | ||
cfg := config[0] | ||
// Set default values | ||
if cfg.Username == "" { | ||
cfg.Username = ConfigDefault.Username | ||
} | ||
if cfg.Password == "" { | ||
cfg.Password = ConfigDefault.Password | ||
} | ||
if cfg.DialTimeout == 0 { | ||
cfg.DialTimeout = ConfigDefault.DialTimeout | ||
} | ||
|
||
return cfg | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package etcd | ||
|
||
import ( | ||
"context" | ||
"go.etcd.io/etcd/client/v3" | ||
"time" | ||
) | ||
|
||
type Storage struct { | ||
db *clientv3.Client | ||
} | ||
|
||
func New(config ...Config) *Storage { | ||
cfg := configDefault(config...) | ||
|
||
cli, err := clientv3.New(clientv3.Config{ | ||
Endpoints: cfg.Endpoints, | ||
DialTimeout: cfg.DialTimeout, | ||
Username: cfg.Username, | ||
Password: cfg.Password, | ||
TLS: cfg.TLS, | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
store := &Storage{ | ||
db: cli, | ||
} | ||
|
||
return store | ||
} | ||
|
||
func (s *Storage) Get(key string) ([]byte, error) { | ||
if len(key) <= 0 { | ||
return nil, nil | ||
} | ||
item, err := s.db.Get(context.Background(), key) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(item.Kvs) <= 0 { | ||
return nil, nil | ||
} | ||
|
||
return item.Kvs[0].Value, nil | ||
} | ||
|
||
func (s *Storage) Set(key string, val []byte, exp time.Duration) error { | ||
// Ain't Nobody Got Time For That | ||
if len(key) <= 0 || len(val) <= 0 { | ||
return nil | ||
} | ||
|
||
lease, err := s.db.Grant(context.Background(), int64(exp.Seconds())) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = s.db.Put(context.Background(), key, string(val), clientv3.WithLease(lease.ID)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (s *Storage) Delete(key string) error { | ||
if len(key) <= 0 { | ||
return nil | ||
} | ||
|
||
_, err := s.db.Delete(context.Background(), key) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (s *Storage) Reset() error { | ||
_, err := s.db.Delete(context.Background(), "", clientv3.WithPrefix()) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (s *Storage) Close() error { | ||
return s.db.Close() | ||
} | ||
|
||
func (s *Storage) Conn() *clientv3.Client { | ||
return s.db | ||
} |
Oops, something went wrong.