kontena / k8s-client

Ruby Kubernetes API client
Apache License 2.0
76 stars 26 forks source link

Instance creation and configuration api should be refactored #121

Open kke opened 5 years ago

kke commented 5 years ago

Oddities / annoyances:

Other than that, it's actually pretty great.

kke commented 5 years ago

Also:

Do we actually need the Dry::Struct / Dry::Types for anything? Couldn't everything just be K8s::Resource( which is < RecursiveOpenStruct).

kke commented 5 years ago

Trying to think how it should work.

K8s::Config

This should actually be something like K8s::KubeConfig. It's not a configuration for K8s::Client. It's for parsing kubeconfig files and finding the necessary values for constructing options for a transport.

K8s::Transport

K8s::Stack

Should maybe be in another gem, such as k8s-client-stack as it's sort of custom.

K8s::Client

The user should mostly have to do:

client = K8s::Client.new
client.api('version').gitVersion
client = K8s::Client.new('~/.kube/config', context: 'foo@foofoo')
client = K8s::Client.new(server: 'https://localhost:6443', ca: 'AbCFCFGH==', token: 'abcd')
begin 
  client = K8s::Client.new
rescue K8s::Error::SSL
  client = K8s::Client.new(insecure_skip_tls_verify: true)
end

The user should not have to do anything like:

K8s::Client.new(transport: K8s::Transport.config(K8s::Config.load_file('/etc/kubernetes/admin.conf')))

K8s::Client.config(K8s::Config.load_file('/etc/kubernetes/admin.conf'))

The interface to create a client instance should be K8s::Client.new. Optionally, a shortcut for it could be K8s.client:

K8s.client(insecure_skip_tls_verify: true) do |client|
  puts client.api('version').gitVersion
end

TODO: try to split this into bite sized issues

cben commented 5 years ago

Some points to remember About token_from_auth_provider, token_from_exec:

  1. In some cases it's bearer token, in some it's a TLS client cert. At least exec provider is generic, you don't know ahead of time which you'll get. So shouldnt have token in name, and return type should admit both. Lately I'm thinking whether auth providers can be modeled cleanly as a KubeConfig -> KubeConfig transform?

  2. they might expire and require renewal. Thus user should not be involved with obtaining a token once and passing it to Client, but Client could call a method on each request to obtain fresh credentials, renewing if necessary. This will become more pressing with https://github.com/kubernetes/kubernetes/issues/70679.

  3. Worse, some providers don't have expiration dates, so one gets an auth expired error and should renew and retry 😞

  4. Is it useful to create multiple Clients with same config, sharing some single object that'll obtain / renew auth? If yes, this might need Client.new(SomethingDoingAuth.nSomethingDoingAuth.new(...)) rather simple Client.new.Client.new. (but it can be optional advanced use case)

See also notes on https://github.com/abonas/kubeclient/issues/393

kke commented 5 years ago

Perhaps the authentication modules should be implemented as some sort of http client library middleware things.

kke commented 5 years ago

Also, adding to https://github.com/kontena/k8s-client/issues/121#issuecomment-519513084