kubeclient 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of kubeclient might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MGQ5MGYzNzY1NzNiZGYyYTVkN2JjNmM3ZTIxNDNjMDc4ZjEwYTNkYQ==
5
- data.tar.gz: !binary |-
6
- MDkzZTkyYzhlNzViMDdiYmFlMjRjNTM4YmRkNjViYWYyNTZjNzNmMA==
2
+ SHA1:
3
+ metadata.gz: ae09dbbbec4a787210bc1a0da2e5a7d9c832bf5d
4
+ data.tar.gz: 97bf049dda0f6e3cc60c485349ea2da2540aa806
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MzcwYjI4NTFkMTFlOTMyMDljYTAzYWFhNTI4ZGMwNTg3ZWY5ZDY1MDgxNjBh
10
- ZjZhNmM0ZmIwYWM5NDVkZjA3MzAyNjNhNDkwY2RhYmJmMTc2ZGY5OGM5NjQ1
11
- ZjJiODA4ODg3YjZiOTIzODU2YzgxMjgxM2M0YmY1ZmY1YjgyZmM=
12
- data.tar.gz: !binary |-
13
- ZmFjNzNjYTc3OGUwYWU1NGRmNzRhNjIxOWZjMmVkZTVhZDAzYzg1YTI3MjZl
14
- ZTRkNTcxYTk4N2RmOWQyMDhhMjYzZGZhZWY3N2IyNzIwYTZiYzVkMmU5ZjU0
15
- YzhkOGFjYTk2ZjE5MzFlYTlhYmRkYzkwYTYyOWZiM2UwOGQ5YTI=
6
+ metadata.gz: fdd7085f59fad729afc1641dc61dc78c82b989bd02f8bd1dbebdbd27cd0e63c9cf644b7fd1df54e411d89e830d99bc596bae6cc66be82720dd8b058edece836b
7
+ data.tar.gz: ddb87120503b364ca0e79eb84a1e9baeb52cccb3850b5ea134e0555cc840c828f8093374ea6fe8bb97e4936b50781848c560954da114531a07c63c011e7291f6
data/.rubocop.yml ADDED
@@ -0,0 +1,6 @@
1
+ MethodLength:
2
+ Enabled: false
3
+ ClassLength:
4
+ Enabled: false
5
+ Metrics/AbcSize:
6
+ Enabled: false
data/README.md CHANGED
@@ -74,6 +74,13 @@ The below example is for v1beta1 <br>
74
74
  is a convenience method instead of calling each entity's get method separately. <br>
75
75
  `client.get_all_entities`
76
76
 
77
+ 7. Receive entity updates <br>
78
+ It is possible to receive live update notices watching the relevant entities:
79
+ <br>
80
+ `client.watch_pods.each do |notice|` <br>
81
+ ` # process notice data` <br>
82
+ `end` <br>
83
+
77
84
  ## Contributing
78
85
 
