ctl

package module
v0.0.0-...-f7f3957 Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2021 License: MIT Imports: 10 Imported by: 0

README

🎛️ ctl

Quickly add dynamic configurations and control panel to your app & server.

Godoc Report Tests Coverage

Usage

By adding these:

package main

import (
	"fmt"
	"net/http"

	"github.com/avrebarra/ctl"
)

func main() {
	cpx := ctl.GetGlobal()
	
	// setting config values
	cpx.Set("flags.hello_enabled", true) // no error handling

	// setup handlers
	http.DefaultServeMux.Handle("/ctl/", ctl.MakeHandler(ctl.ConfigHandler{PathPrefix: "/ctl/", Ctl: ctl.GetGlobal()}))
	http.DefaultServeMux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		// get config value
		flaghello, _ := cpx.Get("flags.hello_enabled").Bool()
		
		// use it
		if flaghello {
			fmt.Fprintf(w, "hello\n")
			return
		}
		fmt.Fprintf(w, "sorry, no hello\n")
	})

	fmt.Println("listening http://localhost:3333...")
	http.ListenAndServe(":3333", http.DefaultServeMux)
}

You will have a dynamic configurables plus HTTP control panel:

$ curl --location --request GET 'localhost:3333/ctl/config'
{"flags.hello_enabled":"true","settings.logging_defaults":"{\"Version\":\"1.0\",\"ClusterID\":\"88888\"}","settings.logging_min_amount":"100000","settings.logging_prefix":"trx_log"}

$ curl --location --request PATCH 'localhost:3333/ctl/config/flags.hello_enabled' \
--header 'Content-Type: application/json' \
--data-raw '{
    "value": "false"
}'
{"key":"flags.transaction_logging_enabled","value":"false"}

Available endpoints:

Other Examples

Managing values via code

Note: It's recommended to specify a centralized storage. By doing so, multiple instances of same service could make use of shared/synchronized dynamic configs. You can also define your own store for db/redis/consul etc by implementing Store interface

package main

import (
	"fmt"

	"github.com/avrebarra/ctl"
)

func main() {
	// setup instance with file storage
	store, _ := ctl.NewStoreFile(ctl.ConfigStoreFile{FilePath: "fixture/store.json"})
	cpx, _ := ctl.New(ctl.Config{
		Store:       store,
		RefreshRate: 10 * time.Second, // how often to refetch data from store
	})

	// setting configurations
	cpx.Set("flags.logging_enabled", true) // no error handling
	cpx.Set("settings.logging_prefix", "trx_log")
	cpx.Set("settings.logging_defaults", DataField{Version: "1.0", ClusterID: "88888"})

	// handling for errors
	err := cpx.Set("settings.logging_min_amount", 100000).Err()
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	// getting config and assert as multiple types (boolean, float, string, object)
	flagEnableBanner, _ := cpx.Get("flags.enable_banner").Bool()
	confMinAmt, _ := cpx.Get("settings.logging_min_amount").Int()

	// binding value to object
	datafield := DataField{}
	_ = cpx.Get("settings.logging_defaults").Bind(&datafield)
}

Referencing and Refreshing Values

package main

import (
	"fmt"

	"github.com/avrebarra/ctl"
)

func main() {
	ref := ctl.GetGlobal().Get("flags.isok") // initial value: none
	fmt.Println(ref.Refresh().Bool())

	ctl.GetGlobal().Set("flags.isok", "true") // change value
	fmt.Println(ref.Refresh().Bool())

	// Output:
	// false value not found
	// true <nil>
}

Replacing the Global Singleton

By default the global instance will be generated with memstore, but you can override it using custom store and options.

package main

import (
	"fmt"

	"github.com/avrebarra/ctl"
)

func main() {
	store, _ := ctl.NewStoreFile(ctl.ConfigStoreFile{FilePath: "fixture/store.json"})
	cpx, _ := ctl.New(ctl.Config{
		Store:       store,
		RefreshRate: 10 * time.Second,
	})

	ctl.RegisterGlobal(cpx)

	flagEnableBanner, _ = ctl.GetGlobal().Get("flags.enable_banner").Bool()
	fmt.Println("values:", flagEnableBanner)
}

Milestones

  • Value.Float()
  • Ctl.Reset()
  • Ctl.Subscribe()
  • Ctl.StopSubscribe()
  • Persistence
  • Value Encryption
  • Reference values
  • REST API Handler helper for management

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MakeHandler

func MakeHandler(cfg ConfigHandler) http.Handler

func RegisterGlobal

func RegisterGlobal(c *Ctl)

Types

type Config

type Config struct {
	Store       Store
	RefreshRate time.Duration
}

type ConfigHandler

type ConfigHandler struct {
	PathPrefix string
	Ctl        *Ctl
}

type ConfigStoreFile

type ConfigStoreFile struct {
	FilePath string `validate:"required"`
}

type Ctl

type Ctl struct {
	// contains filtered or unexported fields
}

func GetGlobal

func GetGlobal() (c *Ctl)

func New

func New(cfg Config) (*Ctl, error)

func (*Ctl) Get

func (e *Ctl) Get(key string) (val Value)

func (*Ctl) List

func (e *Ctl) List() (lis map[string]string)

func (*Ctl) Set

func (e *Ctl) Set(key string, value interface{}) (val Value)

func (*Ctl) Subscribe

func (e *Ctl) Subscribe(key string, fun func(v Value)) (subid string)

type Store

type Store interface {
	Get() (s string, err error)
	Set(s string) (err error)
}

func NewStoreFile

func NewStoreFile(cfg ConfigStoreFile) (Store, error)

func NewStoreMem

func NewStoreMem() Store

type StoreFile

type StoreFile struct {
	// contains filtered or unexported fields
}

func (*StoreFile) Get

func (e *StoreFile) Get() (s string, err error)

func (*StoreFile) Set

func (e *StoreFile) Set(s string) (err error)

type StoreMem

type StoreMem struct {
	// contains filtered or unexported fields
}

func (*StoreMem) Get

func (e *StoreMem) Get() (s string, err error)

func (*StoreMem) Set

func (e *StoreMem) Set(s string) (err error)

type Value

type Value struct {
	// contains filtered or unexported fields
}

func (Value) Bind

func (v Value) Bind(target interface{}) (err error)

func (Value) Bool

func (v Value) Bool() (val bool, err error)

func (Value) Err

func (v Value) Err() (err error)

func (Value) Float

func (v Value) Float() (val float64, err error)

func (Value) Int

func (v Value) Int() (val int, err error)

func (Value) Refresh

func (v Value) Refresh() Value

func (Value) String

func (v Value) String() (val string, err error)

Jump to

Keyboard shortcuts

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