In this version of, Bonny comes with slightly a new concept. In this version you have to define an operator and add it to your application's supervision tree. Also, the processing of events are done in a Plug-like pipeline leveraging the Pluggable
library. This makes controllers easeir to test but also easier to customize. See for yourself.
The probably easiest way is to start with a plain Elixir project and set up your
operator using mix bonny.init
. Since you already know what resources and
controllers you need, this will initiate your operator, CRDs, versions and
controllers for you.
You just have to copy your controller implementation over to the generated
controllers and bring it into a Pluggable
form.
Create a new module (e.g. YourProject.Operator
) which uses use Bonny.Operator
,
implement crds/0
and controllers/2
according to the Operator Guide
and add it to your supervision tree.
For each custom resource your operator defines and each version the resource supports, create the corresponding module:
# lib/your_operator/api/v1/cron_tab.ex
defmodule YourOperator.API.V1.CronTab do
use Bonny.API.Version
@impl Bonny.API.Version
def manifest(), do: struct!(defaults(), storage: true)
end
# lib/your_operator/api/v1alpha1/cron_tab.ex
defmodule YourOperator.API.V1Alpha1.CronTab do
use Bonny.API.Version
@impl Bonny.API.Version
def manifest(), do: defaults()
end
Note that one and only one version of the same custom resource has to be flagged with storage: true
.
Additional printer columns belong to CRD API versions, not to controllers. Therefore, if your
controller defined additional printer columns, move those over to the version you just created.
Modify manifest/0
for this purpose.
# lib/your_operator/api/v1/cron_tab.ex
defmodule YourOperator.API.V1Alpha1.CronTab do
use Bonny.API.Version
@impl Bonny.API.Version
def manifest() do
struct!(
defaults(),
additionalPrinterColumns: [
%{name: "foos", type: :integer, description: "Number of foos", jsonPath: ".spec.foos"}
]
)
end
end
Also see the Controllers Guide
- Change
use Bonny.Controller
touse Bonny.ControllerV2
- If you have defined additional RBAC rules via
@rule {apiGroup, resources_list, verbs_list}
, implement therbac_rules/0
. - If you have defined custom names via
@names %{...}
, the resource scope (e.g.@scope :cluster
) or an API group (e.g.@group "example.com"
), add these values to the CRD in your Operator (see above) - Bring your controller to a
Pluggable
form. See the Controllers Guide
After having migrated all controllers, re-generate your manifest using mix bonny.gen.manifest
.
Version 0.5 comes with some major changes. Please read through this migration guide before upgrading.
With version 0.5, bonny moved Elixir support from ~> 1.9 to ~> 1.10.
The dependency on :k8s
was upgraded from ~> 0.4.0
to ~> 1.1
. With version 1.0
,
:k8s
brought some major changes. Mainly the way the connection to the cluster
is configured. While pre 1.0
, connections were configured in config.exs
, in 1.0
upwards, they had to created and passed to the client by the caller. This change
affects :bonny
, too.
Starting with version 0.5
, you no longer have to configure :k8s
. This means
you can remove this block completely as it has no effect:
config :k8s,
clusters: ...
With 0.5
, :bonny
however has to be configured with a new option :get_conn
. The value of
this configuration option is supposed to be an MFA tuple that tells bonny how to get
the connection struct. The function is called by bonny and is expected to return
either {:ok, K8s.Conn.t()}
or a K8s.Conn.t()
directly.
config :bonny,
get_conn: {MyModule, :get_the_connection},
You can use helpers defined in :k8s
to get the connection:
config :bonny,
get_conn: {K8s.Conn, :from_file, ["~/.kube/config", [context: "optional-alternate-context"]]},
or, when configuring bonny to run in your cluster:
config :bonny,
get_conn: {K8s.Conn, :from_service_account, []}