For more information about this project, see docs.
This is a library for adding support for configuration, metrics, operations and events to any service written in the Go programming language. It supports IETF RESTCONF RFC8040 protocol so it can interoperate with other libraries and systems. Even if you do not currently use these standards, this library gives you a powerful management system based on decades of engineering.
FreeCONF plays an important role in the greater mission to browse, inspect and program every piece of running software in your entire IT infrastructure! FreeCONF uses IETF standards to support configuration, metrics, operations and events to any service written in the Go programming language.
Requires Go version 1.20 or greater.
go get -u github.com/freeconf/yang
- Never write a configuration file parser again
- Generate accurate management documentation
- Support live configuration changes such as log level
- Decouple your code from any management tool (prometheus, slack, influx)
- Support RBAC (Roll Based Access and Control) for mangagement operations without any code change
- Build web-based management interfaces without needing any extra service
- Use call-home to build, automatic inventory database
- Wrap messy integration APIs to other systems
- Track exact changes to APIs for semantic versioning
Once you get started, there are a surprising number of possibilities including non-manamgent APIs, file parsers, DB schema generation, ...
mkdir car
cd car
go mod init car
go get -u github.com/freeconf/restconf
There are some model files needed to start a web server and other basic things.
go run github.com/freeconf/yang/cmd/fc-yang get
you should now see bunch of *.yang files in the current directory. They were actually extracted from the source, not downloaded.
Use YANG to model your management API by creating the following file called car.yang
with the following contents.
module car {
description "Car goes beep beep";
revision 0;
leaf speed {
description "How fast the car goes";
type int32 {
range "0..120";
}
units milesPerSecond;
}
leaf miles {
description "How many miles has car moved";
type decimal64;
config false;
}
rpc reset {
description "Reset the odometer";
}
}
Create a go source file called main.go
with the following contents.
package main
import (
"strings"
"time"
"github.com/freeconf/restconf"
"github.com/freeconf/restconf/device"
"github.com/freeconf/yang/node"
"github.com/freeconf/yang/nodeutil"
"github.com/freeconf/yang/source"
)
// write your code to capture your domain however you want
type Car struct {
Speed int
Miles float64
}
func (c *Car) Start() {
for {
<-time.After(time.Second)
c.Miles += float64(c.Speed)
}
}
// write mangement api to bridge from YANG to code
func manage(car *Car) node.Node {
return &nodeutil.Extend{
// use reflect when possible, here we're using to get/set speed AND
// to read miles metrics.
Base: nodeutil.ReflectChild(car),
// handle action request
OnAction: func(parent node.Node, req node.ActionRequest) (node.Node, error) {
switch req.Meta.Ident() {
case "reset":
car.Miles = 0
}
return nil, nil
},
}
}
// Connect everything together into a server to start up
func main() {
// Your app
car := &Car{}
// Device can hold multiple modules, here we are only adding one
d := device.New(source.Path("."))
if err := d.Add("car", manage(car)); err != nil {
panic(err)
}
// Select wire-protocol RESTCONF to serve the device.
restconf.NewServer(d)
// apply start-up config normally stored in a config file on disk
config := `{
"fc-restconf":{"web":{"port":":8080"}},
"car":{"speed":10}
}`
if err := d.ApplyStartupConfig(strings.NewReader(config)); err != nil {
panic(err)
}
// start your app
car.Start()
}
Start your application
go run . &
You will see a warning about HTTP2, but you can ignore that. Once you install a web certificate, that will go away.
curl http://localhost:8080/restconf/data/car:
{"speed":10,"miles":450}
curl -XPUT http://localhost:8080/restconf/data/car: -d '{"speed":99}'
curl -XPOST http://localhost:8080/restconf/data/car:reset
Interop is important, include proper headers and all input and output will be in strict compliance w/RFC. Major differences is namespaced JSON and slightly different base path for RPCs. You can disallow non-compliance in API.
curl -H 'Accept:application/yang-data+json' http://localhost:8080/restconf/data/car:
{"car:speed":99,"car:miles":3626}
curl -H 'Accept:application/yang-data+json' http://localhost:8080/restconf/operations/car:reset