Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/stripe/skycfg
Skycfg is an extension library for the Starlark language that adds support for constructing Protocol Buffer messages.
https://github.com/stripe/skycfg
Last synced: about 2 months ago
JSON representation
Skycfg is an extension library for the Starlark language that adds support for constructing Protocol Buffer messages.
- Host: GitHub
- URL: https://github.com/stripe/skycfg
- Owner: stripe
- License: apache-2.0
- Created: 2018-08-17T05:14:38.000Z (over 6 years ago)
- Default Branch: trunk
- Last Pushed: 2024-09-04T19:15:18.000Z (4 months ago)
- Last Synced: 2024-09-06T02:57:01.808Z (4 months ago)
- Language: Go
- Homepage:
- Size: 7.86 MB
- Stars: 643
- Watchers: 18
- Forks: 54
- Open Issues: 19
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Authors: AUTHORS
Awesome Lists containing this project
- awesome-starlark - Skycfg - a library for Starlark to (Libraries and extensions)
- awesome-starlark - Skycfg
README
# Skycfg
Skycfg is an extension library for the [Starlark language](https://github.com/bazelbuild/starlark) that adds support for constructing [Protocol Buffer](https://developers.google.com/protocol-buffers/) messages. It was developed by Stripe to simplify configuration of Kubernetes services, Envoy routes, Terraform resources, and other complex configuration data.
At present, only the Go implementation of Starlark is supported.
[![API Documentation](https://godoc.org/github.com/stripe/skycfg?status.svg)](https://godoc.org/github.com/stripe/skycfg)
[![Test Status](https://github.com/stripe/skycfg/workflows/Tests/badge.svg)](https://github.com/stripe/skycfg/actions)
[![Test Coverage](https://coveralls.io/repos/github/stripe/skycfg/badge.svg?branch=master)](https://coveralls.io/github/stripe/skycfg?branch=master)## Getting Started
The entry point to Skycfg is the [`skycfg.Load()`](https://godoc.org/pkg/github.com/stripe/skycfg/#Load) function, which reads a configuration file from local disk. As the implementation stabilizes we expect to expand the public API surface so that Skycfg can be combined with other Starlark extensions.
Lets start with a simple `main` function that prints out every Protobuf message created by the config file `hello.sky`:
```go
package mainimport (
"context"
"fmt"
"github.com/stripe/skycfg"
_ "github.com/golang/protobuf/ptypes/wrappers"
)func main() {
ctx := context.Background()
config, err := skycfg.Load(ctx, "hello.sky")
if err != nil { panic(err) }
messages, err := config.Main(ctx)
if err != nil { panic(err) }
for _, msg := range messages {
fmt.Printf("%s\n", msg.String())
}
}
``````python
# hello.sky
pb = proto.package("google.protobuf")def main(ctx):
return [pb.StringValue(value = "Hello, world!")]
```Now we can build a small test driver and see what values are returned:
```
$ go get github.com/stripe/skycfg
$ go build -o test-skycfg
$ ./test-skycfg
value:"Hello, world!"
$
```Success!
For more in-depth examples covering specific topics, see the `_examples/` directory:
* [`_examples/repl`](https://github.com/stripe/skycfg/tree/master/_examples/repl): Interactive evaluation of a Skycfg file
* [`_examples/k8s`](https://github.com/stripe/skycfg/tree/master/_examples/k8s): Basic Kubernetes integration
* [`_examples/wasm`](https://github.com/stripe/skycfg/tree/master/_examples/wasm): Skycfg in the browser with WebAssembly## Why use Skycfg?
Compared to bare YAML or TOML, the Python-like syntax of Skycfg might not seem like a win. Why would we want configuration files with all those quotes and colons and braces?
There are four important benefits to using Skycfg over YAML:
### Type Safety
Protobuf has a statically-typed data model, which means the type of every field is known to Skycfg when it's building your configuration. There is no risk of accidentally assigning a string to a number, a struct to a different struct, or forgetting to quote a YAML value.
```python
pb = proto.package("google.protobuf")def main(ctx):
return [pb.StringValue(value = 123)]
``````
$ ./test-skycfg
panic: TypeError: value 123 (type `int') can't be assigned to type `string'.
```### Functions
As in standard Python, you can define helper functions to reduce duplicated typing and share logic.
```python
pb = proto.package("google.protobuf")def greet(lang):
greeting = {
"en": "Hello, world!",
"fr": "Bonjour, monde!",
}[lang]
return pb.StringValue(value = greeting)def main(ctx):
return [greet("en"), greet("fr")]
```
```
$ ./test-skycfg
value:"Hello world!"
value:"Bonjour, monde!"
```### Modules
Starlark supports importing modules from other files, which you can use to share common code between configurations. By default the paths to load are resolved on the local filesystem, but you can also override the `load()` handler to support syntaxes such as [Bazel-style target labels](https://docs.bazel.build/versions/master/build-ref.html).
Modules can protect service owners from complex Kubernetes logic:
```python
load("//config/common/kubernetes.sky", "kubernetes")def my_service(ctx):
return kubernetes.pod(
name = "my-namespace/my-service",
containers = [
kubernetes.container(name = "main", image = "index.docker.io/hello-world"),
]
)
```When combined with VCS hooks like [GitHub CODEOWNERS](https://help.github.com/articles/about-codeowners/), you can use modules to provide an API surface for third-party tools deployed in your infrastructure:
```python
load("//config/common/constants.sky", "CLUSTERS")
load("//config/production/k8s_dashboard/v1.10.0/main.sky",
"kubernetes_dashboard")def main(ctx):
return [
kubernetes_dashboard(ctx, cluster = CLUSTERS['ord1']),
kubernetes_dashboard(ctx, cluster = CLUSTERS['ord1-canary']),
]
```### Context Variables
Skycfg supports limited dynamic behavior through the use of _context variables_, which let the Go caller pass arbitrary key:value pairs in the `ctx` parameter.
```go
func main() {
// ...
messages, err := config.Main(ctx, skycfg.WithVars(starlark.StringDict{
"revision": starlark.String("master/12345"),
}))
``````python
pb = proto.package("google.protobuf")def main(ctx):
print("ctx.vars:", ctx.vars)
return []
``````
$ ./test-skycfg
[hello.sky:4] ctx.vars: {"revision": "master/12345"}
```## Contributing
We welcome contributions from the community. For small simple changes, go ahead and [open a pull request](https://github.com/stripe/skycfg/compare). Larger changes should start out in the issue tracker, so we can make sure they fit into the roadmap. Changes to the Starlark language itself (such as new primitive types or syntax) should be applied to https://github.com/google/starlark-go.
## Stability
Skycfg depends on internal details of the go-protobuf generated code, and as such may need to be updated to work with future versions of go-protobuf. We will release Skycfg v1.0 after all dependencies on go-protobuf implementation details have been fixed, which will be after the "api-v2" branch lands in a stable release of go-protobuf.
Our existing public APIs are expected to be stable even before the v1.0 release. Symbols that will change before v1.0 are hidden from the public docs and named `Unstable*`.
## Known issues
### gogo/protobuf support
Skycfg has dropped support for
[gogo/protobuf](https://github.com/gogo/protobuf), an alternative protobuf go
code generator, when upgrading to using the go-protobuf v2 api. For using gogo
support, see `[email protected]` (Skycfg prior to switching to v2).