# K8s
[K8s](https://hexdocs.pm/k8s/readme.html) - Kubernetes API Client for Elixir
[![Build Status](https://travis-ci.org/coryodaniel/k8s.svg?branch=master)](https://travis-ci.org/coryodaniel/k8s)
[![Coverage Status](https://coveralls.io/repos/github/coryodaniel/k8s/badge.svg?branch=master)](https://coveralls.io/github/coryodaniel/k8s?branch=master)
[![Hex.pm](http://img.shields.io/hexpm/v/k8s.svg?style=flat)](https://hex.pm/packages/k8s)
[![Documentation](https://img.shields.io/badge/documentation-on%20hexdocs-green.svg)](https://hexdocs.pm/k8s/)
![Hex.pm](https://img.shields.io/hexpm/l/k8s.svg?style=flat)
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `k8s` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:k8s, "~> 0.2"}
]
end
```
## Usage
Check out the [Usage Guide](https://hexdocs.pm/k8s/usage.html) for in-depth examples.
Most functions are also written using doctests.
* [K8s.Client doctests](https://hexdocs.pm/k8s/K8s.Client.html)
* [K8s.Cluster doctests](https://hexdocs.pm/k8s/K8s.Cluster.html)
* [K8s.Conf doctests](https://hexdocs.pm/k8s/K8s.Conf.html)
* [K8s.Resource doctests](https://hexdocs.pm/k8s/K8s.Resource.html)
* [K8s.Version doctests](https://hexdocs.pm/k8s/K8s.Version.html)
## Features
* A client API for humans
* Kubernetes resources, groups, and CRDs are autodiscovered at boot time. No swagger file to include or override.
* Client supports standard HTTP calls, async batches, wait on status, and watchers
* Supports multiple clusters
* Supports multiple authentication credentials
* serviceaccount
* token
* certificate
* auth-provider
* Supports multiple kubernetes API
* Tested against kubernetes swagger specs: 1.10+ and master
* CRD support
* Kubernetes resource and version helper functions
* Kube config file parsing
* Certificate and service account based auth
* Pluggable auth providers
* Macro free; fast compile & fast startup
### Non-features
* Modules for every kubernetes resource.
* Assume the "default" namespaces. Always provide a namespace when a namespace is applicable.
* Support for the deprecated Watch API.
## Docs
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/k8s](https://hexdocs.pm/k8s).
## Testing
### Adding support for a new version of kubernetes
Download the swagger spec for the new version. `k8s` doesn't use swagger to define the API, but it is used to drive property tests.
```shell
export NEW_VERSION_NUMBER=1.1n
make get/${NEW_VERSION_NUMBER}
```
```shell
make test/${NEW_VERSION_NUMBER}
```
A [mock `Discovery`](.test/support/mock/discovery.ex) module exist populated by [this JSON config](./test/support/mock/data/groups.json) to simulate runtime API discovery.
If new resources or APIs were added to kubernetes in the new version you will likely see one of these errors: `unsupported_group_version` and `unsupported_kind`.
### Unsupported Group Version errors
This error occurs when a new API is added to kubernetes.
Example: `{:error, :unsupported_group_version, "scheduling.k8s.io/v1"}`
Add the `:unsupported_group_version` to the mock configuration and rerun the test suite.
A config entry looks like:
```javascript
// ...
{
"groupVersion": "scheduling.k8s.io/v1", // add the group version name
"kind": "APIResourceList", // leave as is
"resources": [ // add a list of resources provided by the new `groupVersion`
{
"kind": "PriorityClass", // `kind` name
"name": "priorityclasses", // plural name
"namespaced": false, // namespaced or not
"singularName": "",
"verbs": [ // list of verbs supported by the new API
"create",
"delete",
"deletecollection",
"get",
"list",
"patch",
"update",
"watch"
]
}
]
},
// ...
```
### Unsupported Kind errors
This error occurs when a new resource type is added to an existing API, similar to above you will need to add the `resource` to the list of `resources`.
The following config is missing `runtimeclasses` as a resource.
```javascript
{
"groupVersion": "node.k8s.io/v1beta1",
"kind": "APIResourceList",
"resources": [
{
"kind": "Node",
"name": "nodes",
"namespaced": false,
"singularName": "",
"verbs": [
"create",
"delete",
"deletecollection",
"get",
"list",
"patch",
"update",
"watch"
]
}
]
},
```
After mocking:
```javascript
{
"groupVersion": "node.k8s.io/v1beta1",
"kind": "APIResourceList",
"resources": [
{
"kind": "Node",
"name": "nodes",
"namespaced": false,
"singularName": "",
"verbs": [
"create",
"delete",
"deletecollection",
"get",
"list",
"patch",
"update",
"watch"
]
},
{
"kind": "RuntimeClass",
"name": "runtimeclasses",
"namespaced": false,
"singularName": "",
"verbs": [
"create",
"delete",
"deletecollection",
"get",
"list",
"patch",
"update",
"watch"
]
}
]
},
```