obmarg / kazan

Kubernetes API client for Elixir
https://hex.pm/packages/kazan
MIT License
140 stars 35 forks source link

Regarding custom resources #59

Closed drowzy closed 5 years ago

drowzy commented 5 years ago

I'm trying to integrate CRD:s into my app. I know Kazan does not suport CRD yet, but I think it would be a step in the right direction if it would be possible to use Kazan.run with a custom Kazan.Request.response_scheme in a similar way to how nested structs can be decoded using Poison?

  def list_namespaced_healthchecks!(namespace, -opts) do
    %Kazan.Request{
      body: nil,
      method: "get",
      path: "/apis/group/v1alpha1/namespaces/#{namespace}/healthchecks",
      query_params: %{},
      response_schema: %HealthcheckList{items: [%Healthcheck{}]}
    }
  end

or maybe something simpler like run_raw to skip the decoding step in run. In my opinion is no problem creating custom functions returning a %Kazan.Request{} for my CRD and doing encode/decode manually. It would be nice to have the option to do so, since right now I sort of have to duplicate the Kazan.run and Kazan.Watcher logic since I can't work around it.

rodesousa commented 5 years ago

Why healthchecks will not be an arg ?

  def list_namespaced_healthchecks!(namespace, custom_resource, -opts) do
    %Kazan.Request{
      body: nil,
      method: "get",
      path: "/apis/group/v1alpha1/namespaces/#{namespace}/#{custom_resource}",
      query_params: %{},
      response_schema: %HealthcheckList{items: [%Healthcheck{}]} # here i don't know
    }
  end
obmarg commented 5 years ago

Hi @drowzy - sorry for the delay getting back to you about this, the past month has been very busy at work and I've not had much spare time to focus on OS work.

This seems like a good idea to me. Seems like it might be easiest to expand Kazan.Request with an optional response_decoder field, which could just be a function that takes the response after it's been JSON decoded, and returns a struct of some sort. Would also let people override the decoding of built in types on a case by case basis if that's what they wanted to do.

I'd be happy to accept a PR around this if you're up for it - otherwise I'll try and get round to doing this at some point (though I can't guarantee when that'll be)

drowzy commented 5 years ago

I understand and thank you for a great lib! I'll try making some time available and submit a PR

obmarg commented 5 years ago

I've started some work on this in #65. Used a slightly different approach in the end - end users can now define their own CRDs by implementing the Kazan.Model behaviour for each CRD.

By default you can just provide a model_desc function that describes the format of your model, like so:

defmodule MyApp.MyCRD do
   use Kazan.Model
   alias Kazan.{ModelDesc, PropertyDesc}

   defstruct [:id]

   def model_desc() do
     %ModelDesc{
       properties: [
         %PropertyDesc{field: "id", type: "string"}
       ]
    }
  end
end

If you want more control, you can provide encode & decode functions for the CRD that bypass the default behaviour.

Haven't had a chance to test it out yet, but would be interested in any feedback.