View Source Bonny.ControllerV2 behaviour (bonny v1.4.0)

Controllers handle action events observed by a resource watch query. Controllers must be registered at the operator together with the resource watch query. The operator will then delegate events observed by that query for processing to this controller

Controllers use the Pluggable.StepBuilder to build a step in the processing pipeline. In order to use it, a step has to be defined and implemented in the controller. The step must have the following spec

step_name(Bonny.Axn.t(), keyword()) :: Bonny.Axn.t()

The modules Bonny.Axn module is imported to your controller. In your event handler step you should use the functions Bonny.Axn.register_descendant/3, Bonny.Axn.update_status/2 and the ones to register events: Bonny.Axn.success_event/2, Bonny.Axn.failure_event/2 and/or Bonny.Axn.register_event/6. Note that these functions raise exceptions if those resources have already been applied to the cluster.

Example

Match against the struct's :action field which is one of :add, :modify, :reconcile or :delete to provide an implementation for each case.

defmodule MyOperator.Controller.CronTabController do

  # other steps
  step :handle_event
  # other steps

  # apply the resource
  def handle_event(%Bonny.Axn{action: action, resource: resource} = axn, _opts)
      when action in [:add, :modify, :reconcile] do
    success_event(axn)
  end

  def handle_event(%Bonny.Axn{action: :delete, resource: resource} = axn, _opts) do
    #
    axn
  end
end

Registering your descendants with the %Bonny.Axn{} token makes your controller easier to test. Be sure to add Bonny.Pluggable.ApplyDescendants as step to your operator in order for the descendants to be applied to the cluster.

defmodule MyOperator.Controller.CronTabController do

  # other steps
  step :handle_event
  # other steps

  # apply the resource
  def handle_event(axn, _opts) do
    deployment = generate_deployment(axn.resource)

    axn
    |> register_descendant(deployment)
    |> success_event()
  end
end

Use Bonny.Axn.update_status/2 to store API responses or other status data in the resource status. Be sure to enable the status subresource in your CRD version module.

defmodule MyOperator.Controller.CronTabController do

  # other steps
  step :handle_event
  # other steps

  # apply the resource
  def handle_event(axn, _opts) do
    response = apply_state(axn.resource)

    axn
    |> update_status(fn status ->
      Map.put(status, "response", response)
    end)
    |> success_event()
  end
end

Summary

Functions

Returns a specification to start this module under a supervisor.

Types

@type api() :: binary()
@type rbac_rule() :: %{apiGroups: [api()], resources: [resource()], verbs: [verb()]}
@type resource() :: binary()
@type verb() :: binary()

Callbacks

@callback rbac_rules() :: [rbac_rule()]

Functions

Returns a specification to start this module under a supervisor.

See Supervisor.

@spec to_rbac_rule({api() | [api()], resource() | [resource()], verb() | [verb()]}) ::
  rbac_rule()