ruboty-k8s 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ruboty/k8s/version.rb +1 -1
  3. data/ruboty-k8s.gemspec +1 -9
  4. metadata +4 -183
  5. data/lib/kubeclient/.gitignore +0 -15
  6. data/lib/kubeclient/.rubocop.yml +0 -16
  7. data/lib/kubeclient/.travis.yml +0 -12
  8. data/lib/kubeclient/Gemfile +0 -4
  9. data/lib/kubeclient/LICENSE.txt +0 -22
  10. data/lib/kubeclient/README.md +0 -428
  11. data/lib/kubeclient/Rakefile +0 -12
  12. data/lib/kubeclient/kubeclient.gemspec +0 -31
  13. data/lib/kubeclient/lib/kubeclient.rb +0 -32
  14. data/lib/kubeclient/lib/kubeclient/common.rb +0 -512
  15. data/lib/kubeclient/lib/kubeclient/config.rb +0 -126
  16. data/lib/kubeclient/lib/kubeclient/entity_list.rb +0 -16
  17. data/lib/kubeclient/lib/kubeclient/kube_exception.rb +0 -14
  18. data/lib/kubeclient/lib/kubeclient/missing_kind_compatibility.rb +0 -68
  19. data/lib/kubeclient/lib/kubeclient/version.rb +0 -4
  20. data/lib/kubeclient/lib/kubeclient/watch_notice.rb +0 -7
  21. data/lib/kubeclient/lib/kubeclient/watch_stream.rb +0 -80
  22. data/lib/kubeclient/test/cassettes/kubernetes_guestbook.yml +0 -879
  23. data/lib/kubeclient/test/config/allinone.kubeconfig +0 -20
  24. data/lib/kubeclient/test/config/external-ca.pem +0 -18
  25. data/lib/kubeclient/test/config/external-cert.pem +0 -19
  26. data/lib/kubeclient/test/config/external-key.rsa +0 -27
  27. data/lib/kubeclient/test/config/external.kubeconfig +0 -20
  28. data/lib/kubeclient/test/config/nouser.kubeconfig +0 -16
  29. data/lib/kubeclient/test/config/userauth.kubeconfig +0 -28
  30. data/lib/kubeclient/test/json/bindings_list.json +0 -10
  31. data/lib/kubeclient/test/json/component_status.json +0 -17
  32. data/lib/kubeclient/test/json/component_status_list.json +0 -52
  33. data/lib/kubeclient/test/json/config_map_list.json +0 -9
  34. data/lib/kubeclient/test/json/core_api_resource_list.json +0 -181
  35. data/lib/kubeclient/test/json/core_api_resource_list_without_kind.json +0 -129
  36. data/lib/kubeclient/test/json/core_oapi_resource_list_without_kind.json +0 -197
  37. data/lib/kubeclient/test/json/created_endpoint.json +0 -28
  38. data/lib/kubeclient/test/json/created_namespace.json +0 -20
  39. data/lib/kubeclient/test/json/created_secret.json +0 -16
  40. data/lib/kubeclient/test/json/created_service.json +0 -31
  41. data/lib/kubeclient/test/json/empty_pod_list.json +0 -9
  42. data/lib/kubeclient/test/json/endpoint_list.json +0 -48
  43. data/lib/kubeclient/test/json/entity_list.json +0 -56
  44. data/lib/kubeclient/test/json/event_list.json +0 -35
  45. data/lib/kubeclient/test/json/limit_range.json +0 -23
  46. data/lib/kubeclient/test/json/limit_range_list.json +0 -31
  47. data/lib/kubeclient/test/json/namespace.json +0 -13
  48. data/lib/kubeclient/test/json/namespace_exception.json +0 -8
  49. data/lib/kubeclient/test/json/namespace_list.json +0 -32
  50. data/lib/kubeclient/test/json/node.json +0 -29
  51. data/lib/kubeclient/test/json/node_list.json +0 -37
  52. data/lib/kubeclient/test/json/persistent_volume.json +0 -37
  53. data/lib/kubeclient/test/json/persistent_volume_claim.json +0 -32
  54. data/lib/kubeclient/test/json/persistent_volume_claim_list.json +0 -40
  55. data/lib/kubeclient/test/json/persistent_volume_claims_nil_items.json +0 -8
  56. data/lib/kubeclient/test/json/persistent_volume_list.json +0 -45
  57. data/lib/kubeclient/test/json/pod.json +0 -92
  58. data/lib/kubeclient/test/json/pod_list.json +0 -79
  59. data/lib/kubeclient/test/json/pod_template_list.json +0 -9
  60. data/lib/kubeclient/test/json/processed_template.json +0 -27
  61. data/lib/kubeclient/test/json/replication_controller.json +0 -57
  62. data/lib/kubeclient/test/json/replication_controller_list.json +0 -66
  63. data/lib/kubeclient/test/json/resource_quota.json +0 -46
  64. data/lib/kubeclient/test/json/resource_quota_list.json +0 -54
  65. data/lib/kubeclient/test/json/secret_list.json +0 -44
  66. data/lib/kubeclient/test/json/service.json +0 -33
  67. data/lib/kubeclient/test/json/service_account.json +0 -25
  68. data/lib/kubeclient/test/json/service_account_list.json +0 -82
  69. data/lib/kubeclient/test/json/service_illegal_json_404.json +0 -1
  70. data/lib/kubeclient/test/json/service_list.json +0 -97
  71. data/lib/kubeclient/test/json/service_patch.json +0 -25
  72. data/lib/kubeclient/test/json/service_update.json +0 -22
  73. data/lib/kubeclient/test/json/versions_list.json +0 -6
  74. data/lib/kubeclient/test/json/watch_stream.json +0 -3
  75. data/lib/kubeclient/test/test_common.rb +0 -32
  76. data/lib/kubeclient/test/test_component_status.rb +0 -30
  77. data/lib/kubeclient/test/test_config.rb +0 -72
  78. data/lib/kubeclient/test/test_endpoint.rb +0 -35
  79. data/lib/kubeclient/test/test_guestbook_go.rb +0 -238
  80. data/lib/kubeclient/test/test_helper.rb +0 -10
  81. data/lib/kubeclient/test/test_kubeclient.rb +0 -611
  82. data/lib/kubeclient/test/test_limit_range.rb +0 -27
  83. data/lib/kubeclient/test/test_missing_methods.rb +0 -42
  84. data/lib/kubeclient/test/test_namespace.rb +0 -61
  85. data/lib/kubeclient/test/test_node.rb +0 -33
  86. data/lib/kubeclient/test/test_persistent_volume.rb +0 -30
  87. data/lib/kubeclient/test/test_persistent_volume_claim.rb +0 -30
  88. data/lib/kubeclient/test/test_pod.rb +0 -29
  89. data/lib/kubeclient/test/test_pod_log.rb +0 -50
  90. data/lib/kubeclient/test/test_process_template.rb +0 -44
  91. data/lib/kubeclient/test/test_replication_controller.rb +0 -27
  92. data/lib/kubeclient/test/test_resource_list_without_kind.rb +0 -78
  93. data/lib/kubeclient/test/test_resource_quota.rb +0 -25
  94. data/lib/kubeclient/test/test_secret.rb +0 -70
  95. data/lib/kubeclient/test/test_service.rb +0 -293
  96. data/lib/kubeclient/test/test_service_account.rb +0 -28
  97. data/lib/kubeclient/test/test_watch.rb +0 -119
  98. data/lib/kubeclient/test/txt/pod_log.txt +0 -6
  99. data/lib/kubeclient/test/valid_token_file +0 -1
