Skip to content
This repository was archived by the owner on Jun 12, 2021. It is now read-only.

Commit 072bb1d

Browse files
committed
Support in-cluster config
1 parent 88fd5d0 commit 072bb1d

File tree

4 files changed

+234
-15
lines changed

4 files changed

+234
-15
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright 2017 The Kubernetes Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
require 'kubernetes/configuration'
16+
require 'kubernetes/config/error'
17+
18+
module Kubernetes
19+
20+
class InClusterConfig
21+
22+
class << self
23+
24+
#
25+
# Use the service account kubernetes gives to pods to connect to kubernetes
26+
# cluster. It's intended for clients that expect to be running inside a pod
27+
# running on kubernetes. It will raise an exception if called from a process
28+
# not running in a kubernetes environment.
29+
def load(client_configuration: Configuration.default)
30+
config = self.new
31+
config.configure(client_configuration)
32+
end
33+
34+
end
35+
36+
SERVICE_HOST_ENV_NAME = "KUBERNETES_SERVICE_HOST"
37+
SERVICE_PORT_ENV_NAME = "KUBERNETES_SERVICE_PORT"
38+
SERVICE_TOKEN_FILENAME = "/var/run/secrets/kubernetes.io/serviceaccount/token"
39+
SERVICE_CA_CERT_FILENAME = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
40+
41+
attr_accessor :host
42+
attr_accessor :port
43+
attr_accessor :token
44+
45+
def validate
46+
unless (self.host = self.env[SERVICE_HOST_ENV_NAME]) && (self.port = self.env[SERVICE_PORT_ENV_NAME])
47+
raise ConfigError.new("Service host/port is not set")
48+
end
49+
raise ConfigError.new("Service token file does not exists") unless File.file?(self.token_file)
50+
raise ConfigError.new("Service token file does not exists") unless File.file?(self.ca_cert)
51+
end
52+
53+
def env
54+
@env ||= ENV
55+
@env
56+
end
57+
58+
def ca_cert
59+
@ca_cert ||= SERVICE_CA_CERT_FILENAME
60+
@ca_cert
61+
end
62+
63+
def token_file
64+
@token_file ||= SERVICE_TOKEN_FILENAME
65+
@token_file
66+
end
67+
68+
def load_token
69+
open(self.token_file) do |io|
70+
self.token = io.read.chomp
71+
end
72+
end
73+
74+
def configure(configuration)
75+
validate
76+
load_token
77+
configuration.api_key['authorization'] = "Bearer #{self.token}"
78+
configuration.scheme = 'https'
79+
configuration.host = "#{self.host}:#{self.port}"
80+
configuration.ssl_ca_cert = self.ca_cert
81+
end
82+
end
83+
84+
end
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Copyright 2017 The Kubernetes Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
require 'spec_helper'
16+
require 'config/matchers'
17+
18+
require 'kubernetes/config/incluster_config'
19+
20+
21+
describe Kubernetes::InClusterConfig do
22+
23+
context '#configure' do
24+
let(:incluster_config) do
25+
Kubernetes::InClusterConfig.new.tap do |c|
26+
c.instance_variable_set(:@env, {
27+
Kubernetes::InClusterConfig::SERVICE_HOST_ENV_NAME => 'localhost',
28+
Kubernetes::InClusterConfig::SERVICE_PORT_ENV_NAME => '443',
29+
})
30+
c.instance_variable_set(:@ca_cert, file_fixture('certs/ca.crt').to_s)
31+
c.instance_variable_set(:@token_file, file_fixture('tokens/token').to_s)
32+
end
33+
end
34+
35+
it 'should configure configuration' do
36+
expected = Kubernetes::Configuration.new do |c|
37+
c.scheme = 'https'
38+
c.host = 'localhost:443'
39+
c.ssl_ca_cert = file_fixture('certs/ca.crt').to_s
40+
c.api_key['authorization'] = 'Bearer token1'
41+
end
42+
actual = Kubernetes::Configuration.new
43+
44+
incluster_config.configure(actual)
45+
expect(actual).to be_same_configuration_as(expected)
46+
end
47+
end
48+
49+
context '#validate' do
50+
let(:incluster_config) do
51+
Kubernetes::InClusterConfig.new.tap do |c|
52+
c.instance_variable_set(:@env, {
53+
Kubernetes::InClusterConfig::SERVICE_HOST_ENV_NAME => 'localhost',
54+
Kubernetes::InClusterConfig::SERVICE_PORT_ENV_NAME => '443',
55+
})
56+
c.instance_variable_set(:@ca_cert, file_fixture('certs/ca.crt').to_s)
57+
c.instance_variable_set(:@token_file, file_fixture('tokens/token').to_s)
58+
end
59+
end
60+
61+
context 'if valid environment' do
62+
63+
it 'shold not raise ConfigError' do
64+
expect { incluster_config.validate }.not_to raise_error
65+
end
66+
end
67+
68+
context 'if SERVICE_HOST_ENV_NAME env variable is not set' do
69+
70+
it 'should raise ConfigError' do
71+
incluster_config.env[Kubernetes::InClusterConfig::SERVICE_HOST_ENV_NAME] = nil
72+
73+
expect { incluster_config.validate }.to raise_error(Kubernetes::ConfigError)
74+
end
75+
end
76+
77+
context 'if SERVICE_PORT_ENV_NAME env variable is not set' do
78+
79+
it 'should raise ConfigError' do
80+
incluster_config.env[Kubernetes::InClusterConfig::SERVICE_PORT_ENV_NAME] = nil
81+
82+
expect { incluster_config.validate }.to raise_error(Kubernetes::ConfigError)
83+
end
84+
end
85+
86+
context 'if ca_cert file is not exist' do
87+
88+
it 'shold raise ConfigError' do
89+
incluster_config.instance_variable_set(:@ca_cert, 'certs/no_ca.crt')
90+
91+
expect { incluster_config.validate }.to raise_error(Kubernetes::ConfigError)
92+
end
93+
end
94+
95+
context 'if token file is not exist' do
96+
97+
it 'shold raise ConfigError' do
98+
incluster_config.instance_variable_set(:@token_file, 'tokens/no_token')
99+
100+
expect { incluster_config.validate }.to raise_error(Kubernetes::ConfigError)
101+
end
102+
end
103+
end
104+
105+
context '#ca_cert' do
106+
let(:incluster_config) { Kubernetes::InClusterConfig.new }
107+
108+
it 'shold return "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"' do
109+
expect(incluster_config.ca_cert).to eq('/var/run/secrets/kubernetes.io/serviceaccount/ca.crt')
110+
end
111+
end
112+
113+
context '#token_file' do
114+
let(:incluster_config) { Kubernetes::InClusterConfig.new }
115+
116+
it 'shold return "/var/run/secrets/kubernetes.io/serviceaccount/token"' do
117+
expect(incluster_config.token_file).to eq('/var/run/secrets/kubernetes.io/serviceaccount/token')
118+
end
119+
end
120+
end

