Skip to content

Commit a6ebdfd

Browse files
committed
docs: add README.md
Closes #31
1 parent 19f62a4 commit a6ebdfd

File tree

3 files changed

+279
-4
lines changed

3 files changed

+279
-4
lines changed
File renamed without changes.

README.md

Lines changed: 279 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,287 @@
33
[![Telegram EN][telegram-badge]][telegram-en-url]
44
[![Telegram RU][telegram-badge]][telegram-ru-url]
55

6-
<p href="http://tarantool.org">
7-
<img src="https://github.com/tarantool.png" align="right" width=250>
8-
</p>
9-
106
# go-storage: library to manage centralized configuration storages
117

8+
### About
9+
10+
<a href="http://tarantool.org">
11+
<img align="right" src="assets/logo.png" width="250" alt="Tarantool Logo">
12+
</a>
13+
14+
**go-storage** is a Go library that provides a uniform interface for managing
15+
centralized configuration storages, supporting multiple backends like etcd and
16+
Tarantool Config Storage (TCS). It offers transactional operations, conditional
17+
predicates, real-time watch, and data integrity features.
18+
19+
20+
### Overview
21+
22+
The library abstracts the complexities of different storage backends, providing
23+
a consistent API for configuration management. It is designed for distributed
24+
systems where configuration consistency, real-time updates, and transactional
25+
safety are critical.
26+
27+
### Features
28+
29+
- Unified Storage Interface: Single API for multiple backend drivers (etcd,
30+
TCS)
31+
- Transactional Operations: Atomic transactions with conditional predicates
32+
- Real-time Watch: Monitor changes to keys and prefixes
33+
- Conditional Execution: Value and version-based predicates for safe updates
34+
- Data Integrity: Built-in signing and verification of stored data
35+
- Key‑Value Operations: Get, Put, Delete with prefix support
36+
- Range Queries: Efficient scanning of keys with filters
37+
- Extensible Drivers: Easy to add new storage backends
38+
39+
### Installation
40+
41+
```bash
42+
go get github.com/tarantool/go-storage
43+
```
44+
45+
### Quick Start
46+
47+
#### Using etcd Driver
48+
49+
```go
50+
package main
51+
52+
import (
53+
"context"
54+
"log"
55+
56+
"go.etcd.io/etcd/client/v3"
57+
"github.com/tarantool/go-storage/driver/etcd"
58+
"github.com/tarantool/go-storage/operation"
59+
)
60+
61+
func main() {
62+
// Connect to etcd
63+
cli, err := clientv3.New(clientv3.Config{
64+
Endpoints: []string{"localhost:2379"},
65+
})
66+
if err != nil {
67+
log.Fatal(err)
68+
}
69+
defer cli.Close()
70+
71+
// Create etcd driver
72+
driver := etcd.New(cli)
73+
74+
// Execute a simple Put operation
75+
ctx := context.Background()
76+
_, err = driver.Execute(ctx, nil, []operation.Operation{
77+
operation.Put([]byte("/config/app/version"), []byte("1.0.0")),
78+
}, nil)
79+
if err != nil {
80+
log.Fatal(err)
81+
}
82+
}
83+
```
84+
85+
#### Using TCS Driver
86+
87+
```go
88+
package main
89+
90+
import (
91+
"context"
92+
"log"
93+
94+
"github.com/tarantool/go-tarantool/v2"
95+
"github.com/tarantool/go-storage/driver/tcs"
96+
"github.com/tarantool/go-storage/operation"
97+
)
98+
99+
func main() {
100+
// Connect to Tarantool
101+
conn, err := tarantool.Connect("localhost:3301", tarantool.Opts{})
102+
if err != nil {
103+
log.Fatal(err)
104+
}
105+
defer conn.Close()
106+
107+
// Create TCS driver
108+
driver := tcs.New(conn)
109+
110+
// Execute a transaction
111+
ctx := context.Background()
112+
resp, err := driver.Execute(ctx, nil, []operation.Operation{
113+
operation.Put([]byte("/config/app/name"), []byte("MyApp")),
114+
}, nil)
115+
if err != nil {
116+
log.Fatal(err)
117+
}
118+
log.Printf("Transaction succeeded: %v", resp.Succeeded)
119+
}
120+
```
121+
122+
### Drivers
123+
124+
#### etcd Driver
125+
The `driver/etcd` package implements the storage driver interface for etcd. It
126+
supports all etcd features including conditional transactions, leases, and
127+
watch.
128+
129+
#### TCS Driver
130+
The `driver/tcs` package provides a driver for Tarantool Config Storage (TCS),
131+
a distributed key‑value storage built on Tarantool. It offers high performance
132+
and strong consistency.
133+
134+
### API Overview
135+
136+
#### Storage Interface
137+
The core `Storage` interface (`storage.Storage`) provides high‑level methods:
138+
139+
- `Watch(ctx, key, opts) <-chan watch.Event` – watch for changes
140+
- `Tx(ctx) tx.Tx` – create a transaction builder
141+
- `Range(ctx, opts) ([]kv.KeyValue, error)` – range query with prefix/limit
142+
143+
#### Transaction Builder
144+
The `tx.Tx` interface enables conditional transactions:
145+
146+
```go
147+
resp, err := storage.Tx(ctx).
148+
If(predicate.ValueEqual(key, "old")).
149+
Then(operation.Put(key, "new")).
150+
Else(operation.Delete(key)).
151+
Commit()
152+
```
153+
154+
#### Operations
155+
The `operation` package defines `Get`, `Put`, `Delete` operations. Each
156+
operation can be configured with options.
157+
158+
#### Predicates
159+
The `predicate` package provides value and version comparisons:
160+
161+
- `ValueEqual`, `ValueNotEqual`
162+
- `VersionEqual`, `VersionNotEqual`, `VersionGreater`, `VersionLess`
163+
164+
#### Watch
165+
The `watch` package delivers real‑time change events. Watch can be set on a
166+
single key or a prefix.
167+
168+
#### Data Integrity with Typed Storage
169+
The [`integrity`](https://pkg.go.dev/github.com/tarantool/go-storage/integrity)
170+
package provides a high‑level `Typed` interface for storing and retrieving
171+
values with built‑in integrity protection. It automatically computes hashes
172+
and signatures (using configurable algorithms) and verifies them on
173+
retrieval.
174+
175+
##### Creating a Typed Storage Instance
176+
177+
```go
178+
package main
179+
180+
import (
181+
"context"
182+
"crypto/rand"
183+
"crypto/rsa"
184+
"log"
185+
186+
clientv3 "go.etcd.io/etcd/client/v3"
187+
"github.com/tarantool/go-storage"
188+
"github.com/tarantool/go-storage/driver/etcd"
189+
"github.com/tarantool/go-storage/hasher"
190+
"github.com/tarantool/go-storage/crypto"
191+
"github.com/tarantool/go-storage/integrity"
192+
)
193+
194+
func main() {
195+
// 1. Create a base storage (e.g., etcd driver)
196+
cli, err := clientv3.New(clientv3.Config{Endpoints: []string{"localhost:2379"}})
197+
if err != nil {
198+
log.Fatal(err)
199+
}
200+
defer cli.Close()
201+
202+
driver := etcd.New(cli)
203+
baseStorage := storage.NewStorage(driver)
204+
205+
// 2. Generate RSA keys (in production, load from secure storage)
206+
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
207+
if err != nil {
208+
log.Fatal(err)
209+
}
210+
211+
// 3. Build typed storage with integrity protection
212+
typed := integrity.NewTypedBuilder[MyConfig](baseStorage).
213+
WithPrefix("/config").
214+
WithHasher(hasher.NewSHA256Hasher()). // adds SHA‑256 hash verification
215+
WithSignerVerifier(crypto.NewRSAPSSSignerVerifier(*privKey)). // adds RSA‑PSS signatures
216+
Build()
217+
218+
// 4. Store a configuration object with automatic integrity data
219+
ctx := context.Background()
220+
config := MyConfig{Environment: "production", Timeout: 30}
221+
if err := typed.Put(ctx, "app/settings", config); err != nil {
222+
log.Fatal(err)
223+
}
224+
225+
// 5. Retrieve and verify integrity
226+
result, err := typed.Get(ctx, "app/settings")
227+
if err != nil {
228+
log.Fatal(err)
229+
}
230+
231+
if result.Error != nil {
232+
log.Printf("Integrity check failed: %v", result.Error)
233+
} else {
234+
cfg, _ := result.Value.Get()
235+
log.Printf("Retrieved valid config: %+v", cfg)
236+
}
237+
238+
// 6. Range over all configurations under a prefix
239+
results, err := typed.Range(ctx, "app/")
240+
if err != nil {
241+
log.Fatal(err)
242+
}
243+
for _, res := range results {
244+
log.Printf("Found config %s (valid: %v)", res.Name, res.Error == nil)
245+
}
246+
}
247+
248+
type MyConfig struct {
249+
Environment string `yaml:"environment"`
250+
Timeout int `yaml:"timeout"`
251+
}
252+
```
253+
254+
##### Key Features
255+
- Automatic Hash & Signature Generation: Values are stored together with
256+
their hashes and/or signatures.
257+
- Validation on read: `Get` and `Range` operations verify hashes and
258+
signatures; invalid data is reported.
259+
- Configurable Algorithms: Plug in any hasher (`hasher.Hasher`) and
260+
signer/verifier (`crypto.SignerVerifier`).
261+
- Prefix Isolation**: Each typed storage uses a configurable key prefix,
262+
avoiding collisions.
263+
- **Watch Support**: `Watch` method filters events for the typed namespace.
264+
265+
The `integrity.Typed` builder also accepts custom marshallers (default is
266+
YAML), custom namers, and separate signer/verifier instances for asymmetric
267+
setups.
268+
269+
### Examples
270+
271+
Comprehensive examples are available in the driver packages:
272+
273+
- **etcd examples**: [`driver/etcd/examples_test.go`](driver/etcd/examples_test.go)
274+
- **TCS examples**: [`driver/tcs/examples_test.go`](driver/tcs/examples_test.go)
275+
276+
Run them with `go test -v -run Example ./driver/etcd` or `./driver/tcs`.
277+
278+
### Contributing
279+
280+
Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md)
281+
file for guidelines (if present) or open an issue to discuss your ideas.
282+
283+
### License
284+
285+
This project is licensed under the BSD 2‑Clause License – see the [LICENSE](LICENSE) file for details.
286+
12287
[godoc-badge]: https://pkg.go.dev/badge/github.com/tarantool/go-storage.svg
13288
[godoc-url]: https://pkg.go.dev/github.com/tarantool/go-storage
14289
[coverage-badge]: https://coveralls.io/repos/github/tarantool/go-storage/badge.svg?branch=master

assets/logo.png

113 KB
Loading

0 commit comments

Comments
 (0)