diff --git a/README.md b/README.md index 31e77db3..b492a9d4 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,19 @@ client = Kubeclient::Client.new( ) ``` +### Middleware + +The Faraday HTTP client used by kubeclient allows configuration of custom middlewares. For example, you may want to add instrumentation, or add custom retry options. Kubeclient provides a hook for injecting these custom middlewares into the request/response chain, via `Client#configure_faraday(&block)`. This provides an access point to the `Faraday::Connection` object during initialization. As an example, the following code adds retry options to client requests: + +```ruby +client = Kubeclient::Client.new('http://localhost:8080/api', 'v1') +retry_options = { max: 2, interval: 0.05, interval_randomness: 0.5, backoff_factor: 2 } +client.configure_faraday { |conn| conn.request(:retry, retry_options) } +``` + +For more examples and documentation, consult the [Faraday docs](https://lostisland.github.io/faraday/). +Note that certain middlewares (e.g. `:raise_error`) are always included since Kubeclient is dependent on their behaviour to function correctly. + #### Inside a Kubernetes cluster The [recommended way to locate the API server](https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a-pod) within the pod is with the `kubernetes.default.svc` DNS name, which resolves to a Service IP which in turn will be routed to an API server. diff --git a/lib/kubeclient/common.rb b/lib/kubeclient/common.rb index 9ea84513..8ccc91e9 100644 --- a/lib/kubeclient/common.rb +++ b/lib/kubeclient/common.rb @@ -99,6 +99,10 @@ def initialize_client( end end + def configure_faraday(&block) + @faraday_client = create_faraday_client(&block) + end + def method_missing(method_sym, *args, &block) if discovery_needed?(method_sym) discover @@ -313,6 +317,8 @@ def create_faraday_client(url = nil) if @auth_options[:username] && @auth_options[:password] connection.basic_auth(@auth_options[:username], @auth_options[:password]) end + # hook for adding custom faraday configuration + yield(connection) if block_given? connection.use(FaradayMiddleware::FollowRedirects, limit: @http_max_redirects) connection.response(:raise_error) end diff --git a/test/test_kubeclient.rb b/test/test_kubeclient.rb index b964d4e1..97555eb7 100644 --- a/test/test_kubeclient.rb +++ b/test/test_kubeclient.rb @@ -273,6 +273,19 @@ def test_entity_list_parsed_symbolized assert_equal(%i[metadata spec status], response[:items].first.keys) end + def test_custom_faraday_config_options + client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1') + expected_middlewares = [FaradayMiddleware::FollowRedirects, Faraday::Response::RaiseError] + expected_middlewares.each do |klass| + assert(client.faraday_client.builder.handlers.include?(klass)) + end + client.configure_faraday { |connection| connection.use(Faraday::Request::Retry) } + expected_middlewares << Faraday::Request::Retry + expected_middlewares.each do |klass| + assert(client.faraday_client.builder.handlers.include?(klass)) + end + end + class ServiceList attr_reader :names