kubernetes/spec/config/kube_config_spec.rb

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
require 'base64'
1616
require 'spec_helper'
17+
require 'config/matchers'
1718

1819
require 'kubernetes/config/kube_config'
1920

@@ -163,21 +164,6 @@
163164
],
164165
}
165166

166-
RSpec::Matchers.define :be_same_configuration_as do |expected|
167-
match do |actual|
168-
to_h = Proc.new do |configuration|
169-
{}.tap do |hash|
170-
configuration.instance_variables.each do |var|
171-
value = configuration.instance_variable_get(var)
172-
if value.kind_of?(Hash) || value.kind_of?(String)
173-
hash[var.to_s.tr('@', '')] = value
174-
end
175-
end
176-
end
177-
end
178-
to_h.call(actual) == to_h.call(expected)
179-
end
180-
end
181167

182168
describe Kubernetes::KubeConfig do
183169
let(:kube_config) { Kubernetes::KubeConfig.new(file_fixture('config/config').to_s, TEST_KUBE_CONFIG) }

kubernetes/spec/config/matchers.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright 2017 The Kubernetes Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
RSpec::Matchers.define :be_same_configuration_as do |expected|
16+
match do |actual|
17+
to_h = Proc.new do |configuration|
18+
{}.tap do |hash|
19+
configuration.instance_variables.each do |var|
20+
value = configuration.instance_variable_get(var)
21+
if value.kind_of?(Hash) || value.kind_of?(String)
22+
hash[var.to_s.tr('@', '')] = value
23+
end
24+
end
25+
end
26+
end
27+
to_h.call(actual) == to_h.call(expected)
28+
end
29+
end

0 commit comments

Comments
 (0)