kvstore

module
v0.0.0-...-075775b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2023 License: MIT

README

kvstore

PkgGoDev

kvstore is a Key-Value store composed of two services. The services are both written in Go and integrated using gRPC.

Table of Contents

Overview

The two services are provided as static Go binaries, which take configuration via environment variables and command-line arguments/flags. The README.md for each binary details more about configuration:

Command Description
kv-api A REST API for kvstore, intended to be public-facing component
kv-grpc-server A gRPC service providing access to the backend KV storage

Each binary is also built in a multi-stage container that produces scratch images for the resulting binaries. This ensures the images are small and reduces the surface area for exploitation by including only what is needed.

Getting started

Using Docker Compose

Docker Compose allows for defining and running multi-container applications. The provided compose.yaml file is setup to build and run the two services and only requires running docker compose up:

❯ docker compose up
[+] Building 0.0s (0/0)                         docker:default
[+] Running 2/0
 ✔ Container kvstore-kv-api-1          Created            0.0s
 ✔ Container kvstore-kv-grpc-server-1  Created            0.0s
Attaching to kvstore-kv-api-1, kvstore-kv-grpc-server-1
kvstore-kv-grpc-server-1  | Running kv-grpc-server on :9090 ...
kvstore-kv-api-1          |
kvstore-kv-api-1          |    ____    __
kvstore-kv-api-1          |   / __/___/ /  ___
kvstore-kv-api-1          |  / _// __/ _ \/ _ \
kvstore-kv-api-1          | /___/\__/_//_/\___/ v4.11.2
kvstore-kv-api-1          | High performance, minimalist Go web framework
kvstore-kv-api-1          | https://echo.labstack.com
kvstore-kv-api-1          | ____________________________________O/_______
kvstore-kv-api-1          |                                     O\
kvstore-kv-api-1          | ⇨ http server started on [::]:8080

When changes are made to the source code, the images can be rebuilt using docker compose build and then re-running docker compose up

With the two containers now running, test with curl and ensure everything is working.

Building and running manually

Running make all will build static Go binaries for each of the two components and place them in the bin/ folder:

Permissions Size User  Date Modified Name
drwxr-xr-x     - chris 25 Oct 10:07  bin/
.rwxr-xr-x   18M chris 25 Oct 11:07  ├── kv-api*
.rwxr-xr-x   15M chris 25 Oct 10:07  └── kv-grpc-server*

Next start the gRPC server:

❯ bin/kv-grpc-server
Running kv-grpc-server on :9090 ...

CLI arguments/flags can be used to change the listener address, or specify TLS server authentication, although this will default to :9090 and without auth. The name of the boltdb file can also be specified, but defaults to simply data.db.

In another terminal, start the REST API:

❯ bin/kv-api --insecure

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.11.2
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:8080

The --insecure flag must be present when not using TLS authentication. This is an important safety measure to protect against accidental production configuration that excludes authentication.

Finally, make sure the services are running correctly using curl:

Testing with curl

Basic testing can be performed using curl:

❯ curl -XPOST -H 'Content-Type: application/json' localhost:8080/testkey --data-binary '{"value": "somedata"}'
{"status":"OK"}

The value that key testkey should now be set:

❯ curl localhost:8080/testkey
{"key":"testkey","value":"somedata"}

Development

New storage backends

The KV gRPC service is defined by internal/kvpb/kv.proto, which generates the KVServer interface. This interface must be fulfilled by all implementations that are to be registered with the gRPC server that hosts the KV service. The default implementation using boltdb can be found in the boltkv pacakge and can be used as an example to create new packages that fulfill the KVServer interface. This can enable the underlying storage of the KV service to be changed to use other databases/services for backend storage.

Generating protobuf

By default, gRPC using protocol buffers as an Interface Definition Language (IDL) and for message serialization, and kvstore uses the official Golang implementation of protobuf. This means that when the proto definition file(s) change, they must be regenerated.

This requires having the protocol buffer compiler (protoc) installed, and the Go-specific plugins that are needed. The Go plugins can be installed into the current Go workspace by running make generate-install (this only needs to be done once to ensure the plugins are installed). The updated files can then be generated by simply running make generate.

Running integration tests

Some basic integration/end-to-end tests can be found in test/. After all of the services are running using Docker Compose:

❯ go test -v ./test/
=== RUN   TestAPISetDeleteValue
--- PASS: TestAPISetDeleteValue (0.02s)
PASS
ok      github.com/ChrisRx/kvstore/test (cached)
TLS authentication

Any gRPC-based service deployed to production should use TLS authentication. This can be accomplished by specifying the appropriate command-line flags for the kv-api and kv-grpc-server commands, looking something like:

❯ kv-api --cert-file cert.pem --key-file key.pem --ca-file ca.pem

Directories

Path Synopsis
cmd
internal
boltkv
Package boltkv provides an implementation of the gRPC service KV using boltdb as a backend.
Package boltkv provides an implementation of the gRPC service KV using boltdb as a backend.
restapi
Package restapi provides a REST API using a gRPC client to integrate with the KV service.
Package restapi provides a REST API using a gRPC client to integrate with the KV service.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL