diff --git a/Makefile b/Makefile index 48969bc158c3b57592b29650bf89cc967900ef14..2e33b0a1870c9056dcdc66f332d8485ece261526 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ GO = go GO_FLAGS = -ldflags="-X main.version=$(VERSION) $(GO_LDFLAGS)" GOFMT = gofmt +JSONNET_FILES = lib/kubecfg_test.jsonnet examples/guestbook.jsonnet # TODO: Simplify this once ./... ignores ./vendor GO_PACKAGES = ./cmd/... ./utils/... @@ -17,8 +18,9 @@ test: gotest jsonnettest gotest: $(GO) test $(GO_FLAGS) $(GO_PACKAGES) -jsonnettest: kubecfg lib/kubecfg_test.jsonnet - ./kubecfg -J lib show lib/kubecfg_test.jsonnet +jsonnettest: kubecfg $(JSONNET_FILES) +# TODO: use `kubecfg check` once implemented + ./kubecfg -J lib show $(JSONNET_FILES) >/dev/null vet: $(GO) vet $(GO_FLAGS) $(GO_PACKAGES) diff --git a/README.md b/README.md index bd5edf91a987ff9d2d1befe2e8d71c7bc264b505..a7459007d6adaf3d19f9e8f880bf892e7f5734dc 100644 --- a/README.md +++ b/README.md @@ -37,25 +37,26 @@ avoid an immediate `Killed: 9`. ## Quickstart ```console -# This example uses ksonnet-lib -% git clone https://github.com/ksonnet/ksonnet-lib.git - -# Set kubecfg/jsonnet library search path. Can also use `-J` args everywhere. -% export KUBECFG_JPATH=$PWD/ksonnet-lib - -# Hello-world ksonnet-lib example -% cd ksonnet-lib/examples/readme +# Include <kubecfg.git>/lib in kubecfg/jsonnet library search path. +# Can also use explicit `-J` args everywhere. +% export KUBECFG_JPATH=/path/to/kubecfg/lib # Show generated YAML -% kubecfg show -o yaml hello-nginx.jsonnet +% kubecfg show -o yaml examples/guestbook.jsonnet # Create resources -% kubecfg update hello-nginx.jsonnet +% kubecfg update examples/guestbook.jsonnet + +# Modify configuration (downgrade gb-frontend image) +% sed -i.bak '\,gcr.io/google-samples/gb-frontend,s/:v4/:v3/' examples/guestbook.jsonnet +# See differences vs server +% kubecfg diff examples/guestbook.jsonnet -# Modify configuration -% sed -ie 's/nginx:1.7.9/nginx:1.13.0/' hello-nginx.jsonnet # Update to new config -% kubecfg update hello-nginx.jsonnet +% kubecfg update examples/guestbook.jsonnet + +# Clean up after demo +% kubecfg delete examples/guestbook.jsonnet ``` ## Features diff --git a/examples/example.libsonnet b/examples/example.libsonnet new file mode 100644 index 0000000000000000000000000000000000000000..2a02f3bcf29cbdc3a1580d04cbe5ec5c39bdff02 --- /dev/null +++ b/examples/example.libsonnet @@ -0,0 +1,52 @@ +// This library is intended to support kubecfg examples, and should +// not necessarily be considered recommended jsonnet structure. + +local kubecfg = import "kubecfg.libsonnet"; + +{ + service(name):: { + local this = self, + + apiVersion: "v1", + kind: "Service", + metadata: { + name: name, + labels: { name: name }, + }, + + targetPod_:: error "targetPod_ required in this usage", + spec: { + ports: [{port: p.containerPort} + for p in this.targetPod_.spec.containers[0].ports], + selector: this.targetPod_.metadata.labels, + }}, + + container(name, image):: { + local this = self, + + name: name, + image: kubecfg.resolveImage(image), + + env_:: {}, // key/value version of `env` (hidden) + env: [{name: k, value: this.env_[k]} for k in std.objectFields(this.env_)], + + ports: [], + }, + + deployment(name):: { + local this = self, + + apiVersion: "extensions/v1beta1", + kind: "Deployment", + metadata: { + name: name, + labels: { name: name }, + }, + spec: { + replicas: 1, + template: { + metadata: { labels: this.metadata.labels }, + spec: { + containers: [] + }}}}, +} diff --git a/examples/guestbook.jsonnet b/examples/guestbook.jsonnet new file mode 100644 index 0000000000000000000000000000000000000000..94d7dad2eb84d497bee5377b066a1831312eff41 --- /dev/null +++ b/examples/guestbook.jsonnet @@ -0,0 +1,81 @@ +// Simple self-contained example to demonstrate kubecfg. +// This should not necessarily be considered a model jsonnet example +// to build upon. + +// This is a simple port to jsonnet of the standard guestbook example +// https://github.com/kubernetes/kubernetes/tree/master/examples/guestbook +// +// Expects to be run with ../lib in the jsonnet search path: +// ``` +// export KUBECFG_JPATH=$PWD/../lib +// kubecfg update guestbook.jsonnet +// # poke at $(minikube service --url frontend), etc +// kubecfg delete guestbook.jsonnet +// ``` + +local example = import "example.libsonnet"; + +{ + frontend_deployment: example.deployment("frontend") { + spec+: { + replicas: 3, + template+: { + spec+: { + containers: [ + example.container( + "php-redis", "gcr.io/google-samples/gb-frontend:v4" + ) { + resources: { + requests: { cpu: "100m", memory: "100Mi" }, + }, + env_: { + GET_HOSTS_FROM: "dns", + }, + ports: [{containerPort: 80}], + }]}}}}, + + frontend_service: example.service("frontend") { + targetPod_: $.frontend_deployment.spec.template, + spec+: { type: "LoadBalancer" }, + }, + + redis_master_deployment: example.deployment("redis-master") { + spec+: { + template+: { + spec+: { + containers: [ + example.container( + "master", "gcr.io/google_containers/redis:e2e" + ) { + resources: { + requests: { cpu: "100m", memory: "100Mi" }, + }, + ports: [{containerPort: 6379}], + }]}}}}, + + redis_master_service: example.service("redis-master") { + targetPod_: $.redis_master_deployment.spec.template, + }, + + redis_slave_deployment: example.deployment("redis-slave") { + spec+: { + replicas: 2, + template+: { + spec+: { + containers: [ + example.container( + "slave", "gcr.io/google_samples/gb-redisslave:v1" + ) { + resources: { + requests: { cpu: "100m", memory: "100Mi" }, + }, + env_: { + GET_HOSTS_FROM: "dns", + }, + ports: [{containerPort: 6379}], + }]}}}}, + + redis_slave_service: example.service("redis-slave") { + targetPod_: $.redis_slave_deployment.spec.template, + }, +}