Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/errordeveloper/kubeplay
kubeplay – a new way to interact with Kubernetes API from your terminal
https://github.com/errordeveloper/kubeplay
dsl kubectl kubernetes repl ruby
Last synced: 13 days ago
JSON representation
kubeplay – a new way to interact with Kubernetes API from your terminal
- Host: GitHub
- URL: https://github.com/errordeveloper/kubeplay
- Owner: errordeveloper
- License: other
- Created: 2016-12-14T16:23:21.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-07-24T03:15:09.000Z (over 6 years ago)
- Last Synced: 2025-01-08T18:52:22.521Z (16 days ago)
- Topics: dsl, kubectl, kubernetes, repl, ruby
- Language: Go
- Homepage:
- Size: 10.9 MB
- Stars: 86
- Watchers: 4
- Forks: 8
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# `kubeplay` – a new way to interact with Kubernetes
> NOTE: _this project is still in an early stage_
> If you like this project, please checkout [TODOs](#todos) and open an issue if you'd like to contribute or discuss anything in particular.
## Usage example: easy REPL with Ruby syntax
```console
> ./kubeplay
kubeplay (namespace="*")> pods # list pods in the clusterkubeplay (namespace="*")> @pod = _.any # pick a random pod from the list
kubeplay (namespace="*")> puts @pod.to_json # output the pod definition in JSON
{
"metadata": {
...
},
"spec": {
...
"containers": [
{
...
}
],
},
"status": {
...
}
}
kubeplay (namespace="*")> puts @pod.to_ruby # output the same as a Ruby hash
{ ... }
kubeplay (namespace="*")> @pod.delete! # I am a chaos monkey :)
```## Resource Verbs
Currently implemented verbs are the following:
- `pods`
- `services`
- `replicasets`
- `daemonsets`Each of these can be used with index operator, e.g. `services[10]`, as well as `first`, `last` and `any` methonds.
Any resource object can be converted to a JSON string with `to_json` method, or a Ruby object with `to_ruby`.With a Ruby object reprsentation you can do things like this:
```ruby
@metadata = replicasets("*/").to_ruby.items.map do |k,v|
v.metadata
end@metadata.each do |i|
puts "Name:\t#{i.name}"
puts "Labels:\t#{i.labels}"
puts
end
```You can define a verb aliases with `def_alias`, e.g. to create an `rs` verb alias for `replicasets` use
```Ruby
def_alias :rs, :replicasets
```By default a verb operates on all namespaces, hence `(namespace="*")` is shown in the prompt.
You can switch current namespaces with `namespace` verb, e.g.
```console
kubeplay (namespace="*")> namespace "kube-system"
kubeplay (namespace="kube-system")>
```
To go back to all-namespaces mode, use `namespace "*"`.### Resource Arguments
A verb may take up two arguments in any order - a glob string and a block or hash.
#### TL;DR
To get all replica sets in `default` namespaces which have label `app` not matching `foo` or `bar` and label `version` matching `0.1` or `0.2` use
```ruby
replicasets "default/", labels: -> { @app !~ %w(foo bar) ; @version =~ %w(0.1 0.2) ; }
```To get all running pods with label `app` matching `foo` or `bar` use
```ruby
pods { @app =~ %w(foo bar) ; status.phase == "Running" ; }
```#### Glob Expressions
Here are some examples illustrating the types of glob expressions that `kubeplay` understands.
Get all pods in `kube-systems` namespace:
```ruby
pods "kube-system/"
```Get all pods in all namespace:
```ruby
pods "*/"
```Get all pods in current namespace with name matching `*foo*`:
```ruby
pods "*foo*"
```More specifically, this enables getting pods in a namespace other then current like this:
```console
kubeplay (namespace="default")> pods "kube-system/foo-*"
```
Or, gettin pods with name matching `"bar-*` in all namespace like this:
```console
kubeplay (namespace="default")> pods "*/bar-*"
```> NOTE: if current namespace is `"*"`, `pods "*"` is the same as `pods`; `pods "*/*"` is always the same as `pods "*/"`.
#### Label & Field Selectors
Another argument a resource verb understand is a block specifying label and field selectors using special syntax outlined below.
##### Label Selector Syntax
To match a label agains a set of values, use `label("name") =~ %w(foo bar)`, or `!~`.
If you want to just get resources with a certain label to set anything, use `label("baz").defined?`
This
```ruby
{
label("name") =~ %w(foo bar)
label("baz").defined?
}
```
will compile a selector string `name in (foo, bar),myapp`.And this
```ruby
{
label("name") !~ %w(foo bar)
label("baz").defined?
}
```
will compile a selector string `name notin (foo, bar),myapp`.Some well-known labels have shortuct, e.g.
```ruby
{
@app !~ %w(foo bar)
@version =~ %w(0.1 0.2)
@tier =~ %w(frontend backend)
}
```Simply pass a block like this:
```ruby
replicasets { @app !~ %w(foo bar); @version =~ %w(0.1 0.2); @tier =~ %w(frontend backend); }
```You can also use `make_label_selector` verb to construct these expressions and save those to variabels etc.
##### Field Selector Syntax
This syntax is different, yet somewhat simpler.
Here is a selector mathing all running pods:
```ruby
{ status.phase != :Running }
```#### Using Slectors
To get all running pods with label `tier` mathcing `backend`:
```ruby
pods { status.phase != :Running ; @tier =~ "backend" ; }
```Alternatively, if you prefer to be more explicit, you can use a hash:
```ruby
pods fields: -> { status.phase != :Running }, labels: -> { @tier =~ "backend" }
```You can also use compose selector expressions diretly as strings, if you prefer:
```ruby
pods fields: "status.phase != Running", labels: "tier in (backend)"
```### Inspecting the Logs
To get grep logs for any pod matching given selector
```ruby
pods{ @name =~ "launch-generator" ; }.any.logs.grep ".*INFO:.*", ".*user-agent:.*"
```## Usage example: object generator with minimal input
```console
> ./kubeplay -kubeconfig ~/.kube/config
kubeplay (namespace="*")> @pod = make_pod(image: "errordeveloper/foo:latest")
kubeplay (namespace="*")> puts _.to_json
{
"metadata": {
"creationTimestamp": null,
"labels": {
"name": "foo"
}
},
"spec": {
"containers": [
{
"name": "foo",
"image": "errordeveloper/foo:latest",
"resources": {}
}
]
},
"status": {}
}
kubeplay (namespace="*")> @pod.create!
kubeplay (namespace="*")> @pod.delete!kubeplay (namespace="*")> ^D
>
```### TODOs
Here are some TODO items and ideas.
- [x] `pod.delete!`
- [x] `pod.create!`
- [x] `pod.logs` & `pod.logs.grep`
- [x] `pods.logs` & `pods.logs.grep`
- [ ] `pod.logs.pager` and `pod.logs.grep.pager`
- [ ] grep logs in any set of resources
- [ ] more fluent behaviour of set resources, e.g. `replicasets.pods` and not `replicasets.any.pods`
- [ ] reverse lookup, e.g. given `@rs = replicasets.any`, `@rs.pods.any.owner` should be the same as `@rs`
- [ ] way to run scripts and not just REPL
- [ ] extend resource generator functionality
- [ ] `ReplicaSet`+`Service`
- [ ] `Kubefile` DSL#### Ideas
- simple framework for controllers and 3rd-party resource (e.g. chaos monkey of sorts, or use terraform to create an exteranl resource and store URL in a secret, custom policy controller made easy)
- multi-cluster support
- resource diff
- network policy tester framework
- eval/exec code in a pod
- test framework for apps, e.g. "Here is my app, it has a configmap and a secrete, and I want to test if it works"### Building
Get the source code and build the dependencies:
```bash
go get github.com/Masterminds/glide
go get -d github.com/errordeveloper/kubeplay
cd $GOPATH/src/github.com/errordeveloper/kubeplay
$GOPATH/bin/glide up -v
make -C vendor/github.com/mitchellh/go-mruby libmruby.a
go install ./rubykube
```Build `kubeplay`:
```bash
go build .
```### Credits
The mruby integration was inspired by [@erikh's box](https://github.com/erikh/box), and some of the code was initially copied from there.