vconf

package module
v0.0.0-...-0d6e96b Latest Latest
Warning

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

Go to latest
Published: Jan 25, 2019 License: MIT Imports: 4 Imported by: 16

README

VConf GoDoc

This Go library is aimed to simplify working with versioned configs and metadata.

VConf isn't bounded to a specific configuration/metadata format. Instead, it expects that your application converts a string to an object. VConf just provides a standard way to organize your code and orchestrates the process.

VConf supports two formats of versioning: Semantic and Kubernetes.

Brief description of the workflow

  1. You create a package for your config/metadata and a subpackage for each version.
  2. Each such version must implement ConfigInterface interface.
  3. ConfigInterface interface requires Upgrade method which implements upgrade up to the next version.
  4. After all versions are implemented and registered, you are able to provide any version of your config/metadata and will receive the latest object as an output.

Example

You can find a working example at test subfolder. I'll describe here only the key points.

Versions

  • Every version is located in its own subpackage:
yourconfig/latest/
...
yourconfig/v1alpha1/
yourconfig/v1alpha2/
yourconfig/v1beta1/
yourconfig/yourconfig.go
  • Every version Implements ConfigInterface:
type ConfigInterface interface {
  GetVersion() string
  Parse([]byte) error
  Upgrade() (ConfigInterface, error)
}
  • Upgrade method creates an item of the next version and thus implements upgrade:
const Version string = "v1alpha1"

type Config struct {
  Version string `json:"version"`
  FieldA  string `json:"fieldA"`
  FieldB  string `json:"fieldB"`
}

func NewConfig() vconf.ConfigInterface {
  return new(Config)
}

func (c *Config) GetVersion() string {
  return c.Version
}

func (c *Config) Parse(data []byte) error {
  if err := json.Unmarshal(data, c); err != nil {
    return err
  }

  return nil
}

func (c *Config) Upgrade() (vconf.ConfigInterface, error) {
  return &next.Config{
    Version: next.Version,
    Fa: c.FieldA,
    Fb: c.FieldB,
  }, nil
}

Main package

  • Taking into account that VConf doesn't implement any specific format, it's your responsibility to extract a version of the inbound document. GetCurrentVersion function shows how it can be done for JSON format. For YAML it will be pretty much the same.
func GetCurrentVersion(data []byte) (string, error) {
  type VersionStruct struct {
    Version string `json:"version"`
  }
  version := &VersionStruct{}
  if err := json.Unmarshal(data, version); err != nil {
    return "", errors.Wrap(err, "parsing api version")
  }
  return version.Version, nil
}
  • Next you create a new instance of vconf.SchemaHandler (using vconf.NewSchemaHandler function)
sh := vconf.NewSchemaHandler(latest.Version)
  • All available versions have to be registered at the SchemaHandler using RegVersion method. It's handy to manage this list at the top of the package, next to the global constants and variables
var schemaVersions = map[string]func() vconf.ConfigInterface{
  latest.Version: latest.NewConfig,
  v1beta1.Version: v1beta1.NewConfig,
  v1alpha2.Version: v1alpha2.NewConfig,
  v1alpha1.Version: v1alpha1.NewConfig,
}

and later to register these versions after the SchemaHandler instance is created:

  for k, v := range schemaVersions {
    sh.RegVersion(k, v)
  }
  • Now you are ready to run GetLatestConfig method. It expects current version and the initial document as arguments and retures an object which represents the latest version of your config.
  cfg, err := sh.GetLatestConfig(current, []byte(suite))
  if err != nil {
    return err
  }
  • GetLatestConfig return a vconf.ConfigInterface, so a very last step is to convert the received object to the latest struct type:
parsedCfg := cfg.(*latest.Config)

If you need additional fields or methods for the config entity, you can create a new structure at the top level of your config package:

type LatestConfig struct {
  Data *latest.Config
  ExtraField1 string
  ...
}
...
  parsedCfg := cfg.(*latest.Config)
  &LatestConfig {
    Data: *parsedCfg,
    ExtraField1: "...",
  }
...
func (c *LatestConfig) DoSomething {
  ...
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ConfigInterface

type ConfigInterface interface {
	GetVersion() string
	Parse([]byte) error
	Upgrade() (ConfigInterface, error)
}

ConfigInterface defines interface for config version Every single config version must implement this interface

type SchemaHandler

type SchemaHandler struct {
	LatestVersion  string
	SchemaVersions map[string]func() ConfigInterface
}

SchemaHandler is a management interface for the whole versioned config

func NewSchemaHandler

func NewSchemaHandler(latest string) *SchemaHandler

NewSchemaHandler creates a new instance of a SchemaHandler

func (*SchemaHandler) GetLatestConfig

func (sh *SchemaHandler) GetLatestConfig(configVersion string, body []byte) (ConfigInterface, error)

GetLatestConfig is trying to find config version at the SchemaVersions map and to upgrade the given config up to the latest version.

func (*SchemaHandler) RegVersion

func (sh *SchemaHandler) RegVersion(version string, handler func() ConfigInterface)

RegVersion adds a version of your config to the SchemaVersions map. All available versions must be registered using this method. Order doesn't matter.

Directories

Path Synopsis
test

Jump to

Keyboard shortcuts

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