zillabyte-cli 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +29 -0
- data/bin/zillabyte +18 -0
- data/lib/zillabyte/api/base.rb +11 -0
- data/lib/zillabyte/api/data.rb +126 -0
- data/lib/zillabyte/api/flows.rb +239 -0
- data/lib/zillabyte/api/locks.rb +4 -0
- data/lib/zillabyte/api/logs.rb +32 -0
- data/lib/zillabyte/api/metrics.rb +48 -0
- data/lib/zillabyte/api/queries.rb +58 -0
- data/lib/zillabyte/api/semantic_tags.rb +24 -0
- data/lib/zillabyte/api/settings.rb +8 -0
- data/lib/zillabyte/api/sources.rb +28 -0
- data/lib/zillabyte/api/zillalogs.rb +66 -0
- data/lib/zillabyte/api.rb +170 -0
- data/lib/zillabyte/auth.rb +155 -0
- data/lib/zillabyte/cli/auth.rb +33 -0
- data/lib/zillabyte/cli/base.rb +161 -0
- data/lib/zillabyte/cli/config.rb +63 -0
- data/lib/zillabyte/cli/counters.rb +61 -0
- data/lib/zillabyte/cli/flows.rb +702 -0
- data/lib/zillabyte/cli/help.rb +137 -0
- data/lib/zillabyte/cli/helpers/data_schema_builder.rb +3 -0
- data/lib/zillabyte/cli/host.rb +21 -0
- data/lib/zillabyte/cli/logs.rb +118 -0
- data/lib/zillabyte/cli/query.rb +172 -0
- data/lib/zillabyte/cli/relations.rb +326 -0
- data/lib/zillabyte/cli/sources.rb +37 -0
- data/lib/zillabyte/cli/templates/js/simple_function.js +33 -0
- data/lib/zillabyte/cli/templates/js/zillabyte.conf.yaml +2 -0
- data/lib/zillabyte/cli/templates/python/requirements.txt +7 -0
- data/lib/zillabyte/cli/templates/python/simple_function.py +27 -0
- data/lib/zillabyte/cli/templates/python/zillabyte.conf.yaml +4 -0
- data/lib/zillabyte/cli/templates/ruby/Gemfile +3 -0
- data/lib/zillabyte/cli/templates/ruby/simple_function.rb +36 -0
- data/lib/zillabyte/cli/templates/ruby/zillabyte.conf.yaml +2 -0
- data/lib/zillabyte/cli/version.rb +11 -0
- data/lib/zillabyte/cli/zillalogs.rb +86 -0
- data/lib/zillabyte/cli.rb +37 -0
- data/lib/zillabyte/command.rb +254 -0
- data/lib/zillabyte/common/progress.rb +17 -0
- data/lib/zillabyte/common/tar.rb +102 -0
- data/lib/zillabyte/common.rb +13 -0
- data/lib/zillabyte/helpers.rb +49 -0
- data/lib/zillabyte/queries.rb +39 -0
- data/lib/zillabyte-cli/version.rb +5 -0
- data/lib/zillabyte-cli.rb +5 -0
- data/zillabyte-cli.gemspec +42 -0
- data/zillabyte_emails.csv +1 -0
- data/zillaconf.json +3 -0
- 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
|