Skip to content

Commit

Permalink
Allowing URI path prefixes in server URLs (kontena#110)
Browse files Browse the repository at this point in the history
* Adding support for a path prefix

* Locking `dry-types` to 0.14.x to prevent breaking

* Appeasing rubocop

* Adding some tests and better path_prefix logic

* Switching Array#prepend to #insert (2.4 support)

* Making suggested changes

* Beautify a bit
  • Loading branch information
jgnagy authored and Kimmo Lehto committed May 8, 2019
1 parent efa19f4 commit b9d7aa3
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 6 deletions.
1 change: 1 addition & 0 deletions lib/k8s/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'base64'
require 'yajl'
require 'monitor'
require 'uri'

require 'k8s/util'

Expand Down
14 changes: 8 additions & 6 deletions lib/k8s/transport.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,17 @@ def self.in_cluster_config(**options)
)
end

attr_reader :server, :options
attr_reader :server, :options, :path_prefix

# @param server [String] URL with protocol://host:port - any /path is ignored
# @param server [String] URL with protocol://host:port (paths are preserved as well)
# @param auth_token [String] optional Authorization: Bearer token
# @param auth_username [String] optional Basic authentication username
# @param auth_password [String] optional Basic authentication password
# @param options [Hash] @see Excon.new
def initialize(server, auth_token: nil, auth_username: nil, auth_password: nil, **options)
@server = server
uri = URI.parse(server)
@server = "#{uri.scheme}://#{uri.host}:#{uri.port}"
@path_prefix = File.join('/', uri.path, '/') # add leading and/or trailing slashes
@auth_token = auth_token
@auth_username = auth_username
@auth_password = auth_password
Expand All @@ -175,10 +177,10 @@ def build_excon
)
end

# @param path [Array<String>] join path parts together to build the full URL
# @param parts [Array<String>] join path parts together to build the full URL
# @return [String]
def path(*path)
File.join('/', *path)
def path(*parts)
File.join(path_prefix, *parts)
end

