zillabyte-cli 0.0.9

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.
Files changed (53) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +20 -0
  4. data/README.md +29 -0
  5. data/bin/zillabyte +18 -0
  6. data/lib/zillabyte/api/base.rb +11 -0
  7. data/lib/zillabyte/api/data.rb +126 -0
  8. data/lib/zillabyte/api/flows.rb +239 -0
  9. data/lib/zillabyte/api/locks.rb +4 -0
  10. data/lib/zillabyte/api/logs.rb +32 -0
  11. data/lib/zillabyte/api/metrics.rb +48 -0
  12. data/lib/zillabyte/api/queries.rb +58 -0
  13. data/lib/zillabyte/api/semantic_tags.rb +24 -0
  14. data/lib/zillabyte/api/settings.rb +8 -0
  15. data/lib/zillabyte/api/sources.rb +28 -0
  16. data/lib/zillabyte/api/zillalogs.rb +66 -0
  17. data/lib/zillabyte/api.rb +170 -0
  18. data/lib/zillabyte/auth.rb +155 -0
  19. data/lib/zillabyte/cli/auth.rb +33 -0
  20. data/lib/zillabyte/cli/base.rb +161 -0
  21. data/lib/zillabyte/cli/config.rb +63 -0
  22. data/lib/zillabyte/cli/counters.rb +61 -0
  23. data/lib/zillabyte/cli/flows.rb +702 -0
  24. data/lib/zillabyte/cli/help.rb +137 -0
  25. data/lib/zillabyte/cli/helpers/data_schema_builder.rb +3 -0
  26. data/lib/zillabyte/cli/host.rb +21 -0
  27. data/lib/zillabyte/cli/logs.rb +118 -0
  28. data/lib/zillabyte/cli/query.rb +172 -0
  29. data/lib/zillabyte/cli/relations.rb +326 -0
  30. data/lib/zillabyte/cli/sources.rb +37 -0
  31. data/lib/zillabyte/cli/templates/js/simple_function.js +33 -0
  32. data/lib/zillabyte/cli/templates/js/zillabyte.conf.yaml +2 -0
  33. data/lib/zillabyte/cli/templates/python/requirements.txt +7 -0
  34. data/lib/zillabyte/cli/templates/python/simple_function.py +27 -0
  35. data/lib/zillabyte/cli/templates/python/zillabyte.conf.yaml +4 -0
  36. data/lib/zillabyte/cli/templates/ruby/Gemfile +3 -0
  37. data/lib/zillabyte/cli/templates/ruby/simple_function.rb +36 -0
  38. data/lib/zillabyte/cli/templates/ruby/zillabyte.conf.yaml +2 -0
  39. data/lib/zillabyte/cli/version.rb +11 -0
  40. data/lib/zillabyte/cli/zillalogs.rb +86 -0
  41. data/lib/zillabyte/cli.rb +37 -0
  42. data/lib/zillabyte/command.rb +254 -0
  43. data/lib/zillabyte/common/progress.rb +17 -0
  44. data/lib/zillabyte/common/tar.rb +102 -0
  45. data/lib/zillabyte/common.rb +13 -0
  46. data/lib/zillabyte/helpers.rb +49 -0
  47. data/lib/zillabyte/queries.rb +39 -0
  48. data/lib/zillabyte-cli/version.rb +5 -0
  49. data/lib/zillabyte-cli.rb +5 -0
  50. data/zillabyte-cli.gemspec +42 -0
  51. data/zillabyte_emails.csv +1 -0
  52. data/zillaconf.json +3 -0
  53. metadata +278 -0
