zillabyte-cli 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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