From dd63fb5b63785b68f93842c2c26db147bc6bb532 Mon Sep 17 00:00:00 2001 From: etrpx Date: Tue, 28 May 2024 16:26:03 +0300 Subject: [PATCH 1/8] add redis seed --- cmd/envite/environment.go | 3 + cmd/envite/redis.go | 31 +++++++++ go.mod | 16 +++-- go.sum | 39 ++++++++---- seed/redis/component.go | 131 ++++++++++++++++++++++++++++++++++++++ seed/redis/config.go | 33 ++++++++++ 6 files changed, 234 insertions(+), 19 deletions(-) create mode 100644 cmd/envite/redis.go create mode 100644 seed/redis/component.go create mode 100644 seed/redis/config.go diff --git a/cmd/envite/environment.go b/cmd/envite/environment.go index 5dfc915..4ec69f2 100644 --- a/cmd/envite/environment.go +++ b/cmd/envite/environment.go @@ -11,6 +11,7 @@ import ( "github.com/perimeterx/envite" "github.com/perimeterx/envite/docker" "github.com/perimeterx/envite/seed/mongo" + "github.com/perimeterx/envite/seed/redis" "gopkg.in/yaml.v3" "os" "regexp" @@ -69,12 +70,14 @@ type builderFunc func(data []byte, flags flagValues, envID string) (envite.Compo // each type supports additional config params as specified below: // *type: "docker component", all config params are available in docker.Config - https://github.com/PerimeterX/envite/blob/b4e9f545226c990a1025b9ca198856faff8b5eed/docker/config.go#L23 // *type: "mongo seed", all config params are available in mongo.SeedConfig - https://github.com/PerimeterX/envite/blob/b4e9f545226c990a1025b9ca198856faff8b5eed/seed/mongo/config.go#L10 +// *type: "redis seed", all config params are available in redis.SeedConfig // // a full YAML example can be found in the root README.md at // https://github.com/PerimeterX/envite/blob/main/README.md#cli-usage var mapping = map[string]builderFunc{ docker.ComponentType: buildDocker, mongo.ComponentType: buildMongoSeed, + redis.ComponentType: buildRedisSeed, } // buildComponent constructs a Component from raw YAML data. diff --git a/cmd/envite/redis.go b/cmd/envite/redis.go new file mode 100644 index 0000000..fb61ab0 --- /dev/null +++ b/cmd/envite/redis.go @@ -0,0 +1,31 @@ +// Copyright 2024 HUMAN Security. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package main + +import ( + "encoding/json" + "fmt" + "github.com/perimeterx/envite" + "github.com/perimeterx/envite/seed/redis" +) + +// buildRedisSeed is a builder function that constructs a new Redis seed component. +// It takes a byte slice of JSON data as input. +// The function attempts to parse the JSON data into a mongo.SeedConfig struct, which defines the configuration +// for a Redis seed component. If the JSON data is successfully parsed, it then uses this configuration +// to instantiate and return a new MongoDB seed component via the redis.NewSeedComponent function. +// +// Returns: +// - An envite.Component which is the redis.SeedComponent initialized with the provided configuration. +// - An error if the JSON data cannot be parsed into a redis.SeedConfig struct. +func buildRedisSeed(data []byte, _ flagValues, _ string) (envite.Component, error) { + var config redis.SeedConfig + err := json.Unmarshal(data, &config) + if err != nil { + return nil, fmt.Errorf("could not parse config: %w", err) + } + + return redis.NewSeedComponent(config), nil +} diff --git a/go.mod b/go.mod index 46f368f..b4bf102 100644 --- a/go.mod +++ b/go.mod @@ -6,19 +6,22 @@ require ( github.com/docker/docker v25.0.3+incompatible github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.5.0 + github.com/go-redis/redis/v8 v8.11.5 github.com/gorilla/mux v1.8.0 github.com/opencontainers/image-spec v1.0.2 github.com/stretchr/testify v1.8.4 go.mongodb.org/mongo-driver v1.12.1 - golang.org/x/sync v0.3.0 + golang.org/x/sync v0.7.0 gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/distribution/reference v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.1 // indirect @@ -42,12 +45,13 @@ require ( go.opentelemetry.io/otel/metric v1.23.1 // indirect go.opentelemetry.io/otel/sdk v1.23.1 // indirect go.opentelemetry.io/otel/trace v1.23.1 // indirect - golang.org/x/crypto v0.19.0 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/tools v0.20.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/go.sum b/go.sum index ece8e3a..d6f0604 100644 --- a/go.sum +++ b/go.sum @@ -3,11 +3,15 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6 github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/docker v25.0.3+incompatible h1:D5fy/lYmY7bvZa0XTZ5/UJPljor41F+vdyJG5luQLfQ= @@ -18,11 +22,14 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -43,6 +50,9 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6f github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= @@ -86,13 +96,13 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -100,14 +110,14 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -117,8 +127,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -136,8 +146,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -145,9 +155,12 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ= google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= diff --git a/seed/redis/component.go b/seed/redis/component.go new file mode 100644 index 0000000..91b8859 --- /dev/null +++ b/seed/redis/component.go @@ -0,0 +1,131 @@ +// Copyright 2024 HUMAN Security. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package redis + +import ( + "context" + "fmt" + "github.com/go-redis/redis/v8" + "github.com/perimeterx/envite" + "strconv" + "sync" + "sync/atomic" + "time" +) + +// ComponentType represents the type of the redis seed component. +const ComponentType = "redis seed" + +// SeedComponent is a component for seeding redis with data. +type SeedComponent struct { + lock sync.Mutex + config SeedConfig + status atomic.Value + writer *envite.Writer +} + +// NewSeedComponent creates a new SeedComponent instance. +func NewSeedComponent(config SeedConfig) *SeedComponent { + r := &SeedComponent{config: config} + r.status.Store(envite.ComponentStatusStopped) + return r +} + +func (r *SeedComponent) Type() string { + return ComponentType +} + +func (r *SeedComponent) AttachEnvironment(_ context.Context, _ *envite.Environment, writer *envite.Writer) error { + r.writer = writer + return nil +} + +func (r *SeedComponent) Prepare(context.Context) error { + return nil +} + +func (r *SeedComponent) Start(ctx context.Context) error { + r.lock.Lock() + defer r.lock.Unlock() + + r.status.Store(envite.ComponentStatusStarting) + + err := r.seed(ctx) + if err != nil { + r.status.Store(envite.ComponentStatusFailed) + return err + } + + r.status.Store(envite.ComponentStatusFinished) + + return nil +} + +func (r *SeedComponent) seed(ctx context.Context) error { + r.writer.WriteString("starting redis seed") + client, err := r.clientProvider() + if err != nil { + return err + } + + err = client.FlushAll(ctx).Err() + if err != nil { + return err + } + + for _, hashData := range r.config.Data { + var count int + err = client.HSet(ctx, hashData.Key, hashData.Fields).Err() + + if err != nil { + return err + } + if hashData.TTL > 0 { + err = client.Expire(ctx, hashData.Key, time.Duration(hashData.TTL)*time.Second).Err() + if err != nil { + return err + } + } + count = len(hashData.Fields) + + r.writer.WriteString(fmt.Sprintf( + "inserted %s fields to %s", + r.writer.Color.Green(strconv.Itoa(count)), + r.writer.Color.Green(hashData.Key), + )) + } + + return nil +} + +func (r *SeedComponent) clientProvider() (*redis.Client, error) { + if r.config.ClientProvider != nil { + return r.config.ClientProvider() + } + + options, err := redis.ParseURL(r.config.Address) + if err != nil { + return nil, err + } + + return redis.NewClient(options), nil +} + +func (r *SeedComponent) Stop(context.Context) error { + r.status.Store(envite.ComponentStatusStopped) + return nil +} + +func (r *SeedComponent) Cleanup(context.Context) error { + return nil +} + +func (r *SeedComponent) Status(context.Context) (envite.ComponentStatus, error) { + return r.status.Load().(envite.ComponentStatus), nil +} + +func (r *SeedComponent) Config() any { + return r.config +} diff --git a/seed/redis/config.go b/seed/redis/config.go new file mode 100644 index 0000000..7a347e9 --- /dev/null +++ b/seed/redis/config.go @@ -0,0 +1,33 @@ +// Copyright 2024 HUMAN Security. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package redis + +import "github.com/go-redis/redis/v8" + +// SeedConfig represents the configuration for the redis seed component. +type SeedConfig struct { + // Address - a valid redis server address to connect to + Address string `json:"address,omitempty"` + + // ClientProvider - can be used as an alternative to Address, provides a redis client to use. + // available only via code, not available in config files. + // if both ClientProvider and Address are provided, ClientProvider is used. + ClientProvider func() (*redis.Client, error) `json:"-"` + + // Data - a list of objects, each represents a redis key and its data + Data []*SeedData `json:"data,omitempty"` +} + +// SeedData represents data for a redis hash. +type SeedData struct { + // Key - the name of the redis key + Key string `json:"key,omitempty"` + + // Fields - a map of field names and their values to insert using the redis HSet function: + Fields []string `json:"fields,omitempty"` + + // TTL - the time to live for the key in seconds + TTL int `json:"ttl,omitempty"` +} From ffae43434f05815dd1ef7e4071e740315f3b522b Mon Sep 17 00:00:00 2001 From: etrpx Date: Wed, 29 May 2024 12:58:24 +0300 Subject: [PATCH 2/8] - fix typos --- cmd/envite/redis.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/envite/redis.go b/cmd/envite/redis.go index fb61ab0..a6f4ad0 100644 --- a/cmd/envite/redis.go +++ b/cmd/envite/redis.go @@ -13,9 +13,9 @@ import ( // buildRedisSeed is a builder function that constructs a new Redis seed component. // It takes a byte slice of JSON data as input. -// The function attempts to parse the JSON data into a mongo.SeedConfig struct, which defines the configuration +// The function attempts to parse the JSON data into a redis.SeedConfig struct, which defines the configuration // for a Redis seed component. If the JSON data is successfully parsed, it then uses this configuration -// to instantiate and return a new MongoDB seed component via the redis.NewSeedComponent function. +// to instantiate and return a new Redis seed component via the redis.NewSeedComponent function. // // Returns: // - An envite.Component which is the redis.SeedComponent initialized with the provided configuration. From 5511b7ab833e3e1903cd448c3c6acd55ca8c9c60 Mon Sep 17 00:00:00 2001 From: etrpx Date: Wed, 29 May 2024 13:02:01 +0300 Subject: [PATCH 3/8] support set hashed and non hashed entries --- seed/redis/component.go | 57 ++++++++++++++++++++++++++++++----------- seed/redis/config.go | 32 ++++++++++++++--------- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/seed/redis/component.go b/seed/redis/component.go index 91b8859..a2bd746 100644 --- a/seed/redis/component.go +++ b/seed/redis/component.go @@ -70,36 +70,63 @@ func (r *SeedComponent) seed(ctx context.Context) error { return err } - err = client.FlushAll(ctx).Err() - if err != nil { + if err = client.FlushAll(ctx).Err(); err != nil { + return err + } + + if err = r.setEntries(ctx, err, client); err != nil { return err } - for _, hashData := range r.config.Data { - var count int - err = client.HSet(ctx, hashData.Key, hashData.Fields).Err() + if err = r.HashSetEntries(ctx, err, client); err != nil { + return err + } + r.logInsertions() + + return nil +} + +func (r *SeedComponent) setEntries(ctx context.Context, err error, client *redis.Client) error { + for _, entry := range r.config.Entries { + err = client.Set(ctx, entry.Key, entry.Value, entry.TTL*time.Second).Err() + + if err != nil { + return err + } + } + return nil +} + +func (r *SeedComponent) HashSetEntries(ctx context.Context, err error, client *redis.Client) error { + for _, hEntry := range r.config.HEntries { + err = client.HSet(ctx, hEntry.Key, hEntry.Values).Err() if err != nil { return err } - if hashData.TTL > 0 { - err = client.Expire(ctx, hashData.Key, time.Duration(hashData.TTL)*time.Second).Err() + if hEntry.TTL > 0 { + err = client.Expire(ctx, hEntry.Key, hEntry.TTL*time.Second).Err() if err != nil { return err } } - count = len(hashData.Fields) - - r.writer.WriteString(fmt.Sprintf( - "inserted %s fields to %s", - r.writer.Color.Green(strconv.Itoa(count)), - r.writer.Color.Green(hashData.Key), - )) } - return nil } +func (r *SeedComponent) logInsertions() { + count := len(r.config.Entries) + hashedCount := len(r.config.HEntries) + + r.writer.WriteString(fmt.Sprintf( + "inserted %s fields to %s and %s fields to %s", + r.writer.Color.Green(strconv.Itoa(count)), + r.writer.Color.Green("Entries"), + r.writer.Color.Green(strconv.Itoa(hashedCount)), + r.writer.Color.Green("Hashed Entries"), + )) +} + func (r *SeedComponent) clientProvider() (*redis.Client, error) { if r.config.ClientProvider != nil { return r.config.ClientProvider() diff --git a/seed/redis/config.go b/seed/redis/config.go index 7a347e9..242fbc8 100644 --- a/seed/redis/config.go +++ b/seed/redis/config.go @@ -4,7 +4,10 @@ package redis -import "github.com/go-redis/redis/v8" +import ( + "github.com/go-redis/redis/v8" + "time" +) // SeedConfig represents the configuration for the redis seed component. type SeedConfig struct { @@ -16,18 +19,23 @@ type SeedConfig struct { // if both ClientProvider and Address are provided, ClientProvider is used. ClientProvider func() (*redis.Client, error) `json:"-"` - // Data - a list of objects, each represents a redis key and its data - Data []*SeedData `json:"data,omitempty"` -} + // Entries - a list of key-value pairs to set in redis + Entries []*Set `json:"entries,omitempty"` -// SeedData represents data for a redis hash. -type SeedData struct { - // Key - the name of the redis key - Key string `json:"key,omitempty"` + // HEntries - a list of key-value pairs to set in redis hashes + HEntries []*HSet `json:"hentries,omitempty"` +} - // Fields - a map of field names and their values to insert using the redis HSet function: - Fields []string `json:"fields,omitempty"` +// Set Represents a key-value pair to set in redis. +type Set struct { + Key string `json:"key,omitempty"` + Value string `json:"value"` + TTL time.Duration `json:"ttl"` +} - // TTL - the time to live for the key in seconds - TTL int `json:"ttl,omitempty"` +// HSet Represents a key-value pair to set in a redis hash. +type HSet struct { + Key string `json:"key"` + Values map[string]string `json:"values"` + TTL time.Duration `json:"ttl"` } From 38b5505f000bbef3eb3c8354f7193d91237e0e45 Mon Sep 17 00:00:00 2001 From: etrpx Date: Wed, 29 May 2024 14:16:24 +0300 Subject: [PATCH 4/8] - remote redundant use of seconds time unit - change method to private --- seed/redis/component.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/seed/redis/component.go b/seed/redis/component.go index a2bd746..e02dd54 100644 --- a/seed/redis/component.go +++ b/seed/redis/component.go @@ -12,7 +12,6 @@ import ( "strconv" "sync" "sync/atomic" - "time" ) // ComponentType represents the type of the redis seed component. @@ -78,7 +77,7 @@ func (r *SeedComponent) seed(ctx context.Context) error { return err } - if err = r.HashSetEntries(ctx, err, client); err != nil { + if err = r.hashSetEntries(ctx, err, client); err != nil { return err } r.logInsertions() @@ -88,7 +87,7 @@ func (r *SeedComponent) seed(ctx context.Context) error { func (r *SeedComponent) setEntries(ctx context.Context, err error, client *redis.Client) error { for _, entry := range r.config.Entries { - err = client.Set(ctx, entry.Key, entry.Value, entry.TTL*time.Second).Err() + err = client.Set(ctx, entry.Key, entry.Value, entry.TTL).Err() if err != nil { return err @@ -97,7 +96,7 @@ func (r *SeedComponent) setEntries(ctx context.Context, err error, client *redis return nil } -func (r *SeedComponent) HashSetEntries(ctx context.Context, err error, client *redis.Client) error { +func (r *SeedComponent) hashSetEntries(ctx context.Context, err error, client *redis.Client) error { for _, hEntry := range r.config.HEntries { err = client.HSet(ctx, hEntry.Key, hEntry.Values).Err() @@ -105,7 +104,7 @@ func (r *SeedComponent) HashSetEntries(ctx context.Context, err error, client *r return err } if hEntry.TTL > 0 { - err = client.Expire(ctx, hEntry.Key, hEntry.TTL*time.Second).Err() + err = client.Expire(ctx, hEntry.Key, hEntry.TTL).Err() if err != nil { return err } From 3b5b0a951ebadeaa53a82e9cc7147d022572bb2b Mon Sep 17 00:00:00 2001 From: etrpx Date: Wed, 29 May 2024 14:26:04 +0300 Subject: [PATCH 5/8] rename struct fields --- seed/redis/component.go | 8 ++++---- seed/redis/config.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/seed/redis/component.go b/seed/redis/component.go index e02dd54..1cdbdcb 100644 --- a/seed/redis/component.go +++ b/seed/redis/component.go @@ -86,7 +86,7 @@ func (r *SeedComponent) seed(ctx context.Context) error { } func (r *SeedComponent) setEntries(ctx context.Context, err error, client *redis.Client) error { - for _, entry := range r.config.Entries { + for _, entry := range r.config.SetEntries { err = client.Set(ctx, entry.Key, entry.Value, entry.TTL).Err() if err != nil { @@ -97,7 +97,7 @@ func (r *SeedComponent) setEntries(ctx context.Context, err error, client *redis } func (r *SeedComponent) hashSetEntries(ctx context.Context, err error, client *redis.Client) error { - for _, hEntry := range r.config.HEntries { + for _, hEntry := range r.config.HSetEntries { err = client.HSet(ctx, hEntry.Key, hEntry.Values).Err() if err != nil { @@ -114,8 +114,8 @@ func (r *SeedComponent) hashSetEntries(ctx context.Context, err error, client *r } func (r *SeedComponent) logInsertions() { - count := len(r.config.Entries) - hashedCount := len(r.config.HEntries) + count := len(r.config.SetEntries) + hashedCount := len(r.config.HSetEntries) r.writer.WriteString(fmt.Sprintf( "inserted %s fields to %s and %s fields to %s", diff --git a/seed/redis/config.go b/seed/redis/config.go index 242fbc8..f285afe 100644 --- a/seed/redis/config.go +++ b/seed/redis/config.go @@ -19,11 +19,11 @@ type SeedConfig struct { // if both ClientProvider and Address are provided, ClientProvider is used. ClientProvider func() (*redis.Client, error) `json:"-"` - // Entries - a list of key-value pairs to set in redis - Entries []*Set `json:"entries,omitempty"` + // SetEntries - a list of key-value pairs to set in redis + SetEntries []*Set `json:"entries,omitempty"` - // HEntries - a list of key-value pairs to set in redis hashes - HEntries []*HSet `json:"hentries,omitempty"` + // HSetEntries - a list of key-value pairs to set in redis hashes + HSetEntries []*HSet `json:"hentries,omitempty"` } // Set Represents a key-value pair to set in redis. From 21e4d4f067f40815c7719cd4e25a417cdc08a0c3 Mon Sep 17 00:00:00 2001 From: etrpx Date: Wed, 29 May 2024 15:11:38 +0300 Subject: [PATCH 6/8] Change seed data structure --- seed/redis/component.go | 16 ++++++++++++---- seed/redis/config.go | 11 +++++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/seed/redis/component.go b/seed/redis/component.go index 1cdbdcb..b464221 100644 --- a/seed/redis/component.go +++ b/seed/redis/component.go @@ -6,6 +6,7 @@ package redis import ( "context" + "errors" "fmt" "github.com/go-redis/redis/v8" "github.com/perimeterx/envite" @@ -62,6 +63,8 @@ func (r *SeedComponent) Start(ctx context.Context) error { return nil } +var errEmptyEntries = errors.New("no entries to seed") + func (r *SeedComponent) seed(ctx context.Context) error { r.writer.WriteString("starting redis seed") client, err := r.clientProvider() @@ -73,6 +76,11 @@ func (r *SeedComponent) seed(ctx context.Context) error { return err } + if r.config.Entries == nil || + (len(r.config.Entries.HSet) == 0 && len(r.config.Entries.Set) == 0) { + return errEmptyEntries + } + if err = r.setEntries(ctx, err, client); err != nil { return err } @@ -86,7 +94,7 @@ func (r *SeedComponent) seed(ctx context.Context) error { } func (r *SeedComponent) setEntries(ctx context.Context, err error, client *redis.Client) error { - for _, entry := range r.config.SetEntries { + for _, entry := range r.config.Entries.Set { err = client.Set(ctx, entry.Key, entry.Value, entry.TTL).Err() if err != nil { @@ -97,7 +105,7 @@ func (r *SeedComponent) setEntries(ctx context.Context, err error, client *redis } func (r *SeedComponent) hashSetEntries(ctx context.Context, err error, client *redis.Client) error { - for _, hEntry := range r.config.HSetEntries { + for _, hEntry := range r.config.Entries.HSet { err = client.HSet(ctx, hEntry.Key, hEntry.Values).Err() if err != nil { @@ -114,8 +122,8 @@ func (r *SeedComponent) hashSetEntries(ctx context.Context, err error, client *r } func (r *SeedComponent) logInsertions() { - count := len(r.config.SetEntries) - hashedCount := len(r.config.HSetEntries) + count := len(r.config.Entries.Set) + hashedCount := len(r.config.Entries.HSet) r.writer.WriteString(fmt.Sprintf( "inserted %s fields to %s and %s fields to %s", diff --git a/seed/redis/config.go b/seed/redis/config.go index f285afe..a0c1e95 100644 --- a/seed/redis/config.go +++ b/seed/redis/config.go @@ -19,11 +19,14 @@ type SeedConfig struct { // if both ClientProvider and Address are provided, ClientProvider is used. ClientProvider func() (*redis.Client, error) `json:"-"` - // SetEntries - a list of key-value pairs to set in redis - SetEntries []*Set `json:"entries,omitempty"` + // Entries - a list of entries to set in redis + Entries *Entries `json:"entries"` +} - // HSetEntries - a list of key-value pairs to set in redis hashes - HSetEntries []*HSet `json:"hentries,omitempty"` +// Entries contains a list of HSet and Set entries to set in redis. +type Entries struct { + HSet []*HSet `json:"hset,omitempty"` + Set []*Set `json:"set,omitempty"` } // Set Represents a key-value pair to set in redis. From cb163224072d7adf5b396dee92066ed9bc5dbb46 Mon Sep 17 00:00:00 2001 From: etrpx Date: Wed, 29 May 2024 15:18:10 +0300 Subject: [PATCH 7/8] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b66cac2..61ea94a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [[0.1.0](https://github.com/PerimeterX/envite/compare/v0.0.5...v0.1.0) + +### Added + +- Redis Seed functionality. + ## [[0.0.5](https://github.com/PerimeterX/envite/compare/v0.0.4...v0.0.5)] - 2024-02-25 ### Fixed From 9642a5f871681d316d58adf47683ddfa3b35db8e Mon Sep 17 00:00:00 2001 From: avivpxi <42111576+avivpxi@users.noreply.github.com> Date: Thu, 30 May 2024 10:18:48 +0300 Subject: [PATCH 8/8] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61ea94a..611b857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,25 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [[0.1.0](https://github.com/PerimeterX/envite/compare/v0.0.5...v0.1.0) +## [0.0.6](https://github.com/PerimeterX/envite/compare/v0.0.5...v0.0.6) ### Added - Redis Seed functionality. -## [[0.0.5](https://github.com/PerimeterX/envite/compare/v0.0.4...v0.0.5)] - 2024-02-25 +## [0.0.5](https://github.com/PerimeterX/envite/compare/v0.0.4...v0.0.5) - 2024-02-25 ### Fixed - Fix error parsing null configs. -## [[0.0.4](https://github.com/PerimeterX/envite/compare/v0.0.3...v0.0.4)] - 2024-02-21 +## [0.0.4](https://github.com/PerimeterX/envite/compare/v0.0.3...v0.0.4) - 2024-02-21 ### Fixed - Fix all dependency vulnerabilities. -## [[0.0.3](https://github.com/PerimeterX/envite/compare/v0.0.2...v0.0.3)] - 2024-02-17 +## [0.0.3](https://github.com/PerimeterX/envite/compare/v0.0.2...v0.0.3) - 2024-02-17 Prepare for open source.