# @param request_object [Object] include request body using to_json
Expand Down
19 changes: 19 additions & 0 deletions spec/fixtures/config/kubeadm-admin-with-path-prefix.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNE1EY3dOVEEyTWpjeE5Gb1hEVEk0TURjd01qQTJNamN4TkZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBS0V4CjR0ZXN2V1hUV1Z4dlVQdzFwS29NNmE3NFhPRlRTdGF4d0YrcDFMVENUN3JmdlE3Nncwems4c3F1ZEh0MUlMRkgKMnpia1d2b3UrcFlhNUE1YUkxUjlMZk1vSGRPQ2ZUeXBqZmdDVVRzdDl1amxuZ0dmK3M0VFRqRndZMzBvSVNRWQpHaHUvajZBL3gzbWhhQ0psODM2SkhGeTZDTnE1OTk5MU5uMDlDT0RXc0NPbUZ6RHY3K2VaSGZiVzNIMjU1YUpFCm5zS2RHRTJ2ejNSdnVpbmRUUk1FZnhpc1RkRmx1YTZCMWp3MDF2MWRhWlcvek5sSXF6NDRieFJOTmlONFhLVngKeTJqb0dYSDI1aW5udmc4dDQwL1JCSStvamppcU1nQUlRUHVkdVJacW1pYnJMcytDdmtGcUVVWml3cWdWS0ZGQgpwVHQ0dHB5NjVIckZGZVdwcGFjQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFKbGE3ejFWb0dPMmNiL00vK0RJcW1vQit4T2UKY0FJTUJxYTNXZUZQUXZ1N2dFbGh3cTBFRndTQmRtOUp6R0xqVHRxbGZ5ai8veEgwc08wdWt3WS9NTkRhODdsZQpXT1lsZFN3RW5WQXhmVjRvU0U1N2J4ci9NeE1YVnlYRXVDc1VOTFhXbG9SM251Y3hINHQzUFRSV0ZrejRyZ1ZSCk95WUtsL2w4VW9ZQWQ5VytsRHBaa1ZXa2oxbDZXQTJZck5YQVdtZTNnb2xMS3FLSUpZTUhKUlhVbnBHSWN2SHUKWVZDaGxqbjVQMnpubkVrRms5aTVtZjZ0ZDlXNEErc0cwTUJkV3c2bUl0RWRSZmM0MVNQWUgrcUQwZDZaZDNzUwo2ZzRhaXA4Z2dmRG9SbjBDL0FKb3lFVkxRL0ZPdy9ua0NJNnRDSDQ2amZXak0rb2plbFVDSHRMcHFjRT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: "https://192.168.56.11:6443/k8s/clusters/c-dnmgm"
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJWlFXeXFFQW8yaEF3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T0RBM01EVXdOakkzTVRSYUZ3MHhPVEEzTURVd05qSTNNVFphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTBYVWZYNlJnRnVVTGxJcWYKbm4xSkpNM0UvVTZNRUMzVVNNaVRTZUp1dERRL25wVEpVcUxLVXNVTWxCYWtrQ1dueERVTE93RDZvTW5UYmVmVgpkWVp3djIyU3hRRDRiNjd5Yk1ZSVlVdmFYOVVCQ3VvNDdvb2c3RDYraDJ1TWZRNnR4MVZ6Uk85TGIvbCtTeDNsClF4RkJhcC9lUDZ3KzZrc3NWejFReDE2a3pEaE80bkRPZ2g3b2FLUTVpOElIUUhYKzBTUVhITlZyTVRWTjk2aHQKRU5PK0tVZThHRXJvR0JTNktnNlo4MkE4TzBEejVrU2xrMWVVZ054WGQwQldlazkwRFNJcGVkZUxocE1pVnBwTApnUmVmbGloWmxuYWRoNHY0amxrUk9LMTRjS1k1SXdZSzRUdVM3bkpBSWd0blJOa2dXUENNTkRWdXl1R0R2V2U4CnZzMVhCd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFIdkE5bVVxVGZEQ1VuRDBXQUs5Ni9na2VidnVlK0dUMTFMdApYV05RQTZoekN6MHhHck9pSDhGWTNLb3piZ215TTR5VzFwOEkvR29HVzNmSGl2OHVRTVdqZFFIbVBnZVc1cW9VCm54QlBrOXRuZm1RS2E1UGxEQllIdWFVR3owYzBCdW8zdklQbCs3cU91bkh2YUxUbTR5MnBmQ1ZXaFAraHFmSVUKY24weTdsTzlsbEczWU5ZTW01SEpjSFM1SkdZaEh5cm9JclZnN0NORE5Rak9kNVF3ZnRXVnlMMWVJbktzUEVUMApjV0tRMnNPcmZ2R0pIQ0l6R2tjdWhPM09kems5M0QwbnNrNG05OVlZZ3FpdFJqdWtsdldzOXpjd3pxc3hrQWNlCnZEM011Zzk4TFFSQ1Vxcm9CVldXK0JVb2FvTTZJVER3aDV3cDhuMmE3RVNJR052S096dz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBMFhVZlg2UmdGdVVMbElxZm5uMUpKTTNFL1U2TUVDM1VTTWlUU2VKdXREUS9ucFRKClVxTEtVc1VNbEJha2tDV254RFVMT3dENm9NblRiZWZWZFlad3YyMlN4UUQ0YjY3eWJNWUlZVXZhWDlVQkN1bzQKN29vZzdENitoMnVNZlE2dHgxVnpSTzlMYi9sK1N4M2xReEZCYXAvZVA2dys2a3NzVnoxUXgxNmt6RGhPNG5ETwpnaDdvYUtRNWk4SUhRSFgrMFNRWEhOVnJNVFZOOTZodEVOTytLVWU4R0Vyb0dCUzZLZzZaODJBOE8wRHo1a1NsCmsxZVVnTnhYZDBCV2VrOTBEU0lwZWRlTGhwTWlWcHBMZ1JlZmxpaFpsbmFkaDR2NGpsa1JPSzE0Y0tZNUl3WUsKNFR1UzduSkFJZ3RuUk5rZ1dQQ01ORFZ1eXVHRHZXZTh2czFYQndJREFRQUJBb0lCQVFDKzl5QzJpMkFNSDZHUwpPVnpVRy9mZTlUZ2Zsa2greTduYTdmdlRoZjFXa0xoY05kempXWVpMTmxxRWZheGx1OThjTlJ4YkhFWms1LzI3CkczNXpXekphWldWRjlkK0x1NTVNNjdSaU9NME5TRjlkK3pRU3o1NjZwVzRDZTF5bi9BVVdVdUw0TzQrMHRHeWYKd2M3dmVjRUJuR1g5K1dXWEtSaHhKWGNMZmsrVDNEQlE0c3hmOHlGVklPQnMrcW9tVUxHWnREK3Y2YUsyaGk5Zwp5VXE2aTN4R2k1ejZVMU04VmZGN0pJZWV6Y2EyVXVHeVdaeGZtK2JyQkZnaXZPZmYxVlZFdjRTWnVKc3RDSnAvClJNUEMwb2pEN2ptSjVEci9QbXM1MjdMYm9qK3o4TmV6TmJhZW8xVmlDYmtKVkM5ZmNKcm05SGlVWVM2dHZmRzEKRVl3ZUpXVWhBb0dCQU9wMlByeGFzTWYxSlR1Zk9NcjdMeE04NTh4bVN4RndGcnlzVUhOcVYxeW9mT0N3TjF5cQplVXNIbE92RnRLd2ZmaFJBSVJTWEhiMGI5aG84STZLQWY4ZmxOUmR3eENpbVhWeUs0NUQ2WklRMXg3V3hSUDdaCllQcVZKdFp6cWp2S1pWWENNaWZWdWUyd25tWS90NXlidzd1MUR6VGpqWjZ0QklMNXBKeUhJU1RSQW9HQkFPU3kKMjhYQUpKSDJVaDA5VnlIdkovR3NrbUxaMXE4VkxrSHpaTmtHWkcxalZVRmNDU2NISXFGeE9URWdkcnZGVkJwNwpaVjQ1K2Z2VmJlTnV6Y1cyN1FNT214dUVFcC9CVEhnb2FCdmY5djdxektsMjdpY3p4S0JGZVBpbWk2VEpVS2IzCm9UL3ZQZnhDNWw1QWVpSnFoOTRvVS9wTTQvaDdFclBMWjVJWmNaUlhBb0dBRGRId2VydkJ4ZGVPWFVoU1dheWEKcHNDbFRTZ09icld6c1dWYXpLTE5DWG9vK2ptSTJkNTJqZFNoazVBd3lTQ0dGdjE4dGJEK29NSUFMS1cwMkFSSgpBK2hmeThUcTJ4YUxWRVFmaTlFbWthQjE2Q0ROMTFQSzRwcGVFcS80cmRPTlM1UEp6dzFMQzFhb3o1QWI2NUJHCjVrNlMyZVE3MmNtTEJZbGZpWlp4ZnJFQ2dZQkFBTUk2dklRL2lTVC80OXZQdG1PQ1loNXhwYTlNUG13OHJzWXAKYW4yT2szOFhsSTlIS2RzS1BXcVpFaEhJaVBmNWxWRVFKcitNTi9YUjhYK0s5cCtyL0ZseVFPc0paSXBuRWovWQpsVHhGcVNadndzWHhtSzVOZ0VQVHFxQm9GS01LcDBDc2FPTDdCeW43ZEtYNW5jQzZicVRaNXN6aURHZDJnOVZQCmNPbDFid0tCZ0VSUG5xei9Jc3VhdnFhK1FxWG0wWWRycmd2VXBrU2J1a1hsZFVjSVhWR1ZvSDlaNGVmWXE5TnQKa21LQkduNHB2VVppR3hhNkhtd0hGOVRhUVMwbUI1R2dyQ0haQkZkbVVIS1Z1TTVSMVJwejkvR1owV3Fhd0x5YgpGWnVPV0RUa01YTzFNMG45VVV0K1pITDJ5a1gxc2tGdm1lNDNzZEZTTUNZVGhwV1dKd0tMCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
15 changes: 15 additions & 0 deletions spec/k8s/api_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
include FixtureHelpers

