diff --git a/lib/kubeclient/common.rb b/lib/kubeclient/common.rb index 8bcfc578..d51a590b 100644 --- a/lib/kubeclient/common.rb +++ b/lib/kubeclient/common.rb @@ -194,10 +194,22 @@ def self.resolve_unconventional_method_names(name, kind, singular_name) def handle_uri(uri, path) raise ArgumentError, 'Missing uri' unless uri @api_endpoint = (uri.is_a?(URI) ? uri : URI.parse(uri)) - @api_endpoint.path = path if @api_endpoint.path.empty? - @api_endpoint.path = @api_endpoint.path.chop if @api_endpoint.path.end_with?('/') - components = @api_endpoint.path.to_s.split('/') # ["", "api"] or ["", "apis", batch] - @api_group = components.length > 2 ? components[2] + '/' : '' + + # This regex will anchor at the last `/api`, `/oapi` or`/apis/:group`) part of the URL + # The whole path will be matched and if existing, the api_group will be extracted. + re = /^(?.*\/o?api(?:s\/(?[^\/]+))?)$/mi + match = re.match(@api_endpoint.path.chomp('/')) + + if match + # Since `re` captures 2 groups, match will always have 3 elements + # If thus we have a non-nil value in match 2, this is our api_group. + @api_group = match[:apigroup].nil? ? '' : match[:apigroup] + '/' + @api_endpoint.path = match[:path] + else + # This is a fallback, for when `/api` was not provided as part of the uri + @api_group = '' + @api_endpoint.path = @api_endpoint.path.chomp('/') + path + end end def build_namespace_prefix(namespace) diff --git a/test/test_common_url_handling.rb b/test/test_common_url_handling.rb new file mode 100644 index 00000000..894c9749 --- /dev/null +++ b/test/test_common_url_handling.rb @@ -0,0 +1,154 @@ +require_relative 'test_helper' + +# URLHandling tests +class TestCommonUrlHandling < MiniTest::Test + def test_no_path_in_uri + client = Kubeclient::Client.new('http://localhost:8080', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/api/v1', rest_client.url.to_s) + end + + def test_with_api_path_in_uri + client = Kubeclient::Client.new('http://localhost:8080/api', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/api/v1', rest_client.url.to_s) + end + + def test_with_api_path_in_uri_other_version + client = Kubeclient::Client.new('http://localhost:8080/api', 'v2') + rest_client = client.rest_client + assert_equal('v2', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/api/v2', rest_client.url.to_s) + end + + def test_with_api_group_path_in_uri + client = Kubeclient::Client.new('http://localhost:8080/apis/this_is_the_group', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('this_is_the_group/', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/apis/this_is_the_group/v1', rest_client.url.to_s) + end + + def test_with_api_group_path_in_uri_other_version + client = Kubeclient::Client.new('http://localhost:8080/apis/this_is_the_group', 'v2') + rest_client = client.rest_client + assert_equal('v2', client.instance_variable_get(:@api_version)) + assert_equal('this_is_the_group/', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/apis/this_is_the_group/v2', rest_client.url.to_s) + end + + def test_with_api_path_in_uri_trailing_slash + client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/api/v1', rest_client.url.to_s) + end + + def test_with_api_path_in_api + client = Kubeclient::Client.new('http://localhost:8080/api/but/I/want/a/hidden/k8s/api', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/api/but/I/want/a/hidden/k8s/api/v1', rest_client.url.to_s) + end + + def test_with_api_group_path_in_api + client = Kubeclient::Client.new( + 'http://localhost:8080/api/but/I/want/a/hidden/k8s/apis/this_is_the_group', + 'v1' + ) + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('this_is_the_group/', client.instance_variable_get(:@api_group)) + assert_equal( + 'http://localhost:8080/api/but/I/want/a/hidden/k8s/apis/this_is_the_group/v1', + rest_client.url.to_s + ) + end + + def test_rancher_with_api_path_in_uri + client = Kubeclient::Client.new('http://localhost:8080/k8s/clusters/c-somerancherID/api', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/k8s/clusters/c-somerancherID/api/v1', rest_client.url.to_s) + end + + def test_rancher_no_api_path_in_uri + client = Kubeclient::Client.new('http://localhost:8080/k8s/clusters/c-somerancherID', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/k8s/clusters/c-somerancherID/api/v1', rest_client.url.to_s) + end + + def test_rancher_no_api_path_in_uri_trailing_slash + client = Kubeclient::Client.new('http://localhost:8080/k8s/clusters/c-somerancherID/', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/k8s/clusters/c-somerancherID/api/v1', rest_client.url.to_s) + end + + def test_rancher_with_api_path_in_uri_trailing_slash + client = Kubeclient::Client.new('http://localhost:8080/k8s/clusters/c-somerancherID/api/', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/k8s/clusters/c-somerancherID/api/v1', rest_client.url.to_s) + end + + def test_rancher_with_api_group_in_uri_trailing_slash + client = Kubeclient::Client.new('http://localhost:8080/k8s/clusters/c-somerancherID/apis/this_is_the_group', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('this_is_the_group/', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/k8s/clusters/c-somerancherID/apis/this_is_the_group/v1', rest_client.url.to_s) + end + + def test_with_openshift_api_path_in_uri + client = Kubeclient::Client.new('http://localhost:8080/oapi', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/oapi/v1', rest_client.url.to_s) + end + + def test_arbitrary_path_with_openshift_api_path_in_uri + client = Kubeclient::Client.new('http://localhost:8080/foobarbaz/oapi', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/foobarbaz/oapi/v1', rest_client.url.to_s) + end + + def test_with_openshift_api_path_in_uri_trailing_slash + client = Kubeclient::Client.new('http://localhost:8080/oapi/', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/oapi/v1', rest_client.url.to_s) + end + + def test_with_arbitrary_path_in_uri + client = Kubeclient::Client.new('http://localhost:8080/foobarbaz', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/foobarbaz/api/v1', rest_client.url.to_s) + end + + def test_with_arbitrary_and_api_path_in_uri + client = Kubeclient::Client.new('http://localhost:8080/foobarbaz/api', 'v1') + rest_client = client.rest_client + assert_equal('v1', client.instance_variable_get(:@api_version)) + assert_equal('', client.instance_variable_get(:@api_group)) + assert_equal('http://localhost:8080/foobarbaz/api/v1', rest_client.url.to_s) + end +end