biosphere 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7c051409302775143098ba72247418e91385e4cc
4
- data.tar.gz: cad36da8533ac2d075305cef509a853dc66de7ee
3
+ metadata.gz: daf18083e0cee8c170b5cedf2362398fcc8cedd6
4
+ data.tar.gz: 374321563d2b570797295cbd4fe2bee0c5ac5269
5
5
  SHA512:
6
- metadata.gz: 3588e145bcd8718e9d60a3d1d622805ae7e51e21db5e64f521eef54a80d689d1e423e68fd08e13f783e7f93e6ecb5bfd6be9b03609b6b434a8801e5e420c4ec5
7
- data.tar.gz: 06dbd8f38a6e4c02af639559217a3466434f55dbb2a3e0993571f4901c54962a1420732cf9fd44fe66384e14bcb10482a6af3092273ab9187d62f5c6f0caea58
6
+ metadata.gz: f635d48699b79efc3a77d1e147f730f0a3907a7fd7b952b3f4d7e98771da834c4ce5c27d3301f869c4ac634c7c4925d32b9d5c53c6f2ed9357f5f64000d3ed98
7
+ data.tar.gz: 5b9ee10cdccb717bc152e431949458efd02a8ece9fc43f925f34b8e535fb447658350f82e5c86e62abcce9235d10837205c3682ddedffa8d935c76a04871e501
@@ -5,6 +5,7 @@ require 'optparse'
5
5
  require 'ostruct'
6
6
  require 'pp'
7
7
  require "awesome_print"
8
+ require 'colorize'
8
9
 
9
10
  class BiosphereOpts
10
11
 
@@ -49,7 +50,9 @@ class BiosphereOpts
49
50
 
50
51
  end
51
52
 
52
-
53
+ if !STDOUT.isatty
54
+ String.disable_colorization true
55
+ end
53
56
 
54
57
  options = BiosphereOpts.parse(ARGV)
55
58
 
@@ -24,10 +24,105 @@ end
24
24
 
25
25
  class Biosphere
26
26
  module Kube
27
+
28
+ class Client
29
+ def initialize(hostname, ssl_options)
30
+ @clients = []
31
+
32
+ @clients << ::Kubeclient::Client.new("#{hostname}/api" , "v1", ssl_options: ssl_options)
33
+ @clients << ::Kubeclient::Client.new("#{hostname}/apis/extensions/" , "v1beta1", ssl_options: ssl_options)
34
+
35
+ @clients.each { |c| c.discover }
36
+ end
37
+
38
+ def get_resource_name(resource)
39
+ resource_name = nil
40
+ kind = resource[:kind].underscore_case
41
+ @clients.each do |c|
42
+ if c.instance_variable_get("@entities")[kind]
43
+ return c.instance_variable_get("@entities")[kind].resource_name
44
+ end
45
+ end
46
+ return nil
47
+ end
48
+
49
+ def get_client(resource)
50
+ kind = resource[:kind].underscore_case
51
+ @clients.each do |c|
52
+ if c.instance_variable_get("@entities")[kind]
53
+ return c
54
+ end
55
+ end
56
+ return nil
57
+ end
58
+
59
+ def post(resource)
60
+ name = resource[:metadata][:name]
61
+ client = get_client(resource)
62
+ resource_name = get_resource_name(resource)
63
+
64
+ if !client
65
+ raise ArgumentError, "Unknown resource #{resource[:kind]} of #{name} for kubernetes. Maybe this is in a new extension api?"
66
+ end
67
+
68
+ ns_prefix = client.build_namespace_prefix(resource[:metadata][:namespace])
69
+ ret = client.rest_client[ns_prefix + resource_name].post(resource.to_h.to_json, { 'Content-Type' => 'application/json' }.merge(client.instance_variable_get("@headers")))
70
+ return {
71
+ action: :post,
72
+ resource: ns_prefix + resource_name + "/#{name}",
73
+ body: JSON.parse(ret.body, :symbolize_names => true)
74
+ }
75
+ end
76
+
77
+ def get(resource)
78
+ name = resource[:metadata][:name]
79
+ client = get_client(resource)
80
+ resource_name = get_resource_name(resource)
81
+
82
+ if !client
83
+ raise ArgumentError, "Unknown resource #{resource[:kind]} of #{name} for kubernetes. Maybe this is in a new extension api?"
84
+ end
85
+
86
+ ns_prefix = client.build_namespace_prefix(resource[:metadata][:namespace])
87
+ key = ns_prefix + resource_name + "/#{name}"
88
+ ret = client.rest_client[key].get(client.instance_variable_get("@headers"))
89
+ return {
90
+ action: :get,
91
+ resource: key,
92
+ body: JSON.parse(ret.body, :symbolize_names => true)
93
+ }
94
+ end
95
+
96
+ def put(resource)
97
+ name = resource[:metadata][:name]
98
+ client = get_client(resource)
99
+ resource_name = get_resource_name(resource)
100
+
101
+ if !client
102
+ raise ArgumentError, "Unknown resource #{resource[:kind]} of #{name} for kubernetes. Maybe this is in a new extension api?"
103
+ end
104
+
105
+ ns_prefix = client.build_namespace_prefix(resource[:metadata][:namespace])
106
+ key = ns_prefix + resource_name + "/#{name}"
107
+ ret = client.rest_client[key].put(resource.to_h.to_json, { 'Content-Type' => 'application/json' }.merge(client.instance_variable_get("@headers")))
108
+ return {
109
+ action: :put,
110
+ resource: key,
111
+ body: JSON.parse(ret.body, :symbolize_names => true)
112
+ }
113
+
114
+ end
115
+
116
+ end
117
+
27
118
  def kube_test(str)
