storage

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 3, 2026 License: BSD-2-Clause Imports: 11 Imported by: 0

README

Go Reference Code Coverage Telegram EN Telegram RU

go-storage: library to manage centralized configuration storages

About
Tarantool Logo

go-storage is a Go library that provides a uniform interface for managing centralized configuration storages, supporting multiple backends like etcd and Tarantool Config Storage (TCS). It offers transactional operations, conditional predicates, real-time watch, and data integrity features.

Overview

The library abstracts the complexities of different storage backends, providing a consistent API for configuration management. It is designed for distributed systems where configuration consistency, real-time updates, and transactional safety are critical.

Features
  • Unified Storage Interface: Single API for multiple backend drivers (etcd, TCS)
  • Transactional Operations: Atomic transactions with conditional predicates
  • Real-time Watch: Monitor changes to keys and prefixes
  • Conditional Execution: Value and version-based predicates for safe updates
  • Data Integrity: Built-in signing and verification of stored data
  • Key‑Value Operations: Get, Put, Delete with prefix support
  • Range Queries: Efficient scanning of keys with filters
  • Extensible Drivers: Easy to add new storage backends
Installation
go get github.com/tarantool/go-storage
Quick Start
Using etcd Driver
package main

import (
    "context"
    "log"

    "go.etcd.io/etcd/client/v3"
    "github.com/tarantool/go-storage/driver/etcd"
    "github.com/tarantool/go-storage/operation"
)

func main() {
    // Connect to etcd.
    cli, err := clientv3.New(clientv3.Config{
        Endpoints: []string{"localhost:2379"},
    })
    if err != nil {
        log.Fatal(err)
    }
    defer cli.Close()

    // Create etcd driver.
    driver := etcd.New(cli)

    // Execute a simple Put operation.
    ctx := context.Background()
    _, err = driver.Execute(ctx, nil, []operation.Operation{
        operation.Put([]byte("/config/app/version"), []byte("1.0.0")),
    }, nil)
    if err != nil {
        log.Fatal(err)
    }
}
Using TCS Driver
package main

import (
    "context"
    "log"

    "github.com/tarantool/go-tarantool/v2"
    "github.com/tarantool/go-storage/driver/tcs"
    "github.com/tarantool/go-storage/operation"
)

func main() {
    // Connect to Tarantool.
    conn, err := tarantool.Connect("localhost:3301", tarantool.Opts{})
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    // Create TCS driver.
    driver := tcs.New(conn)

    // Execute a transaction.
    ctx := context.Background()
    resp, err := driver.Execute(ctx, nil, []operation.Operation{
        operation.Put([]byte("/config/app/name"), []byte("MyApp")),
    }, nil)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Transaction succeeded: %v", resp.Succeeded)
}
Drivers
etcd Driver

The driver/etcd package implements the storage driver interface for etcd. It supports all etcd features including conditional transactions, leases, and watch.

TCS Driver

The driver/tcs package provides a driver for Tarantool Config Storage (TCS), a distributed key‑value storage built on Tarantool. It offers high performance and strong consistency.

API Overview
Storage Interface

The core Storage interface (storage.Storage) provides high‑level methods:

  • Watch(ctx, key, opts) <-chan watch.Event – watch for changes
  • Tx(ctx) tx.Tx – create a transaction builder
  • Range(ctx, opts) ([]kv.KeyValue, error) – range query with prefix/limit
Transaction Builder

The tx.Tx interface enables conditional transactions:

resp, err := storage.Tx(ctx).
    If(predicate.ValueEqual(key, "old")).
    Then(operation.Put(key, "new")).
    Else(operation.Delete(key)).
    Commit()
Operations

The operation package defines Get, Put, Delete operations. Each operation can be configured with options.

Predicates

The predicate package provides value and version comparisons:

  • ValueEqual, ValueNotEqual
  • VersionEqual, VersionNotEqual, VersionGreater, VersionLess
Watch

The watch package delivers real‑time change events. Watch can be set on a single key or a prefix.

Data Integrity with Typed Storage

The integrity package provides a high‑level Typed interface for storing and retrieving values with built‑in integrity protection. It automatically computes hashes and signatures (using configurable algorithms) and verifies them on retrieval.

Creating a Typed Storage Instance
package main

import (
    "context"
    "crypto/rand"
    "crypto/rsa"
    "log"

    clientv3 "go.etcd.io/etcd/client/v3"
    "github.com/tarantool/go-storage"
    "github.com/tarantool/go-storage/driver/etcd"
    "github.com/tarantool/go-storage/hasher"
    "github.com/tarantool/go-storage/crypto"
    "github.com/tarantool/go-storage/integrity"
)

func main() {
    // 1. Create a base storage (e.g., etcd driver).
    cli, err := clientv3.New(clientv3.Config{Endpoints: []string{"localhost:2379"}})
    if err != nil {
        log.Fatal(err)
    }
    defer cli.Close()

    driver := etcd.New(cli)
    baseStorage := storage.NewStorage(driver)

    // 2. Generate RSA keys (in production, load from secure storage).
    privKey, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        log.Fatal(err)
    }

    // 3. Build typed storage with integrity protection.
    typed := integrity.NewTypedBuilder[MyConfig](baseStorage).
        WithPrefix("/config").
        WithHasher(hasher.NewSHA256Hasher()).          // adds SHA‑256 hash verification.
        WithSignerVerifier(crypto.NewRSAPSSSignerVerifier(*privKey)). // adds RSA‑PSS signatures.
        Build()

    ctx := context.Background()

    // 4. Store a configuration object with automatic integrity data.
    config := MyConfig{Environment: "production", Timeout: 30}
    if err := typed.Put(ctx, "app/settings", config); err != nil {
        log.Fatal(err)
    }

    // 4.5 Store an object using predicates.
    p, _ := typed.ValueEqual(config)

    if err := typed.Put(ctx,
        "app/settings",
        config,
        integrity.WithPutPredicates(p),
    ); err != nil {
        log.Fatal(err)
    }

    // 5. Retrieve and verify integrity.
    result, err := typed.Get(ctx, "app/settings")
    if err != nil {
        log.Fatal(err)
    }

    if result.Error != nil {
        log.Printf("Integrity check failed: %v", result.Error)
    } else {
        cfg, _ := result.Value.Get()
        log.Printf("Retrieved valid config: %+v", cfg)
    }

    // 6. Range over all configurations under a prefix.
    results, err := typed.Range(ctx, "app/")
    if err != nil {
        log.Fatal(err)
    }
    for _, res := range results {
        log.Printf("Found config %s (valid: %v)", res.Name, res.Error == nil)
    }
}

