hotdog 0.0.3 → 0.0.4
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 +4 -4
- data/lib/hotdog/application.rb +4 -0
- data/lib/hotdog/commands/hosts.rb +10 -4
- data/lib/hotdog/commands/search.rb +45 -11
- data/lib/hotdog/commands/tags.rb +21 -7
- data/lib/hotdog/commands/update.rb +1 -0
- data/lib/hotdog/commands.rb +41 -15
- data/lib/hotdog/formatters/json.rb +1 -1
- data/lib/hotdog/formatters/plain.rb +6 -1
- data/lib/hotdog/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 933d32781a29b749befc75434934913bc85ca09a
|
4
|
+
data.tar.gz: ae79146d62e2da1110246485559571d8d43475a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5c3b0eb31180b6057bb3a6da9c077fbef40d79eb28ab46215b5ae60471df254c73011003f5795e07d2dbda1594326db25c8acdacad4e8e4425dbf54fef855ab
|
7
|
+
data.tar.gz: 7791194153534266e7768c0a1cd96d391fd274aab72a4e93b9ea6776515e0fa1b45b628f4e65ac84c8b9fab5d3b3d6fe73341f8b8ec47c054c1c3f61c88ef4a3
|
data/lib/hotdog/application.rb
CHANGED
@@ -16,6 +16,7 @@ module Hotdog
|
|
16
16
|
environment: "default",
|
17
17
|
minimum_expiry: 28800, # 8 hours
|
18
18
|
random_expiry: 604800, # 7 days
|
19
|
+
fixed_string: false,
|
19
20
|
force: false,
|
20
21
|
formatter: get_formatter("plain").new,
|
21
22
|
headers: false,
|
@@ -90,6 +91,9 @@ module Hotdog
|
|
90
91
|
@optparse.on("-E ENVIRONMENT", "--environment ENVIRONMENT", "Specify environment") do |environment|
|
91
92
|
options[:environment] = environment
|
92
93
|
end
|
94
|
+
@optparse.on("--fixed-string", "Interpret pattern as fixed string") do |v|
|
95
|
+
options[:fixed_string] = v
|
96
|
+
end
|
93
97
|
@optparse.on("-f", "--[no-]force", "Enable force mode") do |v|
|
94
98
|
options[:force] = v
|
95
99
|
end
|
@@ -7,29 +7,35 @@ module Hotdog
|
|
7
7
|
update_hosts(@options.dup)
|
8
8
|
|
9
9
|
if args.empty?
|
10
|
-
|
10
|
+
@hosts_q1 ||= @db.prepare(<<-EOS)
|
11
11
|
SELECT DISTINCT host_id FROM hosts_tags;
|
12
12
|
EOS
|
13
|
+
logger.debug("hosts_q1()")
|
14
|
+
result = @hosts_q1.execute().to_a.reduce(:+)
|
13
15
|
else
|
14
16
|
result = args.map { |host_name|
|
15
17
|
if host_name.index("*")
|
16
|
-
|
18
|
+
@hosts_q2 ||= @db.prepare(<<-EOS)
|
17
19
|
SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
|
18
20
|
INNER JOIN hosts ON hosts_tags.host_id = hosts.id
|
19
21
|
WHERE LOWER(hosts.name) GLOB LOWER(?);
|
20
22
|
EOS
|
23
|
+
logger.debug("hosts_q2(%s)" % [host_name.inspect])
|
24
|
+
@hosts_q2.execute(host_name).map { |row| row.first }
|
21
25
|
else
|
22
|
-
|
26
|
+
@hosts_q3 ||= @db.prepare(<<-EOS)
|
23
27
|
SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
|
24
28
|
INNER JOIN hosts ON hosts_tags.host_id = hosts.id
|
25
29
|
WHERE LOWER(hosts.name) = LOWER(?);
|
26
30
|
EOS
|
31
|
+
logger.debug("hosts_q3(%s)" % [host_name.inspect])
|
32
|
+
@hosts_q3.execute(host_name).map { |row| row.first }
|
27
33
|
end
|
28
34
|
}.reduce(:+)
|
29
35
|
end
|
30
36
|
if 0 < result.length
|
31
37
|
result, fields = get_hosts(result)
|
32
|
-
STDOUT.
|
38
|
+
STDOUT.print(format(result, fields: fields))
|
33
39
|
else
|
34
40
|
STDERR.puts("no match found: #{args.join(" ")}")
|
35
41
|
exit(1)
|
@@ -13,7 +13,6 @@ module Hotdog
|
|
13
13
|
end
|
14
14
|
|
15
15
|
update_hosts(@options.dup)
|
16
|
-
# update_tags(@options.dup)
|
17
16
|
|
18
17
|
begin
|
19
18
|
node = parse(expression)
|
@@ -24,7 +23,7 @@ module Hotdog
|
|
24
23
|
result = evaluate(node, self).sort
|
25
24
|
if 0 < result.length
|
26
25
|
result, fields = get_hosts(result)
|
27
|
-
STDOUT.
|
26
|
+
STDOUT.print(format(result, fields: fields))
|
28
27
|
else
|
29
28
|
STDERR.puts("no match found: #{args.join(" ")}")
|
30
29
|
exit(1)
|
@@ -70,13 +69,13 @@ module Hotdog
|
|
70
69
|
}
|
71
70
|
rule(:atom) {
|
72
71
|
( spacing.maybe >> str('(') >> expression >> str(')') >> spacing.maybe \
|
73
|
-
| spacing.maybe >> identifier_regexp.as(:identifier_regexp) >>
|
72
|
+
| spacing.maybe >> identifier_regexp.as(:identifier_regexp) >> separator >> attribute_regexp.as(:attribute_regexp) >> spacing.maybe \
|
74
73
|
| spacing.maybe >> identifier_regexp.as(:identifier_regexp) >> spacing.maybe \
|
75
|
-
| spacing.maybe >> identifier_glob.as(:identifier_glob) >>
|
76
|
-
| spacing.maybe >> identifier_glob.as(:identifier_glob) >>
|
74
|
+
| spacing.maybe >> identifier_glob.as(:identifier_glob) >> separator >> attribute_glob.as(:attribute_glob) >> spacing.maybe \
|
75
|
+
| spacing.maybe >> identifier_glob.as(:identifier_glob) >> separator >> attribute.as(:attribute) >> spacing.maybe \
|
77
76
|
| spacing.maybe >> identifier_glob.as(:identifier_glob) >> spacing.maybe \
|
78
|
-
| spacing.maybe >> identifier.as(:identifier)>>
|
79
|
-
| spacing.maybe >> identifier.as(:identifier)>>
|
77
|
+
| spacing.maybe >> identifier.as(:identifier)>> separator >> attribute_glob.as(:attribute_glob) >> spacing.maybe \
|
78
|
+
| spacing.maybe >> identifier.as(:identifier)>> separator >> attribute.as(:attribute) >> spacing.maybe \
|
80
79
|
| spacing.maybe >> identifier.as(:identifier) >> spacing.maybe \
|
81
80
|
)
|
82
81
|
}
|
@@ -92,6 +91,11 @@ module Hotdog
|
|
92
91
|
( match('[A-Za-z]') >> match('[-./0-9A-Z_a-z]').repeat(0) \
|
93
92
|
)
|
94
93
|
}
|
94
|
+
rule(:separator) {
|
95
|
+
( str(':') \
|
96
|
+
| str('=') \
|
97
|
+
)
|
98
|
+
}
|
95
99
|
rule(:attribute_regexp) {
|
96
100
|
( str('/') >> (str('/').absent? >> any).repeat(0) >> str('/') \
|
97
101
|
)
|
@@ -212,32 +216,47 @@ module Hotdog
|
|
212
216
|
end
|
213
217
|
def evaluate(environment)
|
214
218
|
if attribute?
|
215
|
-
environment.execute(<<-EOS, identifier, attribute).map { |row| row.first }
|
219
|
+
values = environment.execute(<<-EOS, identifier, attribute).map { |row| row.first }
|
216
220
|
SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
|
217
221
|
INNER JOIN tags ON hosts_tags.tag_id = tags.id
|
218
222
|
WHERE LOWER(tags.name) = LOWER(?) AND LOWER(tags.value) = LOWER(?);
|
219
223
|
EOS
|
220
224
|
else
|
221
|
-
environment.execute(<<-EOS, identifier, identifier, identifier).map { |row| row.first }
|
225
|
+
values = environment.execute(<<-EOS, identifier, identifier, identifier).map { |row| row.first }
|
222
226
|
SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
|
223
227
|
INNER JOIN hosts ON hosts_tags.host_id = hosts.id
|
224
228
|
INNER JOIN tags ON hosts_tags.tag_id = tags.id
|
225
229
|
WHERE LOWER(hosts.name) = LOWER(?) OR LOWER(tags.name) = LOWER(?) OR LOWER(tags.value) = LOWER(?);
|
226
230
|
EOS
|
227
231
|
end
|
232
|
+
if not environment.fixed_string? and values.empty?
|
233
|
+
# fallback to glob expression
|
234
|
+
identifier_glob = identifier.gsub(/[-.\/_]/, "?")
|
235
|
+
if identifier != identifier_glob
|
236
|
+
if attribute?
|
237
|
+
attribute_glob = attribute.gsub(/[-.\/:_]/, "?")
|
238
|
+
environment.logger.info("fallback to glob expression: %s:%s" % [identifier_glob, attribute_glob])
|
239
|
+
else
|
240
|
+
attribute_glob = nil
|
241
|
+
environment.logger.info("fallback to glob expression: %s" % [identifier_glob])
|
242
|
+
end
|
243
|
+
values = TagGlobExpressionNode.new(identifier_glob, attribute_glob).evaluate(environment)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
values
|
228
247
|
end
|
229
248
|
end
|
230
249
|
|
231
250
|
class TagGlobExpressionNode < TagExpressionNode
|
232
251
|
def evaluate(environment)
|
233
252
|
if attribute?
|
234
|
-
environment.execute(<<-EOS, identifier, attribute).map { |row| row.first }
|
253
|
+
values = environment.execute(<<-EOS, identifier, attribute).map { |row| row.first }
|
235
254
|
SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
|
236
255
|
INNER JOIN tags ON hosts_tags.tag_id = tags.id
|
237
256
|
WHERE LOWER(tags.name) GLOB LOWER(?) AND LOWER(tags.value) GLOB LOWER(?);
|
238
257
|
EOS
|
239
258
|
else
|
240
|
-
environment.execute(<<-EOS, identifier, identifier, identifier).map { |row| row.first }
|
259
|
+
values = environment.execute(<<-EOS, identifier, identifier, identifier).map { |row| row.first }
|
241
260
|
SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
|
242
261
|
INNER JOIN hosts ON hosts_tags.host_id = hosts.id
|
243
262
|
INNER JOIN tags ON hosts_tags.tag_id = tags.id
|
@@ -245,6 +264,21 @@ module Hotdog
|
|
245
264
|
|
246
265
|
EOS
|
247
266
|
end
|
267
|
+
if not environment.fixed_string? and values.empty?
|
268
|
+
# fallback to glob expression
|
269
|
+
identifier_glob = identifier.gsub(/[-.\/_]/, "?")
|
270
|
+
if identifier != identifier_glob
|
271
|
+
if attribute?
|
272
|
+
attribute_glob = attribute.gsub(/[-.\/:_]/, "?")
|
273
|
+
environment.logger.info("fallback to glob expression: %s:%s" % [identifier_glob, attribute_glob])
|
274
|
+
else
|
275
|
+
attribute_glob = nil
|
276
|
+
environment.logger.info("fallback to glob expression: %s" % [identifier_glob])
|
277
|
+
end
|
278
|
+
values = TagGlobExpressionNode.new(identifier_glob, attribute_glob).evaluate(environment)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
values
|
248
282
|
end
|
249
283
|
end
|
250
284
|
|
data/lib/hotdog/commands/tags.rb
CHANGED
@@ -11,24 +11,38 @@ module Hotdog
|
|
11
11
|
tag_name
|
12
12
|
}
|
13
13
|
result1 = fields.map { |tag_name|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
if not glob?(tag_name)
|
15
|
+
@tags_q1 ||= @db.prepare(<<-EOS)
|
16
|
+
SELECT DISTINCT tags.value FROM hosts_tags
|
17
|
+
INNER JOIN tags ON hosts_tags.tag_id = tags.id
|
18
|
+
WHERE tags.name = LOWER(?);
|
19
|
+
EOS
|
20
|
+
logger.debug("tags_q1(%s)" % [tag_name.inspect])
|
21
|
+
@tags_q1.execute(tag_name).map { |row| row.join(",") }
|
22
|
+
else
|
23
|
+
@tags_q2 ||= @db.prepare(<<-EOS)
|
24
|
+
SELECT DISTINCT tags.value FROM hosts_tags
|
25
|
+
INNER JOIN tags ON hosts_tags.tag_id = tags.id
|
26
|
+
WHERE tags.name GLOB LOWER(?);
|
27
|
+
EOS
|
28
|
+
logger.debug("tags_q2(%s)" % [tag_name.inspect])
|
29
|
+
@tags_q2.execute(tag_name).map { |row| row.join(",") }
|
30
|
+
end
|
19
31
|
}
|
20
32
|
result = (0..result1.reduce(0) { |max, values| [max, values.length].max }).map { |field_index|
|
21
33
|
result1.map { |values| values[field_index] }
|
22
34
|
}
|
23
35
|
else
|
24
36
|
fields = ["tag"]
|
25
|
-
|
37
|
+
@tags_q3 ||= @db.prepare(<<-EOS)
|
26
38
|
SELECT tags.name, tags.value FROM hosts_tags
|
27
39
|
INNER JOIN tags ON hosts_tags.tag_id = tags.id;
|
28
40
|
EOS
|
41
|
+
logger.debug("tags_q3()")
|
42
|
+
result = @tags_q3.execute().map { |name, value| [0 < value.length ? "#{name}:#{value}" : name] }
|
29
43
|
end
|
30
44
|
if 0 < result.length
|
31
|
-
STDOUT.
|
45
|
+
STDOUT.print(format(result, fields: fields))
|
32
46
|
end
|
33
47
|
end
|
34
48
|
end
|
data/lib/hotdog/commands.rb
CHANGED
@@ -8,6 +8,7 @@ module Hotdog
|
|
8
8
|
class BaseCommand
|
9
9
|
def initialize(db, options={})
|
10
10
|
@db = db
|
11
|
+
@fixed_string = options[:fixed_string]
|
11
12
|
@formatter = options[:formatter]
|
12
13
|
@logger = options[:logger]
|
13
14
|
@tags = options[:tags]
|
@@ -36,6 +37,10 @@ module Hotdog
|
|
36
37
|
@db.execute(query, args)
|
37
38
|
end
|
38
39
|
|
40
|
+
def fixed_string?()
|
41
|
+
@fixed_string
|
42
|
+
end
|
43
|
+
|
39
44
|
def suspended?()
|
40
45
|
@suspended
|
41
46
|
end
|
@@ -45,26 +50,47 @@ module Hotdog
|
|
45
50
|
@formatter.format(result, @options.merge(options))
|
46
51
|
end
|
47
52
|
|
53
|
+
def glob?(s)
|
54
|
+
s.index('*') or s.index('?') or s.index('[') or s.index(']')
|
55
|
+
end
|
56
|
+
|
48
57
|
def get_hosts(hosts=[])
|
49
58
|
if 0 < tags.length
|
50
59
|
result = hosts.map { |host_id|
|
51
60
|
update_host_tags(host_id, @options.merge(tags: tags))
|
52
61
|
tags.map { |tag|
|
53
62
|
tag_name, tag_value = tag.split(":", 2)
|
54
|
-
|
55
|
-
|
63
|
+
case tag_name
|
64
|
+
when "expires_at"
|
65
|
+
@get_hosts_q6 ||= @db.prepare(<<-EOS)
|
66
|
+
SELECT expires_at FROM hosts_tags WHERE host_id = ? LIMIT 1;
|
67
|
+
EOS
|
68
|
+
logger.debug("get_hosts_q6()")
|
69
|
+
@get_hosts_q6.execute(host_id).map { |row| Time.at(row.first).strftime("%Y-%m-%dT%H:%M:%S") }.first
|
70
|
+
when "host"
|
56
71
|
@get_hosts_q1 ||= @db.prepare(<<-EOS)
|
57
72
|
SELECT name FROM hosts WHERE id = ? LIMIT 1;
|
58
73
|
EOS
|
59
|
-
|
74
|
+
logger.debug("get_hosts_q1()")
|
75
|
+
@get_hosts_q1.execute(host_id).map { |row| row.first }.first
|
60
76
|
else
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
77
|
+
if not glob?(tag_name)
|
78
|
+
@get_hosts_q2 ||= @db.prepare(<<-EOS)
|
79
|
+
SELECT tags.value FROM hosts_tags
|
80
|
+
INNER JOIN tags ON hosts_tags.tag_id = tags.id
|
81
|
+
WHERE hosts_tags.host_id = ? AND tags.name = ?;
|
82
|
+
EOS
|
83
|
+
logger.debug("get_hosts_q2()")
|
84
|
+
@get_hosts_q2.execute(host_id, tag_name).map { |row| row.first }.join(",")
|
85
|
+
else
|
86
|
+
@get_hosts_q5 ||= @db.prepare(<<-EOS)
|
87
|
+
SELECT tags.value FROM hosts_tags
|
88
|
+
INNER JOIN tags ON hosts_tags.tag_id = tags.id
|
89
|
+
WHERE hosts_tags.host_id = ? AND tags.name GLOB ?;
|
90
|
+
EOS
|
91
|
+
logger.debug("get_hosts_q5()")
|
92
|
+
@get_hosts_q5.execute(host_id, tag_name).map { |row| row.first }.join(",")
|
93
|
+
end
|
68
94
|
end
|
69
95
|
}
|
70
96
|
}
|
@@ -130,7 +156,7 @@ module Hotdog
|
|
130
156
|
code, result = @dog.search("hosts:")
|
131
157
|
logger.debug("dog.serarch(%s) #==> [%s, %s]" % ["hosts:".inspect, code.inspect, result.inspect])
|
132
158
|
if code.to_i / 100 != 2
|
133
|
-
raise("
|
159
|
+
raise("dog.search(%s) returns (%s: %s)" % ["hosts:".inspect, code.inspect, result.inspect])
|
134
160
|
end
|
135
161
|
|
136
162
|
execute(<<-EOS % result["results"]["hosts"].map { "LOWER(?)" }.join(", "), result["results"]["hosts"])
|
@@ -225,9 +251,9 @@ module Hotdog
|
|
225
251
|
logger.debug("update_host_tags_q1(%s)" % [host_id.inspect])
|
226
252
|
host_name = @update_host_tags_q1.execute(host_id).map { |row| row.first }.first
|
227
253
|
else
|
228
|
-
@update_host_tags_q2 ||= @db.prepare("SELECT id FROM hosts WHERE LOWER(name) = LOWER(?) LIMIT 1;")
|
254
|
+
@update_host_tags_q2 ||= @db.prepare("SELECT id, name FROM hosts WHERE LOWER(name) = LOWER(?) LIMIT 1;")
|
229
255
|
logger.debug("update_host_tags_q2(%s)" % [host_name.inspect])
|
230
|
-
host_id = @update_host_tags_q2.execute(host_name).map { |row| row
|
256
|
+
host_id, host_name = @update_host_tags_q2.execute(host_name).map { |row| row }.first
|
231
257
|
end
|
232
258
|
|
233
259
|
if not options[:force]
|
@@ -248,7 +274,7 @@ module Hotdog
|
|
248
274
|
end
|
249
275
|
|
250
276
|
code, result = @dog.host_tags(host_name)
|
251
|
-
logger.debug("dog.
|
277
|
+
logger.debug("dog.host_tags(%s) #==> [%s, %s]" % [host_name.inspect, code.inspect, result.inspect])
|
252
278
|
if code.to_i / 100 != 2
|
253
279
|
case code.to_i
|
254
280
|
when 404 # host not found on datadog
|
@@ -256,7 +282,7 @@ module Hotdog
|
|
256
282
|
logger.debug("update_host_tags_q7(%s)" % [host_name.inspect])
|
257
283
|
@update_host_tags_q7.execute(host_name)
|
258
284
|
end
|
259
|
-
raise("
|
285
|
+
raise("dog.host_tags(%s) returns (%s: %s)" % [host_name.inspect, code.inspect, result.inspect])
|
260
286
|
end
|
261
287
|
|
262
288
|
expires_at = Time.new.to_i + (options[:minimum_expiry] + rand(options[:random_expiry]))
|
data/lib/hotdog/version.rb
CHANGED