let(:transport) { K8s::Transport.new('http://localhost:8080') }
let(:transport_with_prefix) { K8s::Transport.new('http://localhost:8080/k8s/clusters/c-dnmgm') }

context "for the v1 API" do
subject { described_class.new(transport, 'v1') }
Expand All @@ -22,6 +23,20 @@
end
end

context "for URIs with a path prefix" do
subject { described_class.new(transport_with_prefix, 'v1') }

describe '#path' do
it "returns the correct root path" do
expect(subject.path).to eq '/k8s/clusters/c-dnmgm/api/v1'
end

it "returns the correct resource path" do
expect(subject.path('tests')).to eq '/k8s/clusters/c-dnmgm/api/v1/tests'
end
end
end

before do
stub_request(:get, 'localhost:8080/api/v1')
.to_return(
Expand Down
43 changes: 43 additions & 0 deletions spec/k8s/transport_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
expect(subject.server).to eq 'https://192.168.56.11:6443'
end

it 'uses the correct path' do
expect(subject.path).to eq '/'
end

it 'uses the correct options' do
expect(subject.options).to match(
ssl_cert_store: OpenSSL::X509::Store,
Expand All @@ -23,6 +27,30 @@
expect(subject.options[:ssl_cert_store].verify(server_cert)).to eq true
end

context "for URIs with a path prefix" do
subject { described_class.config(K8s::Config.load_file(fixture_path('config/kubeadm-admin-with-path-prefix.conf')))}

it 'uses the correct server' do
expect(subject.server).to eq 'https://192.168.56.11:6443'
end

it 'uses the correct path' do
expect(subject.path).to eq '/k8s/clusters/c-dnmgm/'
end

it 'uses the correct options' do
expect(subject.options).to match(
ssl_cert_store: OpenSSL::X509::Store,
client_cert_data: /^-----BEGIN CERTIFICATE-----\n/,
client_key_data: /^-----BEGIN RSA PRIVATE KEY-----\n/,
)
end

it 'uses an ssl_cert_store that verifies the server cert' do
expect(subject.options[:ssl_cert_store].verify(server_cert)).to eq true
end
end

context "overriding the server option" do
subject {
described_class.config(K8s::Config.load_file(fixture_path('config/kubeadm-admin.conf')),
Expand All @@ -33,6 +61,21 @@
it "uses the overriden server" do
expect(subject.server).to eq 'http://localhost:8001'
end

context "for URIs with a path prefix" do
subject { described_class.config(K8s::Config.load_file(fixture_path('config/kubeadm-admin-with-path-prefix.conf')),
server: 'http://localhost:8001',
)
}

it 'uses the correct server' do
expect(subject.server).to eq 'http://localhost:8001'
end

it 'uses the correct path' do
expect(subject.path).to eq '/'
end
end
end

context "overriding other options" do
Expand Down

0 comments on commit b9d7aa3

Please sign in to comment.