diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index bedb968..c526800 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -17,10 +17,6 @@ steps: - "GOTOOLCHAIN=auto" - label: ":golang: go test" key: "go_test" - retry: - automatic: - - exit_status: "*" - limit: 2 cancel_on_build_failing: true plugins: - docker#v5.11.0: diff --git a/.typos.toml b/.typos.toml index 48e3b63..aa698c8 100644 --- a/.typos.toml +++ b/.typos.toml @@ -16,5 +16,5 @@ ignore-hex = true identifier-leading-digits = false locale = "en" extend-ignore-identifiers-re = [] -extend-ignore-words-re = ["(?i)requestor","(?i)encrypter","(?i)seeked"] +extend-ignore-words-re = ["(?i)requestor","(?i)encrypter","(?i)seeked","(?i)indentity"] extend-ignore-re = ["(?Rm)^.*//\\s*spellchecker:disable-line$"] \ No newline at end of file diff --git a/README.md b/README.md index db2e659..0c355a4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # utils -Utilities for working within the OpenLane ecosystem +Utilities for working within the openlane ecosystem \ No newline at end of file diff --git a/cache/client.go b/cache/client.go new file mode 100644 index 0000000..5a193d5 --- /dev/null +++ b/cache/client.go @@ -0,0 +1,89 @@ +package cache + +import ( + "context" + "time" + + "github.com/redis/go-redis/v9" +) + +// Config for the redis client used to store key-value pairs +type Config struct { + // Enabled to enable redis client in the server + Enabled bool `json:"enabled" koanf:"enabled" default:"true"` + // Address is the host:port to connect to redis + Address string `json:"address" koanf:"address" default:"localhost:6379"` + // Name of the connecting client + Name string `json:"name" koanf:"name" default:"openlane"` + // Username to connect to redis + Username string `json:"username" koanf:"username"` + // Password, must match the password specified in the server configuration + Password string `json:"password" koanf:"password"` + // DB to be selected after connecting to the server, 0 uses the default + DB int `json:"db" koanf:"db" default:"0"` + // Dial timeout for establishing new connections, defaults to 5s + DialTimeout time.Duration `json:"dialTimeout" koanf:"dialTimeout" default:"5s"` + // Timeout for socket reads. If reached, commands will fail + // with a timeout instead of blocking. Supported values: + // - `0` - default timeout (3 seconds). + // - `-1` - no timeout (block indefinitely). + // - `-2` - disables SetReadDeadline calls completely. + ReadTimeout time.Duration `json:"readTimeout" koanf:"readTimeout" default:"0"` + // Timeout for socket writes. If reached, commands will fail + // with a timeout instead of blocking. Supported values: + // - `0` - default timeout (3 seconds). + // - `-1` - no timeout (block indefinitely). + // - `-2` - disables SetWriteDeadline calls completely. + WriteTimeout time.Duration `json:"writeTimeout" koanf:"writeTimeout" default:"0"` + // MaxRetries before giving up. + // Default is 3 retries; -1 (not 0) disables retries. + MaxRetries int `json:"maxRetries" koanf:"maxRetries" default:"3"` + // MinIdleConns is useful when establishing new connection is slow. + // Default is 0. the idle connections are not closed by default. + MinIdleConns int `json:"minIdleConns" koanf:"minIdleConns" default:"0"` + // Maximum number of idle connections. + // Default is 0. the idle connections are not closed by default. + MaxIdleConns int `json:"maxIdleConns" koanf:"maxIdleConns" default:"0"` + // Maximum number of connections allocated by the pool at a given time. + // When zero, there is no limit on the number of connections in the pool. + MaxActiveConns int `json:"maxActiveConns" koanf:"maxActiveConns" default:"0"` +} + +// New returns a new redis client based on the configuration settings +func New(c Config) *redis.Client { + opts := &redis.Options{ + Addr: c.Address, + ClientName: c.Name, + DB: c.DB, + DialTimeout: c.DialTimeout, + ReadTimeout: c.ReadTimeout, + WriteTimeout: c.WriteTimeout, + MaxRetries: c.MaxRetries, + MinIdleConns: c.MinIdleConns, + MaxIdleConns: c.MaxIdleConns, + MaxActiveConns: c.MaxActiveConns, + DisableIndentity: true, + } + + if c.Username != "" { + opts.Username = c.Username + } + + if c.Password != "" { + opts.Password = c.Password + } + + return redis.NewClient(opts) +} + +// Healthcheck pings the client to check if the connection is working +func Healthcheck(c *redis.Client) func(ctx context.Context) error { + return func(ctx context.Context) error { + // check if its alive + if err := c.Ping(ctx).Err(); err != nil { + return err + } + + return nil + } +} diff --git a/cache/doc.go b/cache/doc.go new file mode 100644 index 0000000..5b4b989 --- /dev/null +++ b/cache/doc.go @@ -0,0 +1,2 @@ +// Package cache holds the library for interacting with redis +package cache diff --git a/emails/templates.go b/emails/templates.go index c873746..2444143 100644 --- a/emails/templates.go +++ b/emails/templates.go @@ -65,12 +65,12 @@ type ResetSuccessData struct { // Email subject lines const ( - WelcomeRE = "Welcome to TheOpenLane!" - VerifyEmailRE = "Please verify your email address to login to TheOpenLane" - InviteRE = "Join Your Teammate %s on TheOpenLane!" - PasswordResetRequestRE = "TheOpenLane Password Reset - Action Required" - PasswordResetSuccessRE = "TheOpenLane Password Reset Confirmation" - InviteBeenAccepted = "You've been added to an Organization on TheOpenLane" + WelcomeRE = "Welcome to openlane!" + VerifyEmailRE = "Please verify your email address to login to openlane" + InviteRE = "Join Your Teammate %s on openlane!" + PasswordResetRequestRE = "Openlane Password Reset - Action Required" + PasswordResetSuccessRE = "Openlane Password Reset Confirmation" + InviteBeenAccepted = "You've been added to an Organization on openlane" Subscribed = "You've been subscribed to %s" ) diff --git a/go.mod b/go.mod index 2eaf4c5..1db3f32 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/mattn/go-sqlite3 v1.14.22 github.com/oklog/ulid/v2 v2.1.0 github.com/olekukonko/tablewriter v0.0.5 + github.com/redis/go-redis/v9 v9.6.1 github.com/sendgrid/rest v2.6.9+incompatible github.com/sendgrid/sendgrid-go v3.16.0+incompatible github.com/stretchr/testify v1.9.0 @@ -17,10 +18,12 @@ require ( ) require ( + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.7 // indirect - golang.org/x/sys v0.24.0 // indirect + golang.org/x/sys v0.23.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2df7c6e..eebaeb5 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,17 @@ github.com/brianvoe/gofakeit/v7 v7.0.4 h1:Mkxwz9jYg8Ad8NvT9HA27pCMZGFQo08MK6jD0QTKEww= github.com/brianvoe/gofakeit/v7 v7.0.4/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/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/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= @@ -16,6 +24,8 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -31,8 +41,8 @@ golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=