# `Bonny.API.Version`
[🔗](https://github.com/coryodaniel/bonny/blob/v1.5.0/lib/bonny/api/version.ex#L1)

Describes an API version of a custom resource.

The `%Bonny.API.Version{}` struct contains the fields required to build the
manifest for this version.

This module is meant to be `use`d by a module representing the
API version of a custom resource. The using module has to define
the function `manifest/0`.

The macro `defaults/1` is imported to the using module. It can be used to
simplify getting started. The first argument is the version's name (e.g. "v1").
If no name is passed, The macro will use the using module's name as the
version name.

**Note: The `:storage` flag has to be `true` for exactly one version of a
CRD.**

    defmodule MyOperator.API.V1.CronTab do
      use Bonny.API.Version

      def manifest() do
        struct!(defaults(), storage: true)
      end

Use the `manifest/0` callback to override the defaults, e.g. add a schema.
Pipe your struct into `add_observed_generation_status/1` - which is imported
into the using module - if you use the
`Bonny.Pluggable.SkipObservedGenerations` step in your controller

    defmodule MyOperator.API.V1.CronTab do
      use Bonny.API.Version

      def manifest() do
        struct!(
          defaults(),
          storage: true,
          schema: %{
            openAPIV3Schema: %{
              type: :object,
              properties: %{
                spec: %{
              }
            }
          }
        )
      end

# `printer_column_t`

```elixir
@type printer_column_t() :: %{
  :name =&gt; String.t(),
  :type =&gt; String.t() | atom(),
  optional(:description) =&gt; String.t(),
  jsonPath: String.t()
}
```

Defines an [additional printer column](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#additional-printer-columns).

# `schema_t`

```elixir
@type schema_t() :: %{
  schema: %{
    openAPIV3Schema: %{
      :type =&gt;
        :array | :boolean | :date | :integer | :number | :object | :string,
      :description =&gt; binary(),
      optional(:format) =&gt;
        :int32
        | :int64
        | :float
        | :double
        | :byte
        | :date
        | :&quot;date-time&quot;
        | :password,
      optional(:properties) =&gt; %{required(atom() | binary()) =&gt; schema_t()},
      optional(:additionalProperties) =&gt; schema_t() | boolean(),
      optional(:items) =&gt; schema_t(),
      optional(:&quot;x-kubernetes-preserve-unknown-fields&quot;) =&gt; boolean(),
      optional(:&quot;x-kubernetes-int-or-string&quot;) =&gt; boolean(),
      optional(:&quot;x-kubernetes-embedded-resource&quot;) =&gt; boolean(),
      optional(:&quot;x-kubernetes-validations&quot;) =&gt; [
        %{:rule =&gt; binary(), optional(:message) =&gt; binary()}
      ],
      optional(:pattern) =&gt; binary(),
      optional(:anyOf) =&gt; schema_t(),
      optional(:allOf) =&gt; schema_t(),
      optional(:oneOf) =&gt; schema_t(),
      optional(:not) =&gt; schema_t(),
      optional(:nullable) =&gt; boolean(),
      optional(:default) =&gt; any()
    }
  }
}
```

Defines an [OpenAPI V3 Schema](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema).

The typespec might be incomplete. Please open a PR with your additions and links to the relevant documentation, thanks.

# `subresources_t`

```elixir
@type subresources_t() :: %{
  optional(:status) =&gt; %{},
  optional(:scale) =&gt; %{
    specReplicasPath: binary(),
    statusReplicasPath: binary(),
    labelSelectorPath: binary()
  }
}
```

Defines a version of a custom resource. Refer to the
[CRD versioning documentation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/)

# `t`

```elixir
@type t() :: %Bonny.API.Version{
  additionalPrinterColumns: [printer_column_t()],
  deprecated: boolean(),
  deprecationWarning: nil | binary(),
  name: binary(),
  schema: schema_t(),
  served: boolean(),
  storage: boolean(),
  subresources: subresources_t()
}
```

# `manifest`

```elixir
@callback manifest() :: t()
```

Return a `%Bonny.API.Version{}` struct representing the manifest for this
version of the CRD API.

# `add_conditions`

```elixir
@spec add_conditions(t()) :: t()
```

Adds the status subresource if it hasn't been added before
and adds the schema for the `.status.conditions` array.

### Example

    iex> %Bonny.API.Version{}
    ...> |> Bonny.API.Version.add_conditions()
    ...> |> Map.take([:subresources, :schema])
    %{
      subresources: %{status: %{}},
      schema: %{
        openAPIV3Schema: %{
          type: :object,
          properties: %{
            status: %{
              type: :object,
              properties: %{
                conditions: %{
                  type: :array,
                  items: %{
                    type: :object,
                    properties: %{
                      type: %{type: :string},
                      status: %{type: :string, enum: ["True", "False"]},
                      message: %{type: :string},
                      lastTransitionTime: %{type: :string, format: :"date-time"},
                      lastHeartbeatTime: %{type: :string, format: :"date-time"}
                    }
                  }
                }
              }
            }
          },
          "x-kubernetes-preserve-unknown-fields": true,
        }
      }
    }

# `add_observed_generation_status`

```elixir
@spec add_observed_generation_status(t()) :: t()
```

Adds the status subresource if it hasn't been added before
and adds a field .status.observedGeneration of type integer
to the OpenAPIV3Schema.

### Example

    iex> %Bonny.API.Version{}
    ...> |> Bonny.API.Version.add_observed_generation_status()
    ...> |> Map.take([:subresources, :schema])
    %{
      subresources: %{status: %{}},
      schema: %{
        openAPIV3Schema: %{
          type: :object,
          properties: %{
            status: %{
              type: :object,
              properties: %{
                observedGeneration: %{type: :integer}
              }
            }
          },
          "x-kubernetes-preserve-unknown-fields": true,
        }
      }
    }

# `defaults`
*macro* 

Returns a `Bonny.API.Version` struct with default values. Use this and pipe
it into `struct!()` to override the defaults in your `manifest/0` callback.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