79
86
  1. Fork it ( https://github.com/[my-github-username]/kubeclient/fork )
data/Rakefile CHANGED
@@ -1,7 +1,10 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
+ require 'rubocop/rake_task'
3
4
 
4
- task :default => :test
5
+ task default: :test
5
6
  task :test do
6
- Dir.glob('./test/*_test.rb').each { |file| require file}
7
+ Dir.glob('./test/*_test.rb').each { |file| require file }
7
8
  end
9
+
10
+ RuboCop::RakeTask.new
data/kubeclient.gemspec CHANGED
@@ -4,27 +4,28 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'kubeclient/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "kubeclient"
7
+ spec.name = 'kubeclient'
8
8
  spec.version = Kubeclient::VERSION
9
- spec.authors = ["Alissa Bonas"]
10
- spec.email = ["abonas@redhat.com"]
11
- spec.summary = %q{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"
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
15
 
16
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"]
17
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
19
+ spec.require_paths = ['lib']
20
+ spec.required_ruby_version = '>= 2.0.0'
20
21
 
21
- spec.add_development_dependency "bundler", "~> 1.6"
22
- spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency 'bundler', '~> 1.6'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
23
24
  spec.add_development_dependency 'minitest'
24
25
  spec.add_development_dependency 'webmock'
26
+ spec.add_development_dependency 'rubocop'
25
27
  spec.add_dependency 'rest-client'
26
28
  spec.add_dependency 'activesupport'
27
29
  spec.add_dependency 'json'
28
30
  spec.add_dependency 'recursive-open-struct'
29
-
30
31
  end
@@ -1,10 +1,11 @@
1
+ # Kubernetes Entity List
1
2
  class EntityList < Array
2
3
  attr_reader :kind, :resourceVersion
3
4
 
4
- def initialize(kind,resource_version)
5
+ def initialize(kind, resource_version)
5
6
  @kind = kind
7
+ # rubocop:disable Style/VariableName
6
8
  @resourceVersion = resource_version
7
9
  super()
8
10
  end
9
-
10
- end
11
+ end
@@ -0,0 +1,4 @@
1
+ require 'recursive_open_struct'
2
+
3
+ class Event < RecursiveOpenStruct
4
+ end
@@ -1,3 +1,4 @@
1
+ # Kubernetes HTTP Exceptions
1
2
  class KubeException < Exception
2
3
  attr_reader :error_code, :message
3
4
 
@@ -7,7 +8,6 @@ class KubeException < Exception
7
8
  end
8
9
 
9
10
  def to_s
10
- "HTTP status code " + @error_code.to_s + ", " + @message
11
+ 'HTTP status code ' + @error_code.to_s + ', ' + @message
11
12
  end
12
-
13
- end
13
+ end
@@ -1,4 +1,4 @@
1
1
  require 'recursive_open_struct'
2
- class Node < RecursiveOpenStruct
3
2
 
4
- end
3
+ class Node < RecursiveOpenStruct
4
+ end
@@ -1,4 +1,4 @@
1
1
  require 'recursive_open_struct'
2
- class Pod < RecursiveOpenStruct
3
2
 
3
+ class Pod < RecursiveOpenStruct
4
4
  end
@@ -1,4 +1,4 @@
1
1
  require 'recursive_open_struct'
2
- class ReplicationController < RecursiveOpenStruct
3
2
 
4
- end
3
+ class ReplicationController < RecursiveOpenStruct
4
+ end
@@ -1,5 +1,4 @@
1
1
  require 'recursive_open_struct'
2
2
 
3
3
  class Service < RecursiveOpenStruct
4
-
5
4
  end
@@ -1,3 +1,4 @@
1
+ # Kubernetes REST-API Client
1
2
  module Kubeclient
2
- VERSION = "0.1.1"
3
+ VERSION = '0.1.2'
3
4
  end
@@ -0,0 +1,4 @@
1
+ require 'recursive_open_struct'
2
+
3
+ class WatchNotice < RecursiveOpenStruct
4
+ end
@@ -0,0 +1,29 @@
1
+ require 'json'
2
+ require 'net/http'
3
+
4
+ module Kubeclient
5
+ # HTTP Stream used to watch changes on entities
6
+ class WatchStream
7
+ def initialize(uri)
8
+ @uri = uri
9
+ end
10
+
11
+ def each
12
+ buffer = ''
13
+ Net::HTTP.start(@uri.host, @uri.port) do |http|
14
+ request = Net::HTTP::Get.new @uri
15
+ http.request request do |response|
16
+ unless response.is_a? Net::HTTPSuccess
17
+ fail KubeException.new(response.code, response.message)
18
+ end
19
+ response.read_body do |chunk|
20
+ buffer << chunk
21
+ while (line = buffer.slice!(/.+\n/))
22
+ yield WatchNotice.new(JSON.parse(line))
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/kubeclient.rb CHANGED
@@ -2,133 +2,142 @@ require 'kubeclient/version'
2
2
  require 'json'
3
3
  require 'rest-client'
4
4
  require 'active_support/inflector'
5
+ require 'kubeclient/event'
5
6
  require 'kubeclient/pod'
6
7
  require 'kubeclient/node'
7
8
  require 'kubeclient/service'
8
9
  require 'kubeclient/replication_controller'
9
10
  require 'kubeclient/entity_list'
10
11
  require 'kubeclient/kube_exception'
11
-
12
+ require 'kubeclient/watch'
13
+ require 'kubeclient/watch_stream'
12
14
 
13
15
  module Kubeclient
16
+ # Kubernetes Client
14
17
  class Client
15
- attr_reader :api_endpoint
16
- ENTITIES = %w(Pod Service ReplicationController Node)
17
-
18
- def initialize(api_endpoint,version)
19
- if !api_endpoint.end_with? "/"
20
- api_endpoint = api_endpoint + "/"
21
- end
22
- @api_endpoint = api_endpoint+version
23
- #version flag is needed to take care of the differences between versions
18
+ attr_reader :api_endpoint
19
+ ENTITIES = %w(Pod Service ReplicationController Node Event)
20
+
21
+ def initialize(api_endpoint, version)
22
+ api_endpoint += '/' unless api_endpoint.end_with? '/'
23
+ @api_endpoint = api_endpoint + version
24
+ # version flag is needed to take care of the differences between
25
+ # versions
24
26
  @api_version = version
25
27
  end
26
28
 
27
29
  private
30
+
28
31
  def rest_client
29
- #todo should a new one be created for every request?
32
+ # TODO: should a new one be created for every request?
30
33
  RestClient::Resource.new(@api_endpoint)
31
34
  end
32
35
 
36
+ def handling_kube_exception
37
+ yield
38
+ rescue RestClient::Exception => e
39
+ raise KubeException.new(e.http_code, JSON.parse(e.response)['message'])
40
+ end
41
+
33
42
  protected
43
+
34
44
  def create_entity(hash, entity)
35
45
  entity.classify.constantize.new(hash)
36
46
  end
37
47
 
38
48
  def get_resource_name(entity)
39
- if @api_version == "v1beta1"
40
- entity_name = entity.pluralize.camelize(:lower)
49
+ if @api_version == 'v1beta1'
50
+ entity.pluralize.camelize(:lower)
41
51
  else
42
- entity_name = entity.pluralize.downcase
52
+ entity.pluralize.downcase
43
53
  end
44
- entity_name
45
54
  end
46
55
 
56
+ ENTITIES.each do |entity|
57
+ # get all entities of a type e.g. get_nodes, get_pods, etc.
58
+ define_method("get_#{entity.underscore.pluralize}") do
59
+ # TODO: labels support
60
+ # TODO: namespace support?
61
+ response = handling_kube_exception do
62
+ rest_client[get_resource_name(entity)].get # nil, labels
63
+ end
47
64
 
48
- public
49
-
50
- ENTITIES.each do |entity|
51
-
52
- #get all entities of a type e.g. get_nodes, get_pods, etc.
53
- define_method("get_#{entity.underscore.pluralize}") do |labels=nil|
54
- #todo labels support
55
- #todo namespace support?
56
- begin
57
- response = rest_client[get_resource_name(entity)].get # nil, labels
58
- rescue RestClient::Exception => e
59
- exception = KubeException.new(e.http_code, JSON.parse(e.response)['message'] )
60
- raise exception
61
- end
62
65
  result = JSON.parse(response)
63
- if @api_version == "v1beta1"
64
- collection = EntityList.new(entity,result["resourceVersion"])
65
- else
66
- collection = EntityList.new(entity,result["metadata"]["resourceVersion"])
66
+
67
+ resourceVersion = result.fetch('resourceVersion', nil)
68
+ if resourceVersion.nil?
69
+ resourceVersion = result.fetch('metadata', {})
70
+ .fetch('resourceVersion', nil)
71
+ end
72
+
73
+ collection = EntityList.new(entity, resourceVersion)
74
+
75
+ result['items'].each do |item|
76
+ collection.push(create_entity(item, entity))
67
77
  end
68
- result["items"].each { |item | collection.push(create_entity(item, entity)) }
78
+
69
79
  collection
70
- end
71
-
72
- #get a single entity of a specific type by id
73
- define_method("get_#{entity.underscore}") do |id|
74
- begin
75
- response = rest_client[get_resource_name(entity)+"/#{id}"].get
76
- rescue RestClient::Exception => e
77
- exception = KubeException.new(e.http_code, JSON.parse(e.response)['message'] )
78
- raise exception
79
- end
80
- result = JSON.parse(response)
81
- create_entity(result, entity)
82
- end
83
-
84
- define_method("delete_#{entity.underscore}") do |id|
85
- begin
86
- rest_client[get_resource_name(entity)+"/" +id].delete
87
- rescue RestClient::Exception => e
88
- exception = KubeException.new(e.http_code, JSON.parse(e.response)['message'] )
89
- raise exception
90
- end
91
-
92
- end
93
-
94
- define_method("create_#{entity.underscore}") do |entity_config|
95
- #to_hash should be called because of issue #9 in recursive open struct
96
- hash = entity_config.to_hash
97
- begin
98
- rest_client[get_resource_name(entity)].post(hash.to_json)
99
- rescue RestClient::Exception => e
100
- exception = KubeException.new(e.http_code, JSON.parse(e.response)['message'] )
101
- raise exception
102
- end
103
- end
104
-
105
- define_method("update_#{entity.underscore}") do |entity_config|
106
- id = entity_config.id
107
- #to_hash should be called because of issue #9 in recursive open struct
108
- hash = entity_config.to_hash
109
- #temporary solution to delete id till this issue is solved: https://github.com/GoogleCloudPlatform/kubernetes/issues/3085
110
- hash.delete(:id)
111
- begin
112
- rest_client[get_resource_name(entity)+"/#{id}"].put(hash.to_json)
113
- rescue RestClient::Exception => e
114
- exception = KubeException.new(e.http_code, JSON.parse(e.response)['message'] )
115
- raise exception
116
- end
117
- end
118
-
119
- end
120
-
121
- public
122
- def get_all_entities
123
- result_hash = {}
124
- ENTITIES.each do |entity|
80
+ end
81
+
82
+ # watch all entities of a type e.g. watch_nodes, watch_pods, etc.
83
+ define_method("watch_#{entity.underscore.pluralize}") \
84
+ do |resourceVersion = nil|
85
+ uri = URI.parse(api_endpoint + '/watch/' + get_resource_name(entity))
86
+ uri.query = URI.encode_www_form(
87
+ 'resourceVersion' => resourceVersion) unless resourceVersion.nil?
88
+ WatchStream.new(uri).to_enum
89
+ end
90
+
91
+ # get a single entity of a specific type by id
92
+ define_method("get_#{entity.underscore}") do |id|
93
+ response = handling_kube_exception do
94
+ rest_client[get_resource_name(entity) + "/#{id}"].get
95
+ end
96
+ result = JSON.parse(response)
97
+ create_entity(result, entity)
98
+ end
99
+
100
+ define_method("delete_#{entity.underscore}") do |id|
101
+ handling_kube_exception do
102
+ rest_client[get_resource_name(entity) + "/#{id}"].delete
103
+ end
104
+ end
105
+
106
+ define_method("create_#{entity.underscore}") do |entity_config|
107
+ # to_hash should be called because of issue #9 in recursive open
108
+ # struct
109
+ hash = entity_config.to_hash
110
+ handling_kube_exception do
111
+ rest_client[get_resource_name(entity)].post(hash.to_json)
112
+ end
113
+ end
114
+
115
+ define_method("update_#{entity.underscore}") do |entity_config|
116
+ id = entity_config.id
117
+ # to_hash should be called because of issue #9 in recursive open
118
+ # struct
119
+ hash = entity_config.to_hash
120
+ # TODO: temporary solution to delete id till this issue is solved
121
+ # https://github.com/GoogleCloudPlatform/kubernetes/issues/3085
122
+ hash.delete(:id)
123
+ handling_kube_exception do
124
+ rest_client[get_resource_name(entity) + "/#{id}"].put(hash.to_json)
125
+ end
126
+ end
127
+ end
128
+
129
+ public
130
+
131
+ # FIXME: fix the accessor names
132
+ # rubocop:disable Style/AccessorMethodName
133
+ def get_all_entities
134
+ ENTITIES.each_with_object({}) do |entity, result_hash|
125
135
  # method call for get each entities
126
136
  # build hash of entity name to array of the entities
127
137
  method_name = "get_#{entity.underscore.pluralize}"
128
138
  key_name = entity.underscore
129
139
  result_hash[key_name] = send(method_name)
130
140
  end
131
- result_hash
132
141
  end
133
142
  end
134
143
  end