28
119
  return str
29
120
  end
30
121
 
122
+ def kube_get_client(hostname, ssl_options)
123
+ return Client.new(hostname, ssl_options)
124
+ end
125
+
31
126
  def kube_load_manifest_files(dir)
32
127
  files = Dir[dir + "/**/*.erb"]
33
128
  resources = []
@@ -47,10 +142,31 @@ class Biosphere
47
142
  resources = []
48
143
  puts "Loading file #{file}"
49
144
  str = ERB.new(IO.read(file)).result(binding)
50
- Psych.load_stream(str) do |document|
51
- kind = document["kind"]
52
- resource = ::Kubeclient::Resource.new(document)
53
- resources << resource
145
+ begin
146
+ Psych.load_stream(str) do |document|
147
+ kind = document["kind"]
148
+ resource = ::Kubeclient::Resource.new(document)
149
+ resources << resource
150
+ end
151
+ rescue Psych::SyntaxError => e
152
+ STDERR.puts "\n"
153
+ STDERR.puts "YAML syntax error while parsing file #{file}. Notice this happens after ERB templating, so line numbers might not match."
154
+ STDERR.puts "Here are the relevant lines. Error '#{e.problem}' occured at line #{e.line}"
155
+ STDERR.puts "Notice that yaml is very picky about indentation when you have arrays and maps. Check those first."
156
+ lines = str.split("\n")
157
+ start_line = [0, e.line - 3].max
158
+ end_line = [lines.length - 1, e.line + 3].min
159
+ lines[start_line..end_line].each_with_index do |line, num|
160
+ num += start_line
161
+ if num == e.line
162
+ STDERR.printf("%04d> %s\n".red, num, line)
163
+ else
164
+ STDERR.printf("%04d| %s\n", num, line)
165
+ end
166
+
167
+ end
168
+ STDERR.puts "\n"
169
+ raise e
54
170
  end
55
171
  return resources
56
172
  end
@@ -68,41 +184,27 @@ class Biosphere
68
184
 
69
185
  def kube_apply_resource(client, resource)
70
186
  name = resource[:metadata][:name]
71
- resource_name = client.instance_variable_get("@entities")[resource[:kind].underscore_case].resource_name
72
- ns_prefix = client.build_namespace_prefix(resource[:metadata][:namespace])
73
-
74
187
  responses = []
75
188
  begin
76
- ret = client.rest_client[ns_prefix + resource_name]
77
- .post(resource.to_h.to_json, { 'Content-Type' => 'application/json' }.merge(client.instance_variable_get("@headers")))
78
- responses << {
79
- action: :post,
80
- resource: ns_prefix + resource_name + "/#{name}",
81
- body: JSON.parse(ret.body)
82
- }
83
- puts "Created resource #{ns_prefix + resource_name}/#{name}"
189
+ response = client.post(resource)
190
+ puts "Created resource #{response[:resource]}"
191
+ responses << response
84
192
 
85
193
  rescue RestClient::Conflict => e
86
- key = ns_prefix + resource_name + "/#{name}"
87
- rest = client.rest_client[key]
88
-
89
- ret = rest.get(client.instance_variable_get("@headers"))
90
- current_data = JSON.parse(ret.body, :symbolize_names => true)
91
- puts "Updating resource #{key}"
92
- headers = { 'Content-Type' => 'application/json' }.merge(client.instance_variable_get("@headers"))
93
- update_resource = resource.dup
94
- update_resource.delete_field(:apiVersion)
95
- current_data.merge(update_resource)
96
- pp current_data.to_h
194
+ response = client.get(resource)
195
+ puts "Updating resource #{response[:resource]}"
196
+
197
+ # Get the current full resource from apiserver
198
+ update_resource = response[:body]
199
+
200
+ # Merge the updates on top of it
201
+ update_resource.merge(resource)
202
+
203
+ # Remove fields which apiserver refuses to accept in PUT requests
204
+ update_resource.delete(:apiVersion)
97
205
 
98
206
  begin
99
- ret = rest.put(current_data.to_h.to_json, headers)
100
- responses << {
101
- action: :put,
102
- resource: key,
103
- body: JSON.parse(ret.body)
104
- }
105
-
207
+ responses << client.put(update_resource)
106
208
  rescue RestClient::Exception => e
107
209
  puts "Error updating resource: #{e} #{e.class}"
108
210
  pp JSON.parse(e.response)
@@ -1,3 +1,3 @@
1
1
  class Biosphere
2
- Version = "0.0.9"
2
+ Version = "0.0.10"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: biosphere
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juho Mäkinen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-08 00:00:00.000000000 Z
11
+ date: 2016-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.3.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: colorize
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.8.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.8.1
83
97
  description: "Terraform's HCL lacks quite many programming features like iterators,
84
98
  true variables, advanced string manipulation, functions etc.\n\n This Ruby tool
85
99
  provides an easy-to-use DSL to define Terraform compatible .json files which can