Compare commits
12 Commits
85589697da
...
f3fb25e3a3
Author | SHA1 | Date |
---|---|---|
naicoi | f3fb25e3a3 | |
naicoi | fe04dd21a3 | |
naicoi | cfbc21d9ff | |
naicoi | 1f851e8621 | |
naicoi | 19452e286a | |
naicoi | 9e2c6d9186 | |
naicoi | 6e7bff4565 | |
naicoi | 22a333011d | |
naicoi | 9840674121 | |
naicoi | dc50db7c88 | |
naicoi | 2625fcf725 | |
naicoi | 69ee268a5e |
|
@ -1,5 +1,6 @@
|
|||
FROM caddy:builder-alpine AS builder
|
||||
RUN xcaddy build v2.6.4 \
|
||||
RUN xcaddy build \
|
||||
--with techio.dev/lttech/caddy-redis \
|
||||
--with github.com/caddy-dns/cloudflare \
|
||||
--with github.com/caddy-dns/digitalocean \
|
||||
--with github.com/caddy-dns/porkbun \
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"admin": {
|
||||
"config": {
|
||||
"load": { "module": "http", "url": "{env.CONFIG_URL}" },
|
||||
"load": { "module": "env_redis" },
|
||||
"load_delay": "15s"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package caddyconfig
|
||||
package envredisloader
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
"github.com/go-redis/redis"
|
||||
goredis "github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -40,13 +40,13 @@ func (ENVRedisLoader) CaddyModule() caddy.ModuleInfo {
|
|||
|
||||
func (ENVRedisLoader) LoadConfig(ctx caddy.Context) ([]byte, error) {
|
||||
ClientName := os.Getenv("NAME")
|
||||
redisOpts, err := redis.ParseURL(os.Getenv("REDIS_URL"))
|
||||
redisOpts, err := goredis.ParseURL(os.Getenv("REDIS_URL"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rdb := redis.NewClient(redisOpts)
|
||||
rdb := goredis.NewClient(redisOpts)
|
||||
defer rdb.Close()
|
||||
val, err := rdb.Get("caddy:config:" + ClientName).Bytes()
|
||||
val, err := rdb.Get(ctx, "caddy:config:"+ClientName).Bytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
110
go.mod
110
go.mod
|
@ -1,83 +1,33 @@
|
|||
module github.com/techio-dev/caddy-redis
|
||||
module techio.dev/lttech/caddy-redis
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/caddyserver/caddy/v2 v2.6.4
|
||||
github.com/caddyserver/certmagic v0.18.1
|
||||
github.com/redis/go-redis/v9 v9.0.5
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.0.0 // indirect
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.0 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||
github.com/alecthomas/chroma/v2 v2.5.0 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
||||
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bsm/redislock v0.9.3 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/dgraph-io/badger v1.6.2 // indirect
|
||||
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
|
||||
github.com/dgraph-io/ristretto v0.1.0 // indirect
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
|
||||
github.com/caddyserver/certmagic v0.18.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dlclark/regexp2 v1.7.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
|
||||
github.com/go-chi/chi v4.1.2+incompatible // indirect
|
||||
github.com/go-kit/kit v0.10.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/stretchr/testify v1.8.1 // indirect
|
||||
go.uber.org/goleak v1.1.12 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||
github.com/golang/glog v1.0.0 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/cel-go v0.13.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
github.com/huandu/xstrings v1.3.3 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.13.0 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.3.1 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
|
||||
github.com/jackc/pgtype v1.12.0 // indirect
|
||||
github.com/jackc/pgx/v4 v4.17.2 // indirect
|
||||
github.com/klauspost/compress v1.15.15 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/libdns/libdns v0.2.1 // indirect
|
||||
github.com/manifoldco/promptui v0.9.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.13 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/mholt/acmez v1.2.0 // indirect
|
||||
github.com/micromdm/scep/v2 v2.1.0 // indirect
|
||||
github.com/miekg/dns v1.1.55 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-ps v1.0.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
|
@ -87,38 +37,7 @@ require (
|
|||
github.com/quic-go/qtls-go1-19 v0.2.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.1.0 // indirect
|
||||
github.com/quic-go/quic-go v0.32.0 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/shopspring/decimal v1.2.0 // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/slackhq/nebula v1.6.1 // indirect
|
||||
github.com/smallstep/certificates v0.23.2 // indirect
|
||||
github.com/smallstep/nosql v0.5.0 // indirect
|
||||
github.com/smallstep/truststore v0.12.1 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/cobra v1.6.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||
github.com/tailscale/tscert v0.0.0-20230124224810-c6dc1f4049b2 // indirect
|
||||
github.com/urfave/cli v1.22.12 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/yuin/goldmark v1.5.4 // indirect
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.39.0 // indirect
|
||||
go.opentelemetry.io/otel v1.13.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v0.36.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.13.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.13.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.12.0 // indirect
|
||||
go.step.sm/cli-utils v0.7.5 // indirect
|
||||
go.step.sm/crypto v0.23.2 // indirect
|
||||
go.step.sm/linkedca v0.19.0 // indirect
|
||||
github.com/redis/go-redis/v9 v9.0.5 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
|
@ -126,16 +45,9 @@ require (
|
|||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
||||
golang.org/x/mod v0.11.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/term v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
golang.org/x/tools v0.10.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 // indirect
|
||||
google.golang.org/grpc v1.52.3 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
howett.net/plist v1.0.0 // indirect
|
||||
)
|
||||
|
|
14
main.go
14
main.go
|
@ -1,14 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
caddycmd "github.com/caddyserver/caddy/v2/cmd"
|
||||
|
||||
// plug in Caddy modules here
|
||||
_ "github.com/caddyserver/caddy/v2/modules/standard"
|
||||
_ "github.com/techio-dev/caddy-redis/loader"
|
||||
_ "github.com/techio-dev/caddy-redis/storage"
|
||||
)
|
||||
|
||||
func main() {
|
||||
caddycmd.Main()
|
||||
}
|
144
storage/redis.go
144
storage/redis.go
|
@ -1,144 +0,0 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
var ClientName = "caddy:storage"
|
||||
|
||||
type RedisStorage struct {
|
||||
RedisClient *redis.Client
|
||||
}
|
||||
|
||||
func init() {
|
||||
caddy.RegisterModule(RedisStorage{})
|
||||
}
|
||||
|
||||
func (RedisStorage) CaddyModule() caddy.ModuleInfo {
|
||||
return caddy.ModuleInfo{
|
||||
ID: "caddy.storage.env_redis",
|
||||
New: func() caddy.Module {
|
||||
return new(RedisStorage)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (RedisStorage) CertMagicStorage() (certmagic.Storage, error) {
|
||||
redisOpts, err := redis.ParseURL(os.Getenv("REDIS_URL"))
|
||||
if err != nil {
|
||||
caddy.Log().Named("storage.redis.config").Error(fmt.Sprintf("err %v", err))
|
||||
return nil, err
|
||||
}
|
||||
caddy.Log().Named("storage.redis.config").Info(fmt.Sprintf("Addr: %v, DB: %v", redisOpts.Addr, redisOpts.DB))
|
||||
return &RedisStorage{
|
||||
RedisClient: redis.NewClient(redisOpts),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) Lock(ctx context.Context, key string) error {
|
||||
if val := rs.RedisClient.Exists(ctx, key).Val(); val > 0 {
|
||||
return fmt.Errorf("locked: %v", key)
|
||||
}
|
||||
return rs.RedisClient.Set(ctx, key, key, LockDuration).Err()
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) Unlock(ctx context.Context, key string) error {
|
||||
return rs.RedisClient.Del(ctx, key).Err()
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) Store(ctx context.Context, key string, value []byte) error {
|
||||
var KeyInfo = &certmagic.KeyInfo{
|
||||
Key: key,
|
||||
Modified: time.Now(),
|
||||
Size: int64(len(value)),
|
||||
IsTerminal: false,
|
||||
}
|
||||
statValue, err := json.Marshal(KeyInfo)
|
||||
if err != nil {
|
||||
caddy.Log().Named("redis:Store:Marshal").Error(fmt.Sprintf("err %v", err))
|
||||
return err
|
||||
}
|
||||
if err := rs.RedisClient.Set(ctx, rs.statKey(key), string(statValue), 0).Err(); err != nil {
|
||||
caddy.Log().Named("redis:Store:statKey").Error(fmt.Sprintf("err %v", err))
|
||||
return err
|
||||
}
|
||||
return rs.RedisClient.Set(ctx, key, string(value), 0).Err()
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) Load(ctx context.Context, key string) ([]byte, error) {
|
||||
val, err := rs.RedisClient.Get(ctx, key).Bytes()
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, fs.ErrNotExist
|
||||
}
|
||||
if err != nil {
|
||||
caddy.Log().Named("redis:Load").Error(fmt.Sprintf("err %v", err))
|
||||
return nil, err
|
||||
}
|
||||
if val == nil {
|
||||
return nil, fs.ErrNotExist
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) Delete(ctx context.Context, key string) error {
|
||||
return rs.RedisClient.Del(ctx, key, rs.statKey(key)).Err()
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) Exists(ctx context.Context, key string) bool {
|
||||
return rs.RedisClient.Exists(ctx, key).Val() > 0
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) List(ctx context.Context, prefix string, recursive bool) ([]string, error) {
|
||||
iter := rs.RedisClient.Scan(ctx, 0, rs.prefixKey("*"), 0).Iterator()
|
||||
var keys []string
|
||||
for iter.Next(ctx) {
|
||||
keys = append(keys, strings.TrimPrefix(iter.Val(), rs.prefixKey("")))
|
||||
}
|
||||
if err := iter.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) Stat(ctx context.Context, key string) (certmagic.KeyInfo, error) {
|
||||
var KeyInfo = certmagic.KeyInfo{}
|
||||
val, err := rs.RedisClient.Get(ctx, rs.statKey(key)).Bytes()
|
||||
if err != nil {
|
||||
return KeyInfo, err
|
||||
}
|
||||
if err := json.Unmarshal(val, &KeyInfo); err != nil {
|
||||
return KeyInfo, err
|
||||
}
|
||||
return KeyInfo, nil
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) prefixKey(key string) string {
|
||||
if key == "*" || key == "" {
|
||||
return ClientName + ":data:" + key
|
||||
}
|
||||
return ClientName + ":data:" + rs.redisKey(key)
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) statKey(key string) string {
|
||||
return ClientName + ":stat:" + rs.redisKey(key)
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) redisKey(key string) string {
|
||||
return strings.ReplaceAll(filepath.FromSlash(key), "/", ":")
|
||||
}
|
||||
|
||||
const (
|
||||
LockDuration = time.Minute
|
||||
)
|
Loading…
Reference in New Issue