@@ -0,0 +1,66 @@
1
+
2
+ class Zillabyte::API::Zillalogs < Zillabyte::API::Base
3
+
4
+
5
+ # GET /zillalogs
6
+ def list(options = {})
7
+
8
+ options = {
9
+ # TODO
10
+ }.merge(options)
11
+
12
+ res = @api.request(
13
+ :expects => 200,
14
+ :method => :get,
15
+ :path => "/zillalogs"
16
+ )
17
+
18
+ res.body
19
+
20
+ end
21
+
22
+
23
+ # GET /zillalogs/id
24
+ def find(id, progress = nil, options = {})
25
+
26
+ # Get the resource
27
+ res = @api.request(
28
+ :expects => 200,
29
+ :method => :get,
30
+ :path => "/zillalogs/#{id}"
31
+ )
32
+
33
+ res.body
34
+
35
+ end
36
+
37
+
38
+
39
+
40
+ # POST /zillalogs
41
+ def save(id, name, zillalog, options = {})
42
+
43
+ options = {
44
+ :name => name,
45
+ :zillalog => zillalog
46
+ }.merge(options)
47
+
48
+ options[:id] = id if id
49
+
50
+ res = @api.request(
51
+ :expects => 200,
52
+ :method => :post,
53
+ :path => "/zillalogs",
54
+ :body => options.to_json
55
+ )
56
+
57
+ res.body
58
+
59
+ end
60
+
61
+
62
+
63
+ protected
64
+
65
+
66
+ end
@@ -0,0 +1,170 @@
1
+ # load('zillabyte/helpers.rb') # reload helpers after possible inject_loadpath
2
+ # load('zillabyte/updater.rb') # reload updater after possible inject_loadpath
3
+
4
+ require "base64"
5
+ require "excon"
6
+ # require "securerandom"
7
+ require "uri"
8
+ require "zlib"
9
+ require "active_support/core_ext/object/to_query.rb"
10
+ require 'json'
11
+
12
+
13
+ # workaround for rescue/reraise to define errors in command.rb failing in 1.8.6
14
+ if RUBY_VERSION =~ /^1.8.6/
15
+ # require('zillabyte-api')
16
+ require('rest_client')
17
+ end
18
+
19
+ class Zillabyte::API
20
+
21
+ HEADERS = {
22
+ 'Accept' => 'application/json',
23
+ 'Content-Type' => 'application/json',
24
+ # 'Accept-Encoding' => 'gzip',
25
+ 'User-Agent' => "zillabyte/#{Zillabyte::CLI::VERSION}",
26
+ 'X-Ruby-Version' => RUBY_VERSION,
27
+ 'X-Ruby-Platform' => RUBY_PLATFORM
28
+ }
29
+
30
+ OPTIONS = {
31
+ :headers => {},
32
+ :host => ENV['ZILLABYTE_API_HOST'] || 'api.zillabyte.com',
33
+ :port => (ENV['ZILLABYTE_API_PORT'] || '80').to_i,
34
+ :nonblock => false,
35
+ :scheme => 'http'
36
+ }
37
+
38
+
39
+
40
+ def initialize(options={})
41
+ options = OPTIONS.merge(options)
42
+
43
+ @progress = options.delete(:progress)
44
+ @api_key = options.delete(:api_key) || ENV['ZILLABYTE_API_KEY']
45
+
46
+ options[:headers] = HEADERS.merge({
47
+ 'Authorization' => "auth_token #{@api_key}",
48
+ }).merge(options[:headers])
49
+
50
+ @options = options.clone
51
+ @options[:bubble_exceptions] = ENV['BUBBLE_EXCEPTIONS'] || false
52
+
53
+ @connection = Excon.new("#{options[:scheme]}://#{options[:host]}", options)
54
+
55
+ end
56
+
57
+
58
+ def host
59
+ @options[:host]
60
+ end
61
+
62
+
63
+ def request(params, &block)
64
+ begin
65
+ # The @connection object handles connections to api.zillabyte.com via Excon, this sends a command to the Rails api code
66
+ # with parameters in params (one of which contains the path to the method to be run in the form of a url, e.g. if the
67
+ # :path parameter is set to /functions/#{id}?tar=1, then the show method in functions_controller.rb will be automatically
68
+ # called...it will have it's own set of parameters which correspond to the items in the query string).
69
+ response = @connection.request(params, &block)
70
+ rescue Excon::Errors::HTTPStatusError => error
71
+ @progress.error "internal server error" if @progress
72
+ raise error
73
+ end
74
+
75
+ if response.body && !response.body.empty?
76
+ # decompress_response!(response)
77
+ begin
78
+ response.body = JSON.parse(response.body)
79
+ rescue Exception => e
80
+ raise e if @options[:bubble_exceptions]
81
+ @progress.error "unknown server response: \n #{response.body}" if @progress
82
+ end
83
+ end
84
+
85
+ # Errors?
86
+ if response.body.is_a?(Hash)
87
+ if response.body["status"] == "error"
88
+ if @progress
89
+ if response.body["error"] == "authentication_error"
90
+ @progress.error "authentication error. run 'zillabyte login'"
91
+ else
92
+ @progress.error response.body["error_message"]
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+
99
+ # reset (non-persistent) connection
100
+ @connection.reset
101
+
102
+ response
103
+ end
104
+
105
+
106
+ def data
107
+ @_data ||= ::Zillabyte::API::Data.new(self)
108
+ end
109
+
110
+ def logs
111
+ @_logs ||= ::Zillabyte::API::Logs.new(self)
112
+ end
113
+
114
+
115
+ def queries
116
+ @_queries ||= ::Zillabyte::API::Queries.new(self)
117
+ end
118
+ alias_method :query, :queries
119
+
120
+ def flows
121
+ @_flows ||= ::Zillabyte::API::Flows.new(self)
122
+ end
123
+ alias_method :flow, :flows
124
+
125
+ def metrics
126
+ @_metrics ||= ::Zillabyte::API::Metrics.new(self)
127
+ end
128
+ alias_method :metric, :metrics
129
+
130
+ def zillalogs
131
+ @_rules ||= ::Zillabyte::API::Zillalogs.new(self)
132
+ end
133
+ alias_method :zillalog, :zillalogs
134
+
135
+ def sources
136
+ @_sources ||= ::Zillabyte::API::Sources.new(self)
137
+ end
138
+ alias_method :source, :sources
139
+
140
+
141
+ def collectors
142
+ @_collectors ||= ::Zillabyte::API::Collectors.new(self)
143
+ end
144
+ alias_method :collector, :collectors
145
+
146
+ def semantic_tags
147
+ @_rules ||= ::Zillabyte::API::SemanticTags.new(self)
148
+ end
149
+ alias_method :zillalog, :zillalogs
150
+
151
+
152
+
153
+
154
+
155
+ def self.load
156
+ Dir[File.join(File.dirname(__FILE__), "api", "*.rb")].sort.each do |file|
157
+ require file
158
+ end
159
+
160
+ Dir[File.join(File.dirname(__FILE__), "api", "helpers", "*.rb")].sort.each do |file|
161
+ require file
162
+ end
163
+ end
164
+
165
+
166
+ end
167
+
168
+
169
+ # Load all helpers...
170
+ Zillabyte::API.load()
@@ -0,0 +1,155 @@
1
+ require "cgi"
2
+ require "zillabyte/helpers"
3
+
4
+ require "netrc"
5
+
6
+ class Zillabyte::Auth
7
+ class << self
8
+ include Zillabyte::Helpers
9
+
10
+ attr_accessor :credentials
11
+
12
+
13
+
14
+
15
+ def get_credentials!
16
+
17
+ end
18
+
19
+
20
+ def login
21
+ delete_credentials
22
+ get_credentials
23
+ end
24
+
25
+ def logout
26
+ delete_credentials
27
+ end
28
+
29
+ # just a stub; will raise if not authenticated
30
+ # def check
31
+ # api.get_user
32
+ # end
33
+
34
+ def default_host
35
+ ENV['ZILLABYTE_API_HOST'] || 'api.zillabyte.com'
36
+ end
37
+
38
+ def host
39
+ default_host
40
+ end
41
+
42
+ def reauthorize
43
+ @credentials = ask_for_and_save_credentials
44
+ end
45
+
46
+ # def user # :nodoc:
47
+ # get_credentials[0]
48
+ # end
49
+
50
+ # def password # :nodoc:
51
+ # get_credentials[1]
52
+ # end
53
+
54
+ def api_key
55
+ get_credentials
56
+ end
57
+
58
+ def get_credentials # :nodoc:
59
+ @credentials ||= (read_credentials || ask_for_and_save_credentials)
60
+ end
61
+
62
+ def delete_credentials
63
+ netrc.delete(host)
64
+ netrc.save
65
+ @credentials = nil
66
+ end
67
+
68
+ def netrc_path
69
+ default = Netrc.default_path
70
+ encrypted = default + ".gpg"
71
+ if File.exists?(encrypted)
72
+ encrypted
73
+ else
74
+ default
75
+ end
76
+ end
77
+
78
+ def netrc # :nodoc:
79
+ @netrc ||= begin
80
+ Netrc.read(netrc_path)
81
+ rescue => error
82
+ if error.message =~ /^Permission bits for/
83
+ perm = File.stat(netrc_path).mode & 0777
84
+ abort("Permissions #{perm} for '#{netrc_path}' are too open. You should run `chmod 0600 #{netrc_path}` so that your credentials are NOT accessible by others.")
85
+ else
86
+ raise error
87
+ end
88
+ end
89
+ end
90
+
91
+ def read_credentials
92
+ if ENV['ZILLABYTE_API_KEY']
93
+ ENV['ZILLABYTE_API_KEY']
94
+ else
95
+ # read netrc credentials if they exist
96
+ if netrc
97
+ if netrc[host]
98
+ netrc[host][1]
99
+ else
100
+ nil
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ def write_credentials
107
+ FileUtils.mkdir_p(File.dirname(netrc_path))
108
+ FileUtils.touch(netrc_path)
109
+ netrc[host] = ["login", self.credentials]
110
+ netrc.save
111
+ end
112
+
113
+ def echo_off
114
+ with_tty do
115
+ system "stty -echo"
116
+ end
117
+ end
118
+
119
+ def echo_on
120
+ with_tty do
121
+ system "stty echo"
122
+ end
123
+ end
124
+
125
+ def ask_for_credentials
126
+ puts "Enter your Zillabyte credentials."
127
+ print "Email: "
128
+ $stdout.flush()
129
+ email = ask
130
+ print "Auth Token: "
131
+ $stdout.flush()
132
+ auth_token = ask
133
+ print "\n"
134
+
135
+ auth_token
136
+
137
+ end
138
+
139
+ def ask_for_and_save_credentials
140
+ begin
141
+ @credentials = ask_for_credentials
142
+ write_credentials
143
+ # check
144
+ end
145
+ @credentials
146
+ end
147
+
148
+ def retry_login?
149
+ @login_attempts ||= 0
150
+ @login_attempts += 1
151
+ @login_attempts < 3
152
+ end
153
+
154
+ end
155
+ end
@@ -0,0 +1,33 @@
1
+ require "zillabyte/cli/base"
2
+
3
+ # manage zillabyte accounts
4
+ #
5
+ class Zillabyte::Command::Auth < Zillabyte::Command::Base
6
+
7
+
8
+
9
+ # auth:login
10
+ #
11
+ # Sets the Zillabyte Auth token
12
+ #
13
+ def login
14
+ Zillabyte::Auth.login
15
+ end
16
+
17
+ alias_command "login", "auth:login"
18
+
19
+
20
+
21
+ # auth:logout
22
+ #
23
+ # Sets the Zillabyte Auth token
24
+ #
25
+ def logout
26
+ Zillabyte::Auth.logout
27
+ end
28
+
29
+ alias_command "logout", "auth:logout"
30
+
31
+
32
+
33
+ end
@@ -0,0 +1,161 @@
1
+ require "fileutils"
2
+ require "zillabyte/api"
3
+ require "zillabyte/command"
4
+
5
+ class Zillabyte::Command::Base
6
+ include Zillabyte::Helpers
7
+
8
+ def self.namespace
9
+ self.to_s.split("::").last.downcase
10
+ end
11
+
12
+ attr_reader :args
13
+ attr_reader :options
14
+
15
+ def initialize(args=[], options={})
16
+ @args = args
17
+ @options = options
18
+ end
19
+
20
+
21
+ protected
22
+
23
+ def self.inherited(klass)
24
+ unless klass == Zillabyte::Command::Base
25
+ help = extract_help_from_caller(caller.first)
26
+
27
+ Zillabyte::Command.register_namespace(
28
+ :name => klass.namespace,
29
+ :description => help.first
30
+ )
31
+ end
32
+ end
33
+
34
+ def self.method_added(method)
35
+ return if self == Zillabyte::Command::Base
36
+ return if private_method_defined?(method)
37
+ return if protected_method_defined?(method)
38
+
39
+ help = extract_help_from_caller(caller.first)
40
+ resolved_method = (method.to_s == "index") ? nil : method.to_s
41
+ command = [ self.namespace, resolved_method ].compact.join(":")
42
+ banner = extract_banner(help) || command
43
+
44
+ Zillabyte::Command.register_command(
45
+ :klass => self,
46
+ :method => method,
47
+ :namespace => self.namespace,
48
+ :command => command,
49
+ :banner => banner.strip,
50
+ :help => help.join("\n"),
51
+ :summary => extract_summary(help),
52
+ :description => extract_description(help),
53
+ :options => extract_options(help)
54
+ )
55
+
56
+ alias_command command.gsub(/_/, '-'), command if command =~ /_/
57
+ end
58
+
59
+
60
+
61
+ #
62
+ # Parse the caller format and identify the file and line number as identified
63
+ # in : http://www.ruby-doc.org/core/classes/Kernel.html#M001397. This will
64
+ # look for a colon followed by a digit as the delimiter. The biggest
65
+ # complication is windows paths, which have a colon after the drive letter.
66
+ # This regex will match paths as anything from the beginning to a colon
67
+ # directly followed by a number (the line number).
68
+ #
69
+ # Examples of the caller format :
70
+ # * c:/Ruby192/lib/.../lib/zillabyte/cli/addons.rb:8:in `<module:Command>'
71
+ # * c:/Ruby192/lib/.../zillabyte-2.0.1/lib/zillabyte/cli/pg.rb:96:in `<class:Pg>'
72
+ # * /Users/ph7/...../xray-1.1/lib/xray/thread_dump_signal_handler.rb:9
73
+ #
74
+ def self.extract_help_from_caller(line)
75
+ # pull out of the caller the information for the file path and line number
76
+ if line =~ /^(.+?):(\d+)/
77
+ extract_help($1, $2)
78
+ else
79
+ raise("unable to extract help from caller: #{line}")
80
+ end
81
+ end
82
+
83
+ def self.extract_help(file, line_number)
84
+ buffer = []
85
+ lines = Zillabyte::Command.files[file]
86
+
87
+ (line_number.to_i-2).downto(0) do |i|
88
+ line = lines[i]
89
+ case line[0..0]
90
+ when ""
91
+ when "#"
92
+ buffer.unshift(line[1..-1])
93
+ else
94
+ break
95
+ end
96
+ end
97
+
98
+ buffer
99
+ end
100
+
101
+
102
+ def self.extract_banner(help)
103
+ help.first
104
+ end
105
+
106
+ def self.extract_summary(help)
107
+ extract_description(help).split("\n")[2].to_s.split("\n").first
108
+ end
109
+
110
+ def self.extract_description(help)
111
+ help.reject do |line|
112
+ line =~ /^\s+-(.+)#(.+)/
113
+ end.join("\n")
114
+ end
115
+
116
+ def self.extract_options(help)
117
+ r = help.select do |line|
118
+ line =~ /^\s+-(.+)#(.+)/
119
+ end.inject([]) do |options, line|
120
+ args = line.split('#', 2).first
121
+ args = args.split(/,\s*/).map {|arg| arg.strip}.sort.reverse
122
+ name = args.last.split(' ', 2).first[2..-1]
123
+ options << { :name => name, :args => args }
124
+ end
125
+ end
126
+
127
+
128
+ def self.alias_command(new, old)
129
+ raise "no such command: #{old}" unless Zillabyte::Command.commands[old]
130
+ Zillabyte::Command.command_aliases[new] = old
131
+ end
132
+
133
+
134
+ def shift_argument
135
+ Zillabyte::Command.shift_argument
136
+ end
137
+
138
+ def validate_arguments!
139
+ Zillabyte::Command.validate_arguments!
140
+ end
141
+
142
+ def api
143
+ @__api ||= Zillabyte::API.new(:api_key => Zillabyte::Auth.api_key, :progress => self)
144
+ end
145
+
146
+
147
+
148
+ def progress
149
+ self
150
+ end
151
+
152
+
153
+ end
154
+
155
+
156
+
157
+ module Zillabyte::Command
158
+ unless const_defined?(:BaseWithApp)
159
+ BaseWithApp = Base
160
+ end
161
+ end
@@ -0,0 +1,63 @@
1
+ require 'yaml'
2
+
3
+ module Zillabyte
4
+
5
+ module CLI
6
+
7
+ module Config
8
+
9
+ DEFAULT_CONFIG_FILE = "zillabyte.conf.yaml"
10
+
11
+ ################################################################################
12
+
13
+ def self.get_config_info(dir, progress = nil, options = {})
14
+
15
+ conf_file = nil
16
+ if options[:config_file] and File.exists?(options[:config_file])
17
+ conf_file = options[:config_file]
18
+ else
19
+ conf_file = File.join(dir, options[:config_file] || DEFAULT_CONFIG_FILE)
20
+ end
21
+
22
+ return nil unless File.exists?(conf_file)
23
+ hash = YAML.load_file(conf_file)
24
+
25
+ # set other fields on the configuraiton
26
+ hash['pwd'] = dir
27
+
28
+ # The top_dir and rel_home_dir allows us to package up dependencies that
29
+ # belong to sibling directories (e.g. the collectors directory)
30
+ top_dir = File.expand_path(hash['top_dir'] || ".", dir)
31
+ top_path = Pathname.new(top_dir)
32
+ rel_dir = Pathname.new(dir).relative_path_from(top_path).to_s
33
+ ignore_files = if hash.has_key?("ignore_files")
34
+ ignore_files = hash["ignore_files"]
35
+ ignore_files_array = ignore_files.respond_to?(:to_a) ? ignore_files.to_a() : [ignore_files]
36
+ ignore_files_array.map { |path_arg|
37
+ # It's annoying to fail because of an improperly specified path, though that would be my preference,
38
+ # so we just warn. It would be nice if APIDock covered what exceptions can be raised, too--we probably
39
+ # don't want to catch all of them.
40
+ begin
41
+ path_string = path_arg.to_s()
42
+ path = Pathname.new(File.expand_path(path_string))
43
+ path.relative_path_from(top_path).to_s()
44
+ rescue Exception => e
45
+ progress.error e.message() + "\n" + e.backtrace.join("\n") if progress
46
+ nil
47
+ end
48
+ }.compact()
49
+ else
50
+ []
51
+ end
52
+ hash["rel_dir"] = rel_dir
53
+ hash['top_dir'] = top_dir
54
+ hash["home_dir"] = dir
55
+ hash["ignore_files"] = ignore_files
56
+
57
+ # Get the config
58
+ return hash
59
+
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,61 @@
1
+ # require "zillabyte/cli/base"
2
+ #
3
+ # # manage custom executables
4
+ # #
5
+ # class Zillabyte::Command::Metrics < Zillabyte::Command::Base
6
+ #
7
+ #
8
+ # # metrics
9
+ # #
10
+ # #
11
+ # def index
12
+ # self.list
13
+ # end
14
+ #
15
+ #
16
+ #
17
+ #
18
+ # # metrics
19
+ # #
20
+ # # list custom metrics
21
+ # #
22
+ # def list
23
+ #
24
+ #
25
+ # headings = []
26
+ # rows = api.metrics.list.map do |row|
27
+ # headings = row.keys if headings.size == 0
28
+ # row.values_at *headings
29
+ # end
30
+ # display "metrics:\n" + Terminal::Table.new(:headings => headings, :rows => rows).to_s
31
+ #
32
+ # end
33
+ #
34
+ #
35
+ #
36
+ #
37
+ #
38
+ # # metrics:show NAME
39
+ # #
40
+ # # shows the latest metric
41
+ # #
42
+ # # -t, --tail # continuously watches for new results
43
+ # #
44
+ # def show
45
+ #
46
+ # opts = {}
47
+ # name = options[:name] || shift_argument
48
+ #
49
+ # if name.nil?
50
+ # error "no name given"
51
+ # end
52
+ #
53
+ # res = api.metrics.show(name)
54
+ # puts res
55
+ #
56
+ # end
57
+ #
58
+ #
59
+ #
60
+ #
61
+ # end