diff --git a/lib/kubeclient.rb b/lib/kubeclient.rb index 6066c22a..15c30a2e 100644 --- a/lib/kubeclient.rb +++ b/lib/kubeclient.rb @@ -62,6 +62,20 @@ class Client 'continue' => :continue }.freeze + DELETE_COLLECTION_ARGUMENTS = { + 'continue' => :continue, + 'dryRun' => :dry_run, + 'fieldSelector' => :field_selector, + 'gracePeriodSeconds' => :grace_period_seconds, + 'labelSelector' => :label_selector, + 'limit' => :limit, + 'orphanDependents' => :orphan_dependents, + 'propagationPolicy' => :propagation_policy, + 'resourceVersion' => :resource_version, + 'resourceVersionMatch' => :resource_version_match, + 'timeoutSeconds' => :timeout_seconds + }.freeze + WATCH_ARGUMENTS = { 'labelSelector' => :label_selector, 'fieldSelector' => :field_selector, @@ -294,6 +308,12 @@ def define_entity_methods delete_entity(entity.resource_name, name, namespace, **opts) end + # delete all entities of a type e.g. delete_pods, etc. + define_singleton_method("delete_#{entity.method_names[1]}") \ + do |options = {}| + delete_collection(entity.entity_type, entity.resource_name, options) + end + define_singleton_method("create_#{entity.method_names[0]}") do |entity_config| create_entity(entity.entity_type, entity.resource_name, entity_config) end @@ -449,6 +469,32 @@ def delete_entity(resource_name, name, namespace = nil, delete_options: {}) format_response(@as, response.body) end + # Accepts the following options: + # :namespace (string) - the namespace of the entity. + # :label_selector (string) - a selector to restrict the list of returned objects by labels. + # :field_selector (string) - a selector to restrict the list of returned objects by fields. + # :grace_period_seconds (integer) - the duration before an object should be deleted + # :limit (integer) - a maximum number of items to return in each response + # :orphan_dependents (bool) - should the dependent objects be orphaned + # :propagation_policy (string) - one of Foreground|Background|Orphan + # :resource_version (string) - sets a limit on the resource versions that can be served + # :resource_version_match (string) - determines how the resource_version constraint will be applied + # :timeout_seconds (integer) - limits the duraiton of the call + # :continue (string) - a token used to retrieve the next chunk of entities + # :as (:raw|:ros) - defaults to :ros + # :raw - return the raw response body as a string + # :ros - return a collection of RecursiveOpenStruct objects + def delete_collection(entity_type, resource_name, options = {}) + params = {} + DELETE_COLLECTION_ARGUMENTS.each { |k, v| params[k] = options[v] if options[v] } + + ns_prefix = build_namespace_prefix(options[:namespace]) + response = handle_exception do + faraday_client.delete("#{ns_prefix}#{resource_name}", params) + end + format_response(options[:as] || @as, response.body, entity_type) + end + def create_entity(entity_type, resource_name, entity_config) # Duplicate the entity_config to a hash so that when we assign # kind and apiVersion, this does not mutate original entity_config obj. diff --git a/test/test_kubeclient.rb b/test/test_kubeclient.rb index 0f333c5f..e3a72199 100644 --- a/test/test_kubeclient.rb +++ b/test/test_kubeclient.rb @@ -291,6 +291,54 @@ def test_entity_list_parsed_symbolized assert_equal(%i[metadata spec status], response[:items].first.keys) end + def test_delete_collection + stub_core_api_list + stub_delete_pods + + pods = client.delete_pods + + refute_empty(pods) + assert_instance_of(Kubeclient::Common::EntityList, pods) + # Stripping of 'List' in collection.kind RecursiveOpenStruct mode only is historic. + assert_equal('Pod', pods.kind) + assert_equal(1, pods.size) + assert_instance_of(Kubeclient::Resource, pods[0]) + + assert_requested(:delete, 'http://localhost:8080/api/v1/pods', times: 1) + end + + def test_delete_collection_raw + stub_core_api_list + stub_delete_pods + + response = client.delete_pods(as: :raw) + + refute_empty(response) + assert_equal(open_test_file('pod_list.json').read, response) + + assert_requested(:delete, 'http://localhost:8080/api/v1/pods', times: 1) + end + + def test_delete_collection_parsed + stub_core_api_list + stub_delete_pods + + response = client.delete_pods(as: :parsed) + assert_equal(Hash, response.class) + assert_equal('PodList', response['kind']) + assert_equal(%w[metadata spec status], response['items'].first.keys) + end + + def test_delete_collection_parsed_symbolized + stub_core_api_list + stub_delete_pods + + response = client.delete_pods(as: :parsed_symbolized) + assert_equal(Hash, response.class) + assert_equal('PodList', response[:kind]) + 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] @@ -926,6 +974,11 @@ def stub_get_services .to_return(body: open_test_file('entity_list.json'), status: 200) end + def stub_delete_pods + stub_request(:delete, %r{/pods}) + .to_return(body: open_test_file('pod_list.json'), status: 200) + end + def client @client ||= Kubeclient::Client.new('http://localhost:8080/api/', 'v1') end