@@ -1,12 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'rake/testtask'
3
- require 'rubocop/rake_task'
4
- require 'yaml'
5
-
6
- task default: [:test, :rubocop] # same as .travis.yml
7
-
8
- Rake::TestTask.new do |t|
9
- t.libs << 'test'
10
- end
11
-
12
- RuboCop::RakeTask.new
@@ -1,31 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'kubeclient/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = 'kubeclient'
8
- spec.version = Kubeclient::VERSION
9
- spec.authors = ['Alissa Bonas']
10
- spec.email = ['abonas@redhat.com']
11
- spec.summary = 'A client for Kubernetes REST api'
12
- spec.description = 'A client for Kubernetes REST api'
13
- spec.homepage = 'https://github.com/abonas/kubeclient'
14
- spec.license = 'MIT'
15
-
16
- spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ['lib']
20
- spec.required_ruby_version = '>= 2.0.0'
21
-
22
- spec.add_development_dependency 'bundler', '~> 1.6'
23
- spec.add_development_dependency 'rake', '~> 10.0'
24
- spec.add_development_dependency 'minitest'
25
- spec.add_development_dependency 'webmock', '~> 1.24.2'
26
- spec.add_development_dependency 'vcr'
27
- spec.add_development_dependency 'rubocop', '= 0.46.0'
28
- spec.add_dependency 'rest-client'
29
- spec.add_dependency 'recursive-open-struct', '= 1.0.0'
30
- spec.add_dependency 'http', '= 0.9.8'
31
- end
@@ -1,32 +0,0 @@
1
- require 'kubeclient/version'
2
- require 'json'
3
- require 'rest-client'
4
- require 'kubeclient/entity_list'
5
- require 'kubeclient/kube_exception'
6
- require 'kubeclient/watch_notice'
7
- require 'kubeclient/watch_stream'
8
- require 'kubeclient/common'
9
- require 'kubeclient/config'
10
- require 'kubeclient/missing_kind_compatibility'
11
-
12
- module Kubeclient
13
- # Kubernetes Client
14
- class Client
15
- include ClientMixin
16
- # define a multipurpose resource class, available before discovery
17
- ClientMixin.resource_class(Kubeclient, 'Resource')
18
- def initialize(
19
- uri,
20
- version = 'v1',
21
- **options
22
- )
23
- initialize_client(
24
- Kubeclient,
25
- uri,
26
- '/api',
27
- version,
28
- options
29
- )
30
- end
31
- end
32
- end
@@ -1,512 +0,0 @@
1
- require 'json'
2
- require 'rest-client'
3
- module Kubeclient
4
- # Common methods
5
- # this is mixed in by other gems
6
- module ClientMixin
7
- ENTITY_METHODS = %w(get watch delete create update patch rollback).freeze
8
-
9
- DEFAULT_SSL_OPTIONS = {
10
- client_cert: nil,
11
- client_key: nil,
12
- ca_file: nil,
13
- cert_store: nil,
14
- verify_ssl: OpenSSL::SSL::VERIFY_PEER
15
- }.freeze
16
-
17
- DEFAULT_AUTH_OPTIONS = {
18
- username: nil,
19
- password: nil,
20
- bearer_token: nil,
21
- bearer_token_file: nil
22
- }.freeze
23
-
24
- DEFAULT_SOCKET_OPTIONS = {
25
- socket_class: nil,
26
- ssl_socket_class: nil
27
- }.freeze
28
-
29
- DEFAULT_HTTP_PROXY_URI = nil
30
-
31
- SEARCH_ARGUMENTS = {
32
- 'labelSelector' => :label_selector,
33
- 'fieldSelector' => :field_selector
34
- }.freeze
35
-
36
- WATCH_ARGUMENTS = { 'resourceVersion' => :resource_version }.merge!(SEARCH_ARGUMENTS).freeze
37
-
38
- attr_reader :api_endpoint
39
- attr_reader :ssl_options
40
- attr_reader :auth_options
41
- attr_reader :http_proxy_uri
42
- attr_reader :headers
43
- attr_reader :discovered
44
-
45
- def initialize_client(
46
- class_owner,
47
- uri,
48
- path,
49
- version,
50
- ssl_options: DEFAULT_SSL_OPTIONS,
51
- auth_options: DEFAULT_AUTH_OPTIONS,
52
- socket_options: DEFAULT_SOCKET_OPTIONS,
53
- http_proxy_uri: DEFAULT_HTTP_PROXY_URI
54
- )
55
- validate_auth_options(auth_options)
56
- handle_uri(uri, path)
57
-
58
- @class_owner = class_owner
59
- @entities = {}
60
- @discovered = false
61
- @api_version = version
62
- @headers = {}
63
- @ssl_options = ssl_options
64
- @auth_options = auth_options
65
- @socket_options = socket_options
66
- @http_proxy_uri = http_proxy_uri.to_s if http_proxy_uri
67
-
68
- if auth_options[:bearer_token]
69
- bearer_token(@auth_options[:bearer_token])
70
- elsif auth_options[:bearer_token_file]
71
- validate_bearer_token_file
72
- bearer_token(File.read(@auth_options[:bearer_token_file]))
73
- end
74
- end
75
-
76
- def method_missing(method_sym, *args, &block)
77
- if discovery_needed?(method_sym)
78
- discover
79
- send(method_sym, *args, &block)
80
- else
81
- super
82
- end
83
- end
84
-
85
- def respond_to_missing?(method_sym, include_private = false)
86
- if discovery_needed?(method_sym)
87
- discover
88
- respond_to?(method_sym, include_private)
89
- else
90
- super
91
- end
92
- end
93
-
94
- def discovery_needed?(method_sym)
95
- !@discovered && ENTITY_METHODS.any? { |x| method_sym.to_s.start_with?(x) }
96
- end
97
-
98
- def handle_exception
99
- yield
100
- rescue RestClient::Exception => e
101
- json_error_msg = begin
102
- JSON.parse(e.response || '') || {}
103
- rescue JSON::ParserError
104
- {}
105
- end
106
- err_message = json_error_msg['message'] || e.message
107
- raise KubeException.new(e.http_code, err_message, e.response)
108
- end
109
-
110
- def discover
111
- load_entities
112
- define_entity_methods
113
- @discovered = true
114
- end
115
-
116
- def self.parse_definition(kind, name)
117
- # "name": "componentstatuses", networkpolicies, endpoints
118
- # "kind": "ComponentStatus" NetworkPolicy, Endpoints
119
- # maintain pre group api compatibility for endpoints.
120
- # See: https://github.com/kubernetes/kubernetes/issues/8115
121
- kind = 'Endpoint' if kind == 'Endpoints'
122
-
123
- prefix = kind[0..kind.rindex(/[A-Z]/)] # NetworkP
124
- m = name.match(/^#{prefix.downcase}(.*)$/)
125
- m && OpenStruct.new(
126
- entity_type: kind, # ComponentStatus
127
- resource_name: name, # componentstatuses
128
- method_names: [
129
- ClientMixin.underscore_entity(kind), # component_status
130
- ClientMixin.underscore_entity(prefix) + m[1] # component_statuses
131
- ]
132
- )
133
- end
134
-
135
- def handle_uri(uri, path)
136
- raise ArgumentError, 'Missing uri' unless uri
137
- @api_endpoint = (uri.is_a?(URI) ? uri : URI.parse(uri))
138
- @api_endpoint.path = path if @api_endpoint.path.empty?
139
- @api_endpoint.path = @api_endpoint.path.chop if @api_endpoint.path.end_with? '/'
140
- components = @api_endpoint.path.to_s.split('/') # ["", "api"] or ["", "apis", batch]
141
- @api_group = components.length > 2 ? components[2] + '/' : ''
142
- end
143
-
144
- def build_namespace_prefix(namespace)
145
- namespace.to_s.empty? ? '' : "namespaces/#{namespace}/"
146
- end
147
-
148
- def self.resource_class(class_owner, entity_type)
149
- if class_owner.const_defined?(entity_type, false)
150
- class_owner.const_get(entity_type, false)
151
- else
152
- class_owner.const_set(
153
- entity_type,
154
- Class.new(RecursiveOpenStruct) do
155
- def initialize(hash = nil, args = {})
156
- args[:recurse_over_arrays] = true
157
- super(hash, args)
158
- end
159
- end
160
- )
161
- end
162
- end
163
-
164
- def define_entity_methods
165
- @entities.values.each do |entity|
166
- klass = ClientMixin.resource_class(@class_owner, entity.entity_type)
167
- # get all entities of a type e.g. get_nodes, get_pods, etc.
168
- define_singleton_method("get_#{entity.method_names[1]}") do |options = {}|
169
- get_entities(entity.entity_type, klass, entity.resource_name, options)
170
- end
171
-
172
- # watch all entities of a type e.g. watch_nodes, watch_pods, etc.
173
- define_singleton_method("watch_#{entity.method_names[1]}") do |options = {}|
174
- # This method used to take resource_version as a param, so
175
- # this conversion is to keep backwards compatibility
176
- options = { resource_version: options } unless options.is_a?(Hash)
177
-
178
- watch_entities(entity.resource_name, options)
179
- end
180
-
181
- # get a single entity of a specific type by name
182
- define_singleton_method("get_#{entity.method_names[0]}") do |name, namespace = nil|
183
- get_entity(klass, entity.resource_name, name, namespace)
184
- end
185
-
186
- define_singleton_method("delete_#{entity.method_names[0]}") do |name, namespace = nil|
187
- delete_entity(entity.resource_name, name, namespace)
188
- end
189
-
190
- define_singleton_method("create_#{entity.method_names[0]}") do |entity_config|
191
- create_entity(entity.entity_type, entity.resource_name, entity_config, klass)
192
- end
193
-
194
- define_singleton_method("update_#{entity.method_names[0]}") do |entity_config|
195
- update_entity(entity.resource_name, entity_config)
196
- end
197
-
198
- define_singleton_method("patch_#{entity.method_names[0]}") do |name, patch, namespace = nil|
199
- patch_entity(entity.resource_name, name, patch, namespace)
200
- end
201
-
202
- define_singleton_method("rollback_#{entity.method_names[0]}") do |name, entity_config = {}, namespace = nil|
203
- rollback_entity(entity.resource_name, name, entity_config: entity_config, namespace: namespace)
204
- end
205
- end
206
- end
207
-
208
- def self.underscore_entity(entity_name)
209
- entity_name.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
210
- end
211
-
212
- def create_rest_client(path = nil)
213
- path ||= @api_endpoint.path
214
- options = {
215
- ssl_ca_file: @ssl_options[:ca_file],
216
- ssl_cert_store: @ssl_options[:cert_store],
217
- verify_ssl: @ssl_options[:verify_ssl],
218
- ssl_client_cert: @ssl_options[:client_cert],
219
- ssl_client_key: @ssl_options[:client_key],
220
- proxy: @http_proxy_uri,
221
- user: @auth_options[:username],
222
- password: @auth_options[:password]
223
- }
224
- RestClient::Resource.new(@api_endpoint.merge(path).to_s, options)
225
- end
226
-
227
- def rest_client
228
- @rest_client ||= begin
229
- create_rest_client("#{@api_endpoint.path}/#{@api_version}")
230
- end
231
- end
232
-
233
- # Accepts the following string options:
234
- # :namespace - the namespace of the entity.
235
- # :name - the name of the entity to watch.
236
- # :label_selector - a selector to restrict the list of returned objects by their labels.
237
- # :field_selector - a selector to restrict the list of returned objects by their fields.
238
- # :resource_version - shows changes that occur after that particular version of a resource.
239
- def watch_entities(resource_name, options = {})
240
- ns = build_namespace_prefix(options[:namespace])
241
-
242
- path = "watch/#{ns}#{resource_name}"
243
- path += "/#{options[:name]}" if options[:name]
244
- uri = @api_endpoint.merge("#{@api_endpoint.path}/#{@api_version}/#{path}")
245
-
246
- params = {}
247
- WATCH_ARGUMENTS.each { |k, v| params[k] = options[v] if options[v] }
248
- uri.query = URI.encode_www_form(params) if params.any?
249
-
250
- Kubeclient::Common::WatchStream.new(uri, http_options(uri))
251
- end
252
-
253
- # Accepts the following string options:
254
- # :namespace - the namespace of the entity.
255
- # :label_selector - a selector to restrict the list of returned objects by their labels.
256
- # :field_selector - a selector to restrict the list of returned objects by their fields.
257
- def get_entities(entity_type, klass, resource_name, options = {})
258
- params = {}
259
- SEARCH_ARGUMENTS.each { |k, v| params[k] = options[v] if options[v] }
260
-
261
- ns_prefix = build_namespace_prefix(options[:namespace])
262
-
263
- response = handle_exception do
264
- rest_client[ns_prefix + resource_name]
265
- .get({ 'params' => params }.merge(@headers))
266
- end
267
-
268
- result = JSON.parse(response)
269
-
270
- resource_version =
271
- result.fetch('resourceVersion') do
272
- result.fetch('metadata', {}).fetch('resourceVersion', nil)
273
- end
274
-
275
- # result['items'] might be nil due to https://github.com/kubernetes/kubernetes/issues/13096
276
- collection = result['items'].to_a.map { |item| new_entity(item, klass) }
277
-
278
- Kubeclient::Common::EntityList.new(entity_type, resource_version, collection)
279
- end
280
-
281
- def get_entity(klass, resource_name, name, namespace = nil)
282
- ns_prefix = build_namespace_prefix(namespace)
283
- response = handle_exception do
284
- rest_client[ns_prefix + resource_name + "/#{name}"]
285
- .get(@headers)
286
- end
287
- result = JSON.parse(response)
288
- new_entity(result, klass)
289
- end
290
-
291
- def delete_entity(resource_name, name, namespace = nil)
292
- ns_prefix = build_namespace_prefix(namespace)
293
- handle_exception do
294
- rest_client[ns_prefix + resource_name + "/#{name}"]
295
- .delete(@headers)
296
- end
297
- end
298
-
299
- def create_entity(entity_type, resource_name, entity_config, klass)
300
- # Duplicate the entity_config to a hash so that when we assign
301
- # kind and apiVersion, this does not mutate original entity_config obj.
302
- hash = entity_config.to_hash
303
-
304
- ns_prefix = build_namespace_prefix(hash[:metadata][:namespace])
305
-
306
- # TODO: temporary solution to add "kind" and apiVersion to request
307
- # until this issue is solved
308
- # https://github.com/GoogleCloudPlatform/kubernetes/issues/6439
309
- # TODO: #2 solution for
310
- # https://github.com/kubernetes/kubernetes/issues/8115
311
- hash[:kind] = (entity_type.eql?('Endpoint') ? 'Endpoints' : entity_type)
312
- hash[:apiVersion] = @api_group + @api_version
313
- response = handle_exception do
314
- rest_client[ns_prefix + resource_name]
315
- .post(hash.to_json, { 'Content-Type' => 'application/json' }.merge(@headers))
316
- end
317
- result = JSON.parse(response)
318
- new_entity(result, klass)
319
- end
320
-
321
- def update_entity(resource_name, entity_config)
322
- name = entity_config[:metadata][:name]
323
- ns_prefix = build_namespace_prefix(entity_config[:metadata][:namespace])
324
- handle_exception do
325
- rest_client[ns_prefix + resource_name + "/#{name}"]
326
- .put(entity_config.to_h.to_json, { 'Content-Type' => 'application/json' }.merge(@headers))
327
- end
328
- end
329
-
330
- def patch_entity(resource_name, name, patch, namespace = nil)
331
- ns_prefix = build_namespace_prefix(namespace)
332
-
333
- handle_exception do
334
- rest_client[ns_prefix + resource_name + "/#{name}"]
335
- .patch(
336
- patch.to_json,
337
- { 'Content-Type' => 'application/strategic-merge-patch+json' }.merge(@headers)
338
- )
339
- end
340
- end
341
-
342
- def rollback_entity(resource_name, name, entity_config: {}, namespace: nil)
343
- ns_prefix = build_namespace_prefix(namespace)
344
-
345
- hash = entity_config.to_hash
346
- kind = resource_name.eql?('deployments') ? 'deployment' : resource_name
347
- hash[:kind] = "#{kind.capitalize}Rollback"
348
- hash[:apiVersion] = "extensions/v1beta1"
349
- hash[:rollbackTo] ||= {}
350
- hash[:name] ||= name
351
-
352
- handle_exception do
353
- rest_client[ns_prefix + resource_name + "/#{name}/rollback"]
354
- .post(
355
- hash.to_json,
356
- { 'Content-Type' => 'application/json' }.merge(@headers)
357
- )
358
- end
359
- end
360
-
361
- def new_entity(hash, klass)
362
- klass.new(hash)
363
- end
364
-
365
- def all_entities
366
- discover unless @discovered
367
- @entities.values.each_with_object({}) do |entity, result_hash|
368
- # method call for get each entities
369
- # build hash of entity name to array of the entities
370
- method_name = "get_#{entity.method_names[1]}"
371
- begin
372
- result_hash[entity.method_names[0]] = send(method_name)
373
- rescue KubeException
374
- next # do not fail due to resources not supporting get
375
- end
376
- end
377
- end
378
-
379
- def get_pod_log(pod_name, namespace, container: nil, previous: false)
380
- params = {}
381
- params[:previous] = true if previous
382
- params[:container] = container if container
383
-
384
- ns = build_namespace_prefix(namespace)
385
- handle_exception do
386
- rest_client[ns + "pods/#{pod_name}/log"]
387
- .get({ 'params' => params }.merge(@headers))
388
- end
389
- end
390
-
391
- def watch_pod_log(pod_name, namespace, container: nil)
392
- # Adding the "follow=true" query param tells the Kubernetes API to keep
393
- # the connection open and stream updates to the log.
394
- params = { follow: true }
395
- params[:container] = container if container
396
-
397
- ns = build_namespace_prefix(namespace)
398
-
399
- uri = @api_endpoint.dup
400
- uri.path += "/#{@api_version}/#{ns}pods/#{pod_name}/log"
401
- uri.query = URI.encode_www_form(params)
402
-
403
- Kubeclient::Common::WatchStream.new(uri, http_options(uri), format: :text)
404
- end
405
-
406
- def proxy_url(kind, name, port, namespace = '')
407
- discover unless @discovered
408
- entity_name_plural =
409
- if %w(services pods nodes).include?(kind.to_s)
410
- kind.to_s
411
- else
412
- @entities[kind.to_s].resource_name
413
- end
414
- ns_prefix = build_namespace_prefix(namespace)
415
- # TODO: Change this once services supports the new scheme
416
- if entity_name_plural == 'pods'
417
- rest_client["#{ns_prefix}#{entity_name_plural}/#{name}:#{port}/proxy"].url
418
- else
419
- rest_client["proxy/#{ns_prefix}#{entity_name_plural}/#{name}:#{port}"].url
420
- end
421
- end
422
-
423
- def process_template(template)
424
- ns_prefix = build_namespace_prefix(template[:metadata][:namespace])
425
- response = handle_exception do
426
- rest_client[ns_prefix + 'processedtemplates']
427
- .post(template.to_h.to_json, { 'Content-Type' => 'application/json' }.merge(@headers))
428
- end
429
- JSON.parse(response)
430
- end
431
-
432
- def api_valid?
433
- result = api
434
- result.is_a?(Hash) && (result['versions'] || []).any? do |group|
435
- @api_group.empty? ? group.include?(@api_version) : group['version'] == @api_version
436
- end
437
- end
438
-
439
- def api
440
- response = handle_exception { create_rest_client.get(@headers) }
441
- JSON.parse(response)
442
- end
443
-
444
- private
445
-
446
- def load_entities
447
- @entities = {}
448
- fetch_entities['resources'].each do |resource|
449
- next if resource['name'].include?('/')
450
- resource['kind'] ||=
451
- Kubeclient::Common::MissingKindCompatibility.resource_kind(resource['name'])
452
- entity = ClientMixin.parse_definition(resource['kind'], resource['name'])
453
- @entities[entity.method_names[0]] = entity if entity
454
- end
455
- end
456
-
457
- def fetch_entities
458
- JSON.parse(handle_exception { rest_client.get(@headers) })
459
- end
460
-
461
- def bearer_token(bearer_token)
462
- @headers ||= {}
463
- @headers[:Authorization] = "Bearer #{bearer_token}"
464
- end
465
-
466
- def validate_auth_options(opts)
467
- # maintain backward compatibility:
468
- opts[:username] = opts[:user] if opts[:user]
469
-
470
- if [:bearer_token, :bearer_token_file, :username].count { |key| opts[key] } > 1
471
- raise(
472
- ArgumentError,
473
- 'Invalid auth options: specify only one of username/password,' \
474
- ' bearer_token or bearer_token_file'
475
- )
476
- elsif [:username, :password].count { |key| opts[key] } == 1
477
- raise ArgumentError, 'Basic auth requires both username & password'
478
- end
479
- end
480
-
481
- def validate_bearer_token_file
482
- msg = "Token file #{@auth_options[:bearer_token_file]} does not exist"
483
- raise ArgumentError, msg unless File.file?(@auth_options[:bearer_token_file])
484
-
485
- msg = "Cannot read token file #{@auth_options[:bearer_token_file]}"
486
- raise ArgumentError, msg unless File.readable?(@auth_options[:bearer_token_file])
487
- end
488
-
489
- def http_options(uri)
490
- options = {
491
- basic_auth_user: @auth_options[:username],
492
- basic_auth_password: @auth_options[:password],
493
- headers: @headers,
494
- http_proxy_uri: @http_proxy_uri
495
- }
496
-
497
- if uri.scheme == 'https'
498
- options[:ssl] = {
499
- ca_file: @ssl_options[:ca_file],
500
- cert: @ssl_options[:client_cert],
501
- cert_store: @ssl_options[:cert_store],
502
- key: @ssl_options[:client_key],
503
- # ruby HTTP uses verify_mode instead of verify_ssl
504
- # http://ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html
505
- verify_mode: @ssl_options[:verify_ssl]
506
- }
507
- end
508
-
509
- options.merge(@socket_options)
510
- end
511
- end
512
- end