zillabyte-cli 0.0.24 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +6 -14
  2. data/lib/#zillabyte-cli.rb# +5 -0
  3. data/lib/zillabyte/api/apps.rb +16 -132
  4. data/lib/zillabyte/api/components.rb +115 -0
  5. data/lib/zillabyte/api/flows.rb +121 -0
  6. data/lib/zillabyte/api/keys.rb +70 -0
  7. data/lib/zillabyte/api.rb +15 -2
  8. data/lib/zillabyte/auth.rb +43 -16
  9. data/lib/zillabyte/cli/#logs.rb# +12 -0
  10. data/lib/zillabyte/cli/#repl.rb# +43 -0
  11. data/lib/zillabyte/cli/apps.rb +52 -893
  12. data/lib/zillabyte/cli/auth.rb +3 -8
  13. data/lib/zillabyte/cli/base.rb +28 -7
  14. data/lib/zillabyte/cli/components.rb +245 -0
  15. data/lib/zillabyte/cli/flows.rb +549 -0
  16. data/lib/zillabyte/cli/git.rb +38 -0
  17. data/lib/zillabyte/cli/help.rb +11 -4
  18. data/lib/zillabyte/cli/keys.rb +177 -0
  19. data/lib/zillabyte/cli/query.rb +0 -1
  20. data/lib/zillabyte/cli/relations.rb +2 -1
  21. data/lib/zillabyte/cli/templates/{js → apps/js}/simple_function.js +0 -0
  22. data/lib/zillabyte/cli/templates/{js → apps/js}/zillabyte.conf.yaml +0 -0
  23. data/lib/zillabyte/cli/templates/apps/python/app.py +17 -0
  24. data/lib/zillabyte/cli/templates/{python → apps/python}/requirements.txt +0 -0
  25. data/lib/zillabyte/cli/templates/{python → apps/python}/zillabyte.conf.yaml +1 -1
  26. data/lib/zillabyte/cli/templates/{ruby → apps/ruby}/Gemfile +0 -0
  27. data/lib/zillabyte/cli/templates/{ruby → apps/ruby}/app.rb +1 -1
  28. data/lib/zillabyte/cli/templates/{ruby → apps/ruby}/zillabyte.conf.yaml +0 -0
  29. data/lib/zillabyte/cli/templates/python/{simple_function.py → #simple_function.py#} +3 -6
  30. data/lib/zillabyte/common/session.rb +3 -1
  31. data/lib/zillabyte/helpers.rb +64 -1
  32. data/lib/zillabyte/runner/app_runner.rb +226 -0
  33. data/lib/zillabyte/runner/component_operation.rb +529 -0
  34. data/lib/zillabyte/runner/component_runner.rb +244 -0
  35. data/lib/zillabyte/runner/multilang_operation.rb +1133 -0
  36. data/lib/zillabyte/runner/operation.rb +11 -0
  37. data/lib/zillabyte/runner.rb +6 -0
  38. data/lib/zillabyte-cli/version.rb +1 -1
  39. data/zillabyte-cli.gemspec +1 -0
  40. metadata +83 -52
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NzQ3YzkyMjYxM2QzZTIzMWVlZmNlNzQ2NTc2MWE2ODkxZTA2NGM1Ng==
5
- data.tar.gz: !binary |-
6
- NjlkZmQ0ODY0Y2EyYTM1ZDRiZWQ4YmQ5Zjk0NzFlOWRkNTMxY2QzMg==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- N2UxNmUyZjlkZGZhZWZkNjM3MzM2MmE5YWM5MzBmMjMyZDc3N2UzNDI3ZDYz
10
- NWNmYjhhODM0NmExYzI1ZTVkODgxMjZlOTcyN2NmNWRjZjI2MGQ3NjAwNzI1
11
- MzQxZGZlYzA5YzI0OThlNWJjZTI5YzU3MmI3MzI1MmVmY2Q2YjM=
12
- data.tar.gz: !binary |-
13
- N2YxNzllMGY3MzYyZGQ5MzgyZDJiZmZkZTcyNmY5Mzk1NmQxODM1NDI1YjUz
14
- NjEyMzNmM2ZlMzQ2NTAwMmMxOGY3MWRkNmQxNjM0OGI3YTFhZTZlMTlmMTA4
15
- OTgzZWFjNDNkNTBjMDE3MGEyMzY5ZjU4OThhNjA5ZDhhMmI4MWQ=
2
+ SHA1:
3
+ metadata.gz: 54c7334eca6bc7a0ee7d5b20093411539b51b891
4
+ data.tar.gz: 6239db222616513ebc77fbfadf8c3484d215800a
5
+ SHA512:
6
+ metadata.gz: 1a3382cdff1fa803334611716c351f8bd27ce899b43180713331ef6f8e37279b38accbf100126ad9cd0b48b3df3217c9dc8ffbc420725950d61d716e35773da0
7
+ data.tar.gz: e0a1dceff8dd68bf110c403979b42224d06ebb07415e58f7eb5446c5a1a4bf3ba5936d0d059ace0bacd105ad4cc9602218f882975f8327eb92528df29f66e49f
@@ -0,0 +1,5 @@
1
+ require "zillabyte-cli/version"
2
+ require "zillabyte/api"
3
+ require "zillabyte/cli"
4
+ require "zillabyte/common"
5
+ require "zillabyte/queries"
@@ -1,7 +1,8 @@
1
1
  require 'net/http'
2
2
  require 'zillabyte/cli/config'
3
+ require 'zillabyte/api/flows'
3
4
 
4
- class Zillabyte::API::Apps < Zillabyte::API::Base
5
+ class Zillabyte::API::Apps < Zillabyte::API::Flows
5
6
 
6
7
 
7
8
  # GET /apps
@@ -14,7 +15,7 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
14
15
  res = @api.request(
15
16
  :expects => 200,
16
17
  :method => :get,
17
- :path => "/flows",
18
+ :path => "/apps",
18
19
  :body => options.to_json
19
20
  )
20
21
 
@@ -23,7 +24,7 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
23
24
  end
24
25
 
25
26
 
26
- # GET /flows/id
27
+ # GET /apps/id
27
28
  def get(id, options = {})
28
29
 
29
30
  options = {
@@ -33,48 +34,37 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
33
34
  res = @api.request(
34
35
  :expects => 200,
35
36
  :method => :get,
36
- :path => "/flows/#{id}",
37
+ :path => "/apps/#{id}",
37
38
  :body => options.to_json
38
39
  )
39
40
 
40
41
  res.body
41
42
 
42
43
  end
43
-
44
44
 
45
- # GET /flows/id/kill
45
+ # POST /apps/id/kill
46
46
  def kill(id, options = {})
47
47
 
48
48
  options = {
49
49
  # TODO
50
50
  }.merge(options)
51
-
51
+
52
52
  res = @api.request(
53
53
  :expects => 200,
54
54
  :method => :post,
55
- :path => "/flows/#{id}/kill",
56
- :body => options.to_json
55
+ :path => "/apps/#{id}/kill",
56
+ :body => options.to_json
57
57
  )
58
-
58
+
59
59
  res.body
60
60
 
61
61
  end
62
62
 
63
- def delete(id, options ={})
64
- res = @api.request(
65
- :expects => 200,
66
- :method => :delete,
67
- :path => "/flows/#{id}",
68
- :body => options.to_json
69
- )
70
- res.body
71
- end
72
-
73
63
  def list_cycles(id, options={})
74
64
  res = @api.request(
75
65
  :expects => 200,
76
66
  :method => :get,
77
- :path => "/flows/#{id}/cycles",
67
+ :path => "/apps/#{id}/cycles",
78
68
  :body => options.to_json
79
69
  )
80
70
  res.body
@@ -85,7 +75,7 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
85
75
  res = @api.request(
86
76
  :expects => 200,
87
77
  :method => :post,
88
- :path => "/flows/#{id}/cycles",
78
+ :path => "/apps/#{id}/cycles",
89
79
  :body => options.to_json
90
80
  )
91
81
  res.body
@@ -95,7 +85,7 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
95
85
  res = @api.request(
96
86
  :expects => 200,
97
87
  :method => :post,
98
- :path => "/flows/#{id}/cycles/run_forever",
88
+ :path => "/apps/#{id}/cycles/run_forever",
99
89
  :body => options.to_json
100
90
  )
101
91
  res.body
@@ -105,61 +95,13 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
105
95
  res = @api.request(
106
96
  :expects => 200,
107
97
  :method => :get,
108
- :path => "/flows/#{id}/cycles/cycles_poll",
98
+ :path => "/apps/#{id}/cycles/cycles_poll",
109
99
  :body => options.to_json
110
100
  )
111
101
  res.body
112
102
  end
113
103
 
114
104
 
115
- # GET /flows/id/download
116
- def pull_to_directory(id, dir, session = nil, options = {})
117
-
118
- # Get the resource. note query params
119
- type = options[:output_type]
120
- session.display "downloading ##{id}" if session && type.nil?
121
- res = @api.request(
122
- :expects => 200,
123
- :method => :get,
124
- :path => "/flows/#{id}/download",
125
- :body => options.to_json
126
- )
127
-
128
- hash = res.body
129
- unless hash['status'] == 'error'
130
- if(hash['tar'])
131
- session.display "unpacking to #{dir}" if type.nil?
132
- tar = StringIO.new(Base64.decode64(hash['tar']))
133
- hash.delete('tar')
134
- Zillabyte::Common::Tar.untar(tar, dir)
135
- #If you get an uri instead of the tar, then download the file directly from s3
136
- elsif(hash['uri'])
137
- session.display "downloading ##{id} to #{dir}" if type.nil?
138
- uri = URI(hash['uri'])
139
- try_again = 1
140
- while(try_again)
141
- Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
142
- request = Net::HTTP::Get.new(uri.request_uri)
143
- response = http.request(request)
144
- if response.code.to_i >= 300
145
- try_again = 1
146
- break
147
- end
148
- tar = StringIO.new(response.body)
149
- Zillabyte::Common::Tar.untar(tar, dir)
150
- try_again = nil
151
- end
152
- end
153
- hash.delete('uri')
154
- end
155
- end
156
-
157
- hash
158
-
159
- end
160
-
161
-
162
-
163
105
  # POST /apps
164
106
  #
165
107
  def push_directory(dir, session = nil, options = {})
@@ -167,7 +109,7 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
167
109
  type = options[:output_type]
168
110
  # Get the meta info
169
111
  options[:local_flag] = 1
170
- hash = Zillabyte::API::Apps.get_rich_meta_info_from_script(dir, session, options)
112
+ hash = Zillabyte::API::Flows.get_rich_meta_info_from_script(dir, session, options)
171
113
  if hash.nil?
172
114
  session.error("unable to extract app meta information", type) if session
173
115
  end
@@ -199,7 +141,7 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
199
141
  res = @api.request(
200
142
  :expects => 200,
201
143
  :method => :post,
202
- :path => "/flows",
144
+ :path => "/apps",
203
145
  :body => options.to_json
204
146
  )
205
147
 
@@ -228,62 +170,4 @@ class Zillabyte::API::Apps < Zillabyte::API::Base
228
170
 
229
171
  end
230
172
 
231
- ####################################################IMPORTANT####################################################
232
- # #
233
- # get_rich_meta_info_from_script only works with zillabyte apps:push now! The pipe "info_to_ruby.in" is #
234
- # hardcoded as the meta info passing pipe, so if 2 processes are trying to access it simultaneously there might #
235
- # be problems since it gets created/destroyed within this script (attempting to create a fifo that already #
236
- # exists or deleting a fifo that still has information in it may occur). #
237
- # #
238
- ####################################################IMPORTANT####################################################
239
- def self.get_rich_meta_info_from_script(dir, session = nil, options = {})
240
- hash = Zillabyte::CLI::Config.get_config_info(dir, session, options)
241
- if hash.nil?
242
- return {"status" => "error", "error" => "invalid_directory", "error_message" => "The specified directory (#{dir}) does not appear to contain a valid Zillabyte configuration file."}
243
- end
244
-
245
- type = options[:output_type]
246
-
247
- full_script = File.join(dir, hash['script'])
248
- command = nil
249
-
250
-
251
- info_file = "#{dir}/#{SecureRandom.uuid}"
252
- arg = "--info --file #{info_file}"
253
-
254
-
255
- case hash["language"]
256
- when "ruby"
257
- command = "cd \"#{dir}\"; unset BUNDLE_GEMFILE; ZILLABYTE_HARNESS=1 bundle exec ruby \"#{full_script}\" #{arg}"
258
- command = "cd \"#{dir}\"; unset BUNDLE_GEMFILE; ZILLABYTE_HARNESS=1 bundle exec ruby \"#{full_script}\" #{arg}"
259
- when "python"
260
- if(File.directory?("#{dir}/vEnv"))
261
- command = "cd \"#{dir}\"; PYTHONPATH=~/zb1/multilang/python/Zillabyte #{dir}/vEnv/bin/python \"#{full_script}\" #{arg}"
262
- else
263
- command = "cd \"#{dir}\"; PYTHONPATH=~/zb1/multilang/python/Zillabyte python \"#{full_script}\" #{arg}"
264
- end
265
- when "js"
266
- #command = "#{Zillabyte::API::CASPERJS_BIN} #{Zillabyte::API::API_CLIENT_JS} \"#{full_script}\" --info"
267
- command = "cd \"#{dir}\"; NODE_PATH=~/zb1/multilang/js/src/lib #{Zillabyte::API::NODEJS_BIN} \"#{full_script}\" #{arg}"
268
- else
269
- session.error "unsupported language: #{hash["language"]}" if session
270
- return nil
271
- end
272
-
273
- results = Zillabyte::Command::Apps.get_info(command, info_file, dir, options)
274
-
275
- begin
276
- meta = JSON.parse(results.split("\n").first.strip) # Throws error if invalid json
277
- rescue Exception => e
278
- session.error("the underlying app did not return a valid result. command: #{command} error: #{e.message}", type) if session
279
- exit
280
- end
281
-
282
-
283
- # Merge with the new info
284
- return hash.merge(meta)
285
-
286
- end
287
-
288
-
289
173
  end
@@ -0,0 +1,115 @@
1
+ require 'net/http'
2
+ require 'zillabyte/cli/config'
3
+ require 'zillabyte/api/flows'
4
+
5
+ class Zillabyte::API::Components < Zillabyte::API::Flows
6
+
7
+
8
+ # GET /apps
9
+ def list(options = {})
10
+
11
+ options = {
12
+ # TODO
13
+ }.merge(options)
14
+
15
+ res = @api.request(
16
+ :expects => 200,
17
+ :method => :get,
18
+ :path => "/components",
19
+ :body => options.to_json
20
+ )
21
+
22
+ body = res.body
23
+ body.map do |component|
24
+ next if component["schema"].nil?
25
+
26
+ inputs = ""
27
+ outputs = ""
28
+
29
+ nodes = component["schema"]["nodes"]
30
+ nodes.each do |node|
31
+ if node["type"] == "source"
32
+ inputs += "#{node["name"]}:\n"
33
+ node["fields"].each do |field|
34
+ inputs += " (#{field.keys[0]}, #{field.values[0].upcase})\n"
35
+ end
36
+ elsif node["type"] == "sink"
37
+ outputs += "#{node["name"]}:\n"
38
+ node["columns"].each do |field|
39
+ outputs += " (#{field.keys[0]}, #{field.values[0].upcase})\n"
40
+ end
41
+ end
42
+ end
43
+
44
+ component["inputs"] = inputs
45
+ component["outputs"] = outputs
46
+ end
47
+
48
+ body
49
+
50
+ end
51
+
52
+ # GET /components/id
53
+ def get(id, options = {})
54
+
55
+ options = {
56
+ # TODO
57
+ }.merge(options)
58
+
59
+ res = @api.request(
60
+ :expects => 200,
61
+ :method => :get,
62
+ :path => "/components/#{id}",
63
+ :body => options.to_json
64
+ )
65
+
66
+ res.body
67
+
68
+ end
69
+
70
+
71
+ # POST /components/id/execute
72
+ def rpc(id, options = {})
73
+
74
+ res = @api.request(
75
+ :expects => 200,
76
+ :method => :post,
77
+ :path => "/components/#{id}/execute",
78
+ :body => options.to_json
79
+ )
80
+
81
+ res.body
82
+ end
83
+
84
+ # GET /components/id/execute
85
+ def get_rpc_results(id, options = {})
86
+
87
+ res = @api.request(
88
+ :expects => 200,
89
+ :method => :get,
90
+ :path => "/components/#{id}/execute",
91
+ :body => options.to_json
92
+ )
93
+
94
+ res.body
95
+ end
96
+
97
+ # POST /components/id/kill
98
+ def kill(id, options = {})
99
+
100
+ options = {
101
+ # TODO
102
+ }.merge(options)
103
+
104
+ res = @api.request(
105
+ :expects => 200,
106
+ :method => :post,
107
+ :path => "/components/#{id}/kill",
108
+ :body => options.to_json
109
+ )
110
+
111
+ res.body
112
+
113
+ end
114
+
115
+ end
@@ -0,0 +1,121 @@
1
+ require 'net/http'
2
+ require 'zillabyte/cli/config'
3
+
4
+ class Zillabyte::API::Flows < Zillabyte::API::Base
5
+
6
+ # DELETE /flows/id
7
+ def delete(id, options ={})
8
+ res = @api.request(
9
+ :expects => 200,
10
+ :method => :delete,
11
+ :path => "/flows/#{id}",
12
+ :body => options.to_json
13
+ )
14
+ res.body
15
+ end
16
+
17
+ # GET /flows/id/download
18
+ def pull_to_directory(id, dir, session = nil, options = {})
19
+
20
+ # Get the resource. note query params
21
+ type = options[:output_type]
22
+ session.display "downloading ##{id}" if session && type.nil?
23
+ res = @api.request(
24
+ :expects => 200,
25
+ :method => :get,
26
+ :path => "/flows/#{id}/download",
27
+ :body => options.to_json
28
+ )
29
+
30
+ hash = res.body
31
+ unless hash['status'] == 'error'
32
+ if(hash['tar'])
33
+ session.display "unpacking to #{dir}" if type.nil?
34
+ tar = StringIO.new(Base64.decode64(hash['tar']))
35
+ hash.delete('tar')
36
+ Zillabyte::Common::Tar.untar(tar, dir)
37
+ #If you get an uri instead of the tar, then download the file directly from s3
38
+ elsif(hash['uri'])
39
+ session.display "downloading ##{id} to #{dir}" if type.nil?
40
+ uri = URI(hash['uri'])
41
+ try_again = 1
42
+ while(try_again)
43
+ Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
44
+ request = Net::HTTP::Get.new(uri.request_uri)
45
+ response = http.request(request)
46
+ if response.code.to_i >= 300
47
+ try_again = 1
48
+ break
49
+ end
50
+ tar = StringIO.new(response.body)
51
+ Zillabyte::Common::Tar.untar(tar, dir)
52
+ try_again = nil
53
+ end
54
+ end
55
+ hash.delete('uri')
56
+ end
57
+ end
58
+
59
+ hash
60
+
61
+ end
62
+
63
+ ####################################################IMPORTANT####################################################
64
+ # #
65
+ # get_rich_meta_info_from_script only works with zillabyte apps:push now! The pipe "info_to_ruby.in" is #
66
+ # hardcoded as the meta info passing pipe, so if 2 processes are trying to access it simultaneously there might #
67
+ # be problems since it gets created/destroyed within this script (attempting to create a fifo that already #
68
+ # exists or deleting a fifo that still has information in it may occur). #
69
+ # #
70
+ ####################################################IMPORTANT####################################################
71
+ def self.get_rich_meta_info_from_script(dir, session = nil, options = {})
72
+ hash = Zillabyte::CLI::Config.get_config_info(dir, session, options)
73
+ if hash.nil?
74
+ return {"status" => "error", "error" => "invalid_directory", "error_message" => "The specified directory (#{dir}) does not appear to contain a valid Zillabyte configuration file."}
75
+ end
76
+
77
+ type = options[:output_type]
78
+
79
+ full_script = File.join(dir, hash['script'])
80
+ command = nil
81
+
82
+
83
+ info_file = "#{dir}/#{SecureRandom.uuid}"
84
+ arg = "--info --file #{info_file}"
85
+
86
+
87
+ case hash["language"]
88
+ when "ruby"
89
+ command = "cd \"#{dir}\"; unset BUNDLE_GEMFILE; ZILLABYTE_HARNESS=1 bundle exec ruby \"#{full_script}\" #{arg}"
90
+ command = "cd \"#{dir}\"; unset BUNDLE_GEMFILE; ZILLABYTE_HARNESS=1 bundle exec ruby \"#{full_script}\" #{arg}"
91
+ when "python"
92
+ if(File.directory?("#{dir}/vEnv"))
93
+ command = "cd \"#{dir}\"; PYTHONPATH=~/zb1/multilang/python/Zillabyte #{dir}/vEnv/bin/python \"#{full_script}\" #{arg}"
94
+ else
95
+ command = "cd \"#{dir}\"; PYTHONPATH=~/zb1/multilang/python/Zillabyte python \"#{full_script}\" #{arg}"
96
+ end
97
+ when "js"
98
+ #command = "#{Zillabyte::API::CASPERJS_BIN} #{Zillabyte::API::API_CLIENT_JS} \"#{full_script}\" --info"
99
+ command = "cd \"#{dir}\"; NODE_PATH=~/zb1/multilang/js/src/lib #{Zillabyte::API::NODEJS_BIN} \"#{full_script}\" #{arg}"
100
+ else
101
+ session.error "unsupported language: #{hash["language"]}" if session
102
+ return nil
103
+ end
104
+
105
+ results = Zillabyte::Command::Flows.get_info(command, info_file, dir, options)
106
+
107
+ begin
108
+ meta = JSON.parse(results.split("\n").first.strip) # Throws error if invalid json
109
+ rescue Exception => e
110
+ session.error("the underlying app did not return a valid result. command: #{command} error: #{e.message}", type) if session
111
+ exit
112
+ end
113
+
114
+
115
+ # Merge with the new info
116
+ return hash.merge(meta)
117
+
118
+ end
119
+
120
+
121
+ end
@@ -0,0 +1,70 @@
1
+ require 'net/http'
2
+
3
+ class Zillabyte::API::Keys < Zillabyte::API::Base
4
+
5
+ def request(options = {})
6
+ new_headers = @api.headers.merge("Content-Type" => "text/plain")
7
+ new_options = options.merge(headers: new_headers)
8
+ @api.request(new_options)
9
+ end
10
+ private(:request)
11
+
12
+ # PUT /keys/:name
13
+ def add(name, key)
14
+ response = request(
15
+ body: key,
16
+ expects: 200,
17
+ method: :put,
18
+ path: "/keys/#{CGI.escape(name)}",
19
+ )
20
+ body = response.body
21
+ body["body"]
22
+ end
23
+
24
+ # GET /keys/:name
25
+ def show(name)
26
+ response = request(
27
+ expects: 200,
28
+ method: :get,
29
+ path: "/keys/#{CGI.escape(name)}",
30
+ )
31
+ body = response.body
32
+ body["body"]
33
+ end
34
+
35
+ # DELETE /keys/:name
36
+ def remove(name, key_data)
37
+ response = request(
38
+ expects: 200,
39
+ method: :delete,
40
+ path: "/keys/#{CGI.escape(name)}",
41
+ query: {
42
+ key_data: key_data,
43
+ },
44
+ )
45
+ body = response.body
46
+ body["body"]
47
+ end
48
+
49
+ # GET /keys
50
+ def list()
51
+ response = request(
52
+ expects: 200,
53
+ method: :get,
54
+ path: "/keys",
55
+ )
56
+ body = response.body
57
+ body
58
+ end
59
+
60
+ # DELETE /keys
61
+ def clear()
62
+ response = request(
63
+ expects: 200,
64
+ method: :delete,
65
+ path: "/keys",
66
+ )
67
+ body = response.body
68
+ body["body"]
69
+ end
70
+ end
data/lib/zillabyte/api.rb CHANGED
@@ -184,8 +184,11 @@ class Zillabyte::API
184
184
  def logs
185
185
  @_logs ||= ::Zillabyte::API::Logs.new(self)
186
186
  end
187
-
188
-
187
+
188
+ def keys
189
+ @_keys ||= ::Zillabyte::API::Keys.new(self)
190
+ end
191
+
189
192
  def queries
190
193
  @_queries ||= ::Zillabyte::API::Queries.new(self)
191
194
  end
@@ -195,7 +198,17 @@ class Zillabyte::API
195
198
  @_apps ||= ::Zillabyte::API::Apps.new(self)
196
199
  end
197
200
  alias_method :app, :apps
201
+
202
+ def flows
203
+ @_flows || ::Zillabyte::API::Flows.new(self)
204
+ end
205
+ alias_method :flow, :flows
198
206
 
207
+ def components
208
+ @_components ||= ::Zillabyte::API::Components.new(self)
209
+ end
210
+ alias_method :component, :components
211
+
199
212
  def metrics
200
213
  @_metrics ||= ::Zillabyte::API::Metrics.new(self)
201
214
  end