type MyConfig struct {
    Environment string `yaml:"environment"`
    Timeout     int    `yaml:"timeout"`
}
Key Features
  • Automatic Hash & Signature Generation: Values are stored together with their hashes and/or signatures.
  • Validation on read: Get and Range operations verify hashes and signatures; invalid data is reported.
  • Configurable Algorithms: Plug in any hasher (hasher.Hasher) and signer/verifier (crypto.SignerVerifier).
  • Prefix Isolation: Each typed storage uses a configurable key prefix, avoiding collisions.
  • Watch Support: Watch method filters events for the typed namespace.

The integrity.Typed builder also accepts custom marshallers (default is YAML), custom namers, and separate signer/verifier instances for asymmetric setups.

Examples

Comprehensive examples are available in the driver packages:

Run them with go test -v -run Example ./driver/etcd or ./driver/tcs.

Contributing

Contributions are welcome! Please see the CONTRIBUTING.md file for guidelines (if present) or open an issue to discuss your ideas.

License

This project is licensed under the BSD 2‑Clause License – see the LICENSE file for details.

Documentation

Overview

Package storage provides a uniform way to handle various types of centralized config storages for Tarantool.

See the github.com/tarantool/go-storage/integrity package for high-level typed storage with automatic hash and signature verification.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option func(*storageOptions)

Option is a function that configures storage options.

func WithRetry

func WithRetry() Option

WithRetry configures retry behavior for failed operations. This is a dummy option for demonstration purposes.

func WithTimeout

func WithTimeout() Option

WithTimeout configures a default timeout for storage operations. This is a dummy option for demonstration purposes.

type RangeOption

type RangeOption func(*rangeOptions)

RangeOption is a function that configures range operation options.

func WithLimit

func WithLimit(limit int) RangeOption

WithLimit configures a range operation to limit the number of results returned.

func WithPrefix

func WithPrefix(prefix string) RangeOption

WithPrefix configures a range operation to filter keys by the specified prefix.

type Storage

type Storage interface {
	// Watch streams changes for a specific key or prefix.
	// Options:
	//   - WithPrefix: watch for changes on keys with the specified prefix
	Watch(ctx context.Context, key []byte, opts ...watch.Option) <-chan watch.Event

	// Tx creates a new transaction.
	// The context manages timeouts and cancellation for the transaction.
	Tx(ctx context.Context) txPkg.Tx

	// Range queries a range of keys with optional filtering.
	// Options:
	//   - WithPrefix: filter keys by prefix
	//   - WithLimit: limit the number of results returned
	Range(ctx context.Context, opts ...RangeOption) ([]kv.KeyValue, error)
}

Storage is the main interface for key-value storage operations. It provides methods for watching changes, transaction management, and range queries.

func NewStorage

func NewStorage(driver driver.Driver, _ ...Option) Storage

NewStorage creates a new Storage instance with the specified driver. Optional StorageOption parameters can be provided to configure the storage.

Directories

Path Synopsis
Package crypto implements verification interfaces.
Package crypto implements verification interfaces.
Package driver defines the interface for storage driver implementations.
Package driver defines the interface for storage driver implementations.
dummy
Package dummy provides a base in-memory implementation of the storage driver interface for demonstration and tests.
Package dummy provides a base in-memory implementation of the storage driver interface for demonstration and tests.
etcd
Package etcd provides an etcd implementation of the storage driver interface.
Package etcd provides an etcd implementation of the storage driver interface.
tcs
Package tcs provides a Tarantool config storage driver implementation.
Package tcs provides a Tarantool config storage driver implementation.
Package hasher provides types and interfaces for hash calculating.
Package hasher provides types and interfaces for hash calculating.
Package integrity provides typed storage with built-in data integrity protection.
Package integrity provides typed storage with built-in data integrity protection.
internal
mocks
Package mocks provides generated mock implementations for testing.
Package mocks provides generated mock implementations for testing.
testing
Package testing provides a mock implementation of the tarantool.Doer and other interfaces.
Package testing provides a mock implementation of the tarantool.Doer and other interfaces.
Package kv provides key-value data structures and interfaces for storage operations.
Package kv provides key-value data structures and interfaces for storage operations.
Package namer represent interface to templates creation.
Package namer represent interface to templates creation.
Package operation provides types and interfaces for storage operations.
Package operation provides types and interfaces for storage operations.
Package predicate provides types and interfaces for conditional operations.
Package predicate provides types and interfaces for conditional operations.
Package tx provides transactional interfaces for atomic storage operations.
Package tx provides transactional interfaces for atomic storage operations.
Package watch provides change notification functionality for storage operations.
Package watch provides change notification functionality for storage operations.

Jump to

Keyboard shortcuts

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