kubeclient 0.1.7 → 0.1.8

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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4cce5a424d82f97a745e142c887bb3f212e1cb44
4
- data.tar.gz: bba2a4ba2dde980a5987d55b7dc16978a371ae29
3
+ metadata.gz: be8f06e6c46d5f6e8f202ff4f0b36d6474649b45
4
+ data.tar.gz: 678a768f43fab92d1e5368da223fb6a8f193b628
5
5
  SHA512:
6
- metadata.gz: c4095bf9e4a000c1c42ef97aec6bae358decb35943193875003352a3ede9f50e156ad3cb4643d4f7c11d70505c38ad77711763a08b6d1f527a308b29622a3188
7
- data.tar.gz: 6d516c2b91b6976cd4eb05f5c72e5044acfa9d8addd12829120628cab787d4911bab04e7cb504cffd4f0e987b4397a3af78337c43f47bd953ee5ec1d216fb5f7
6
+ metadata.gz: 6195902eb2f834c05346d9c6b8f8c200fd44e253451fb9b376486325804d700eddb50d7e35fdb4ba3e5ae48e338db4fea7e6ad156ca84e0033ba1723a7b550b5
7
+ data.tar.gz: ec74ebf40164b703d4442c3c77fd715ce1f662392e76ef4bc7ac448ae5a76f5937313dd5503fb361c03e1970b4576ef5776e4e3c8e6e37a871481db18c03d323
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Kubeclient
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/kubeclient.svg)](http://badge.fury.io/rb/kubeclient)
4
- [![Build Status](https://travis-ci.org/abonas/kubeclient.svg)](https://travis-ci.org/abonas/kubeclient)
4
+ [![Build Status](https://travis-ci.org/abonas/kubeclient.svg?branch=master)](https://travis-ci.org/abonas/kubeclient)
5
5
  [![Code Climate](http://img.shields.io/codeclimate/github/abonas/kubeclient.svg)](https://codeclimate.com/github/abonas/kubeclient)
6
6
  [![Dependency Status](https://gemnasium.com/abonas/kubeclient.svg)](https://gemnasium.com/abonas/kubeclient)
7
7
 
8
8
  A Ruby client for Kubernetes REST api.
9
9
  The client supports GET, POST, PUT, DELETE on nodes, pods, services, replication controllers and namespaces.
10
- The client currently supports Kubernetes REST api version v1beta1 and v1beta3.
10
+ The client currently supports Kubernetes REST api version v1beta3.
11
11
 
12
12
  ## Installation
13
13
 
@@ -28,12 +28,18 @@ Or install it yourself as:
28
28
  ## Usage
29
29
 
30
30
  Initialize the client: <br>
31
- `client = Kubeclient::Client.new 'http://localhost:8080/api/' , "v1beta1"`
31
+ `client = Kubeclient::Client.new 'http://localhost:8080/api/' , "v1beta3"`
32
32
 
33
33
  or for the v3:
34
34
 
35
35
  `client = Kubeclient::Client.new 'http://localhost:8080/api/' , "v1beta3"`
36
36
 
37
+ Another option is to initialize the client with URI object:
38
+
39
+ `uri = URI::HTTP.build(host: "somehostname", port: 8080)`
40
+ `client = Kubeclient::Client.new uri`
41
+
42
+
37
43
  It is also possible to use https and configure ssl with:
38
44
 
39
45
  `client = Kubeclient::Client.new 'https://localhost:8443/api/' , "v1beta3"`
@@ -55,10 +61,10 @@ Examples:
55
61
  <br>
56
62
  `pods = client.get_pods`
57
63
  <br>
58
- You can get entities which have specific labels by specifying input parameter named `labels`: <br>
59
- `pods = client.get_pods(labels: 'name=redis-master')` <br>
64
+ You can get entities which have specific labels by specifying input parameter named `label-selector`: <br>
65
+ `pods = client.get_pods(label_selector: 'name=redis-master')` <br>
60
66
  You can specify multiple labels and that returns entities which have both labels: <br>
61
- `pods = client.get_pods(labels: 'name=redis-master,app=redis')`
67
+ `pods = client.get_pods(label_selector: 'name=redis-master,app=redis')`
62
68
 
63
69
  2. Get a specific node (and respectively: get_service "service id" , get_pod "pod id" , get_replication_controller "rc id" )
64
70
  <br>
@@ -75,25 +81,25 @@ Input parameter - id (string) specifying service id, pod id, replication control
75
81
 
76
82
  4. Create a service (and respectively: create_pod pod_object, create_replication_controller rc_obj) <br>
77
83
  Input parameter - object of type Service, Pod, ReplicationController. <br>
78
- The below example is for v1beta1
84
+ The below example is for v1beta3
79
85
  <br>
80
86
  `service = Service.new` <br>
81
- `service.id = "redis-master"`<br>
82
- `service.port = 6379`<br>
83
- `service.containerPort = "redis-server"`<br>
84
- `service.selector = {}`<br>
85
- `service.selector.name = "redis"`<br>
86
- `service.selector.role = "master"`<br>
87
+ `service.metadata.name = "redis-master"`<br>
88
+ `service.spec.port = 6379`<br>
89
+ `service.spec.containerPort = "redis-server"`<br>
90
+ `service.spec.selector = {}`<br>
91
+ `service.spec.selector.name = "redis"`<br>
92
+ `service.spec.selector.role = "master"`<br>
87
93
  `client.create_service service`<br>
88
94
  <br>
89
95
 
90
96
  5. Update entity (update pod, service, replication controller) <br>
91
97
  Input parameter - object of type Service, Pod, ReplicationController <br>
92
- The below example is for v1beta1 <br>
98
+ The below example is for v1beta3 <br>
93
99
  `client.update_service service1`
94
100
  <br>
95
101
 
96
- 6. Get all entities - Returns a hash with 4 keys (node, service,pod, replication_controller). Each key points to an EntityList of same type. This method
102
+ 6. all_entities - Returns a hash with 7 keys (node, service, pod, replication_controller, namespace, endpoint and event). Each key points to an EntityList of same type. This method
97
103
  is a convenience method instead of calling each entity's get method separately. <br>
98
104
  `client.get_all_entities`
99
105
 
data/lib/kubeclient.rb CHANGED
@@ -12,53 +12,61 @@ module Kubeclient
12
12
  class Client
13
13
  attr_reader :api_endpoint
14
14
 
15
- ENTITY_TYPES = %w(Pod Service ReplicationController Node Event Endpoint
16
- Namespace)
17
-
18
15
  # Dynamically creating classes definitions (class Pod, class Service, etc.),
19
16
  # The classes are extending RecursiveOpenStruct.
20
17
  # This cancels the need to define the classes
21
18
  # manually on every new entity addition,
22
19
  # and especially since currently the class body is empty
23
- ENTITY_TYPES.each do |entity_type|
24
- Object.const_set(entity_type, Class.new(RecursiveOpenStruct))
20
+ ENTITY_TYPES = %w(Pod Service ReplicationController Node Event Endpoint
21
+ Namespace).map do |et|
22
+ [Kubeclient.const_set(et, Class.new(RecursiveOpenStruct)), et]
25
23
  end
26
24
 
27
- def initialize(uri, version)
25
+ def initialize(uri, version = 'v1beta3')
28
26
  @api_endpoint = (uri.is_a? URI) ? uri : URI.parse(uri)
29
- @api_endpoint.merge!(File.join(@api_endpoint.path, version))
30
- # version flag is needed to take care of the differences between
31
- # versions
27
+ @api_endpoint.path = '/api/' if @api_endpoint.path.empty?
28
+ unless @api_endpoint.path.end_with? '/'
29
+ @api_endpoint.path = @api_endpoint.path + '/'
30
+ end
32
31
  @api_version = version
33
32
  ssl_options
34
33
  end
35
34
 
36
- private
37
-
38
35
  def rest_client
39
- options = {
40
- ssl_ca_file: @ssl_options[:ca_file],
41
- verify_ssl: @ssl_options[:verify_ssl],
42
- ssl_client_cert: @ssl_options[:client_cert],
43
- ssl_client_key: @ssl_options[:client_key]
44
- }
45
-
46
- # TODO: should a new one be created for every request?
47
- RestClient::Resource.new(@api_endpoint, options)
36
+ @rest_client ||= begin
37
+ options = {
38
+ ssl_ca_file: @ssl_options[:ca_file],
39
+ verify_ssl: @ssl_options[:verify_ssl],
40
+ ssl_client_cert: @ssl_options[:client_cert],
41
+ ssl_client_key: @ssl_options[:client_key]
42
+ }
43
+ endpoint_with_version = @api_endpoint
44
+ .merge("#{@api_endpoint.path}#{@api_version}")
45
+ RestClient::Resource.new(endpoint_with_version, options)
46
+ end
48
47
  end
49
48
 
50
- def handling_kube_exception
49
+ private
50
+
51
+ def handle_exception
51
52
  yield
52
53
  rescue RestClient::Exception => e
53
- raise KubeException.new(e.http_code, JSON.parse(e.response)['message'])
54
+ begin
55
+ err_message = JSON.parse(e.response)['message']
56
+ rescue JSON::ParserError
57
+ err_message = e.message
58
+ end
59
+ raise KubeException.new(e.http_code, err_message)
54
60
  end
55
61
 
56
- def get_entities(entity_type, options)
62
+ def get_entities(entity_type, klass, options)
57
63
  params = {}
58
- params['labels'] = options[:labels] if options[:labels]
64
+ if options[:label_selector]
65
+ params['label-selector'] = options[:label_selector]
66
+ end
59
67
 
60
68
  # TODO: namespace support?
61
- response = handling_kube_exception do
69
+ response = handle_exception do
62
70
  rest_client[get_resource_name(entity_type)].get(params: params)
63
71
  end
64
72
 
@@ -70,20 +78,17 @@ module Kubeclient
70
78
  result.fetch('metadata', {}).fetch('resourceVersion', nil)
71
79
  end
72
80
 
73
- collection = EntityList.new(entity_type, resource_version)
81
+ collection = result['items'].map { |item| new_entity(item, klass) }
74
82
 
75
- result['items'].each do |item|
76
- collection.push(new_entity(item, entity_type))
77
- end
78
-
79
- collection
83
+ EntityList.new(entity_type, resource_version, collection)
80
84
  end
81
85
 
82
86
  def watch_entities(entity_type, resource_version = nil)
83
87
  resource_name = get_resource_name(entity_type.to_s)
84
88
 
85
- uri = api_endpoint.merge(
86
- File.join(api_endpoint.path, 'watch', resource_name))
89
+ uri = @api_endpoint
90
+ .merge("#{@api_endpoint.path}#{@api_version}/watch/" \
91
+ "#{resource_name}")
87
92
 
88
93
  unless resource_version.nil?
89
94
  uri.query = URI.encode_www_form('resourceVersion' => resource_version)
@@ -100,16 +105,16 @@ module Kubeclient
100
105
  WatchStream.new(uri, options)
101
106
  end
102
107
 
103
- def get_entity(entity_type, id)
104
- response = handling_kube_exception do
108
+ def get_entity(entity_type, klass, id)
109
+ response = handle_exception do
105
110
  rest_client[get_resource_name(entity_type) + "/#{id}"].get
106
111
  end
107
112
  result = JSON.parse(response)
108
- new_entity(result, entity_type)
113
+ new_entity(result, klass)
109
114
  end
110
115
 
111
116
  def delete_entity(entity_type, id)
112
- handling_kube_exception do
117
+ handle_exception do
113
118
  rest_client[get_resource_name(entity_type) + "/#{id}"].delete
114
119
  end
115
120
  end
@@ -118,7 +123,7 @@ module Kubeclient
118
123
  # to_hash should be called because of issue #9 in recursive open
119
124
  # struct
120
125
  hash = entity_config.to_hash
121
- handling_kube_exception do
126
+ handle_exception do
122
127
  rest_client[get_resource_name(entity_type)].post(hash.to_json)
123
128
  end
124
129
  end
@@ -131,23 +136,19 @@ module Kubeclient
131
136
  # TODO: temporary solution to delete id till this issue is solved
132
137
  # https://github.com/GoogleCloudPlatform/kubernetes/issues/3085
133
138
  hash.delete(:id)
134
- handling_kube_exception do
139
+ handle_exception do
135
140
  rest_client[get_resource_name(entity_type) + "/#{id}"].put(hash.to_json)
136
141
  end
137
142
  end
138
143
 
139
144
  protected
140
145
 
141
- def new_entity(hash, entity_type)
142
- entity_type.classify.constantize.new(hash)
146
+ def new_entity(hash, klass)
147
+ klass.new(hash)
143
148
  end
144
149
 
145
150
  def get_resource_name(entity_type)
146
- if @api_version == 'v1beta1'
147
- entity_type.pluralize.camelize(:lower)
148
- else
149
- entity_type.pluralize.downcase
150
- end
151
+ entity_type.pluralize.downcase
151
152
  end
152
153
 
153
154
  public
@@ -162,13 +163,13 @@ module Kubeclient
162
163
  }
163
164
  end
164
165
 
165
- ENTITY_TYPES.each do |entity_type|
166
+ ENTITY_TYPES.each do |klass, entity_type|
166
167
  entity_name = entity_type.underscore
167
168
  entity_name_plural = entity_name.pluralize
168
169
 
169
170
  # get all entities of a type e.g. get_nodes, get_pods, etc.
170
171
  define_method("get_#{entity_name_plural}") do |options = {}|
171
- get_entities(entity_type, options)
172
+ get_entities(entity_type, klass, options)
172
173
  end
173
174
 
174
175
  # watch all entities of a type e.g. watch_nodes, watch_pods, etc.
@@ -178,7 +179,7 @@ module Kubeclient
178
179
 
179
180
  # get a single entity of a specific type by id
180
181
  define_method("get_#{entity_name}") do |id|
181
- get_entity(entity_type, id)
182
+ get_entity(entity_type, klass, id)
182
183
  end
183
184
 
184
185
  define_method("delete_#{entity_name}") do |id|
@@ -195,7 +196,7 @@ module Kubeclient
195
196
  end
196
197
 
197
198
  def all_entities
198
- ENTITY_TYPES.each_with_object({}) do |entity_type, result_hash|
199
+ ENTITY_TYPES.each_with_object({}) do |(_, entity_type), result_hash|
199
200
  # method call for get each entities
200
201
  # build hash of entity name to array of the entities
201
202
  method_name = "get_#{entity_type.underscore.pluralize}"
@@ -203,5 +204,17 @@ module Kubeclient
203
204
  result_hash[key_name] = send(method_name)
204
205
  end
205
206
  end
207
+
208
+ def api
209
+ response = handle_exception do
210
+ RestClient::Resource.new(@api_endpoint.to_s).get
211
+ end
212
+ JSON.parse(response)
213
+ end
214
+
215
+ def api_valid?
216
+ result = api
217
+ result.is_a?(Hash) && result['versions'].is_a?(Array)
218
+ end
206
219
  end
207
220
  end
@@ -1,11 +1,15 @@
1
- # Kubernetes Entity List
2
- class EntityList < Array
3
- attr_reader :kind, :resourceVersion
1
+ require 'delegate'
4
2
 
5
- def initialize(kind, resource_version)
6
- @kind = kind
7
- # rubocop:disable Style/VariableName
8
- @resourceVersion = resource_version
9
- super()
3
+ module Kubeclient
4
+ # Kubernetes Entity List
5
+ class EntityList < DelegateClass(Array)
6
+ attr_reader :kind, :resourceVersion
7
+
8
+ def initialize(kind, resource_version, list)
9
+ @kind = kind
10
+ # rubocop:disable Style/VariableName
11
+ @resourceVersion = resource_version
12
+ super(list)
13
+ end
10
14
  end
11
15
  end
@@ -1,4 +1,4 @@
1
1
  # Kubernetes REST-API Client
2
2
  module Kubeclient
3
- VERSION = '0.1.7'
3
+ VERSION = '0.1.8'
4
4
  end
@@ -0,0 +1,56 @@
1
+ {
2
+ "kind": "ServiceList",
3
+ "apiVersion": "v1beta3",
4
+ "metadata": {
5
+ "selfLink": "/api/v1beta3/services",
6
+ "resourceVersion": "59"
7
+ },
8
+ "items": [
9
+ {
10
+ "metadata": {
11
+ "name": "kubernetes",
12
+ "namespace": "default",
13
+ "selfLink": "/api/v1beta3/services/kubernetes?namespace=default",
14
+ "uid": "016e9dcd-ce39-11e4-ac24-3c970e4a436a",
15
+ "resourceVersion": "6",
16
+ "creationTimestamp": "2015-03-19T15:08:16+02:00",
17
+ "labels": {
18
+ "component": "apiserver",
19
+ "provider": "kubernetes"
20
+ }
21
+ },
22
+ "spec": {
23
+ "port": 443,
24
+ "protocol": "TCP",
25
+ "selector": null,
26
+ "portalIP": "10.0.0.2",
27
+ "containerPort": 0,
28
+ "sessionAffinity": "None"
29
+ },
30
+ "status": {}
31
+ },
32
+ {
33
+ "metadata": {
34
+ "name": "kubernetes-ro",
35
+ "namespace": "default",
36
+ "selfLink": "/api/v1beta3/services/kubernetes-ro?namespace=default",
37
+ "uid": "015b78bf-ce39-11e4-ac24-3c970e4a436a",
38
+ "resourceVersion": "5",
39
+ "creationTimestamp": "2015-03-19T15:08:15+02:00",
40
+ "labels": {
41
+ "component": "apiserver",
42
+ "provider": "kubernetes"
43
+ }
44
+ },
45
+ "spec": {
46
+ "port": 80,
47
+ "protocol": "TCP",
48
+ "selector": null,
49
+ "portalIP": "10.0.0.1",
50
+ "containerPort": 0,
51
+ "sessionAffinity": "None"
52
+ },
53
+ "status": {}
54
+ }
55
+ ]
56
+ }
@@ -0,0 +1,56 @@
1
+ {
2
+ "kind": "ServiceList",
3
+ "apiVersion": "v1beta3",
4
+ "metadata": {
5
+ "selfLink": "/api/v1beta3/services",
6
+ "resourceVersion": "59"
7
+ },
8
+ "items": [
9
+ {
10
+ "metadata": {
11
+ "name": "kubernetes",
12
+ "namespace": "default",
13
+ "selfLink": "/api/v1beta3/services/kubernetes?namespace=default",
14
+ "uid": "016e9dcd-ce39-11e4-ac24-3c970e4a436a",
15
+ "resourceVersion": "6",
16
+ "creationTimestamp": "2015-03-19T15:08:16+02:00",
17
+ "labels": {
18
+ "component": "apiserver",
19
+ "provider": "kubernetes"
20
+ }
21
+ },
22
+ "spec": {
23
+ "port": 443,
24
+ "protocol": "TCP",
25
+ "selector": null,
26
+ "portalIP": "10.0.0.2",
27
+ "containerPort": 0,
28
+ "sessionAffinity": "None"
29
+ },
30
+ "status": {}
31
+ },
32
+ {
33
+ "metadata": {
34
+ "name": "kubernetes-ro",
35
+ "namespace": "default",
36
+ "selfLink": "/api/v1beta3/services/kubernetes-ro?namespace=default",
37
+ "uid": "015b78bf-ce39-11e4-ac24-3c970e4a436a",
38
+ "resourceVersion": "5",
39
+ "creationTimestamp": "2015-03-19T15:08:15+02:00",
40
+ "labels": {
41
+ "component": "apiserver",
42
+ "provider": "kubernetes"
43
+ }
44
+ },
45
+ "spec": {
46
+ "port": 80,
47
+ "protocol": "TCP",
48
+ "selector": null,
49
+ "portalIP": "10.0.0.1",
50
+ "containerPort": 0,
51
+ "sessionAffinity": "None"
52
+ },
53
+ "status": {}
54
+ }
55
+ ]
56
+ }