vzcdn 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/ec +18 -1
- data/bin/vzcdn +18 -1
- data/lib/args.rb +12 -54
- data/lib/command_proc.rb +5 -4
- data/lib/common.rb +10 -7
- data/lib/config_handler.rb +10 -12
- data/lib/config_reader.rb +16 -0
- data/lib/route.rb +101 -4
- data/lib/table_print.rb +176 -0
- data/lib/util.rb +29 -0
- data/lib/vzcdn/version.rb +1 -1
- data/lib/zone.rb +98 -70
- metadata +4 -3
- data/lib/t.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17369072c6982f75c6051118810f9a5a2ff1360f
|
4
|
+
data.tar.gz: 5b5b170030343d0c6cef577dec0e4749a80d5641
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87b87d36051c63cb48c92824bae3f2993040f17ba15b02acd0740621c2a49c9b4cc67c38ddff91f16da1c7c5b535c6a6e3f7bcf908edfb397fe0cd7cc2734ac2
|
7
|
+
data.tar.gz: a66b939d4ffdf552500f46546e960a5bb9b621909a9f77400be7756a377036ea5739a9f612d754e51dd281e2a379e6d986aecbed28e70df161df870de38fc3b7
|
data/bin/ec
CHANGED
@@ -8,9 +8,26 @@ if ARGV[0] == "-v"
|
|
8
8
|
exit
|
9
9
|
end
|
10
10
|
|
11
|
+
if ARGV[0] == "-d"
|
12
|
+
$debug = true
|
13
|
+
ARGV.shift
|
14
|
+
else
|
15
|
+
$debug = false
|
16
|
+
end
|
17
|
+
|
11
18
|
args = []
|
12
19
|
ARGV.each { |arg|
|
13
20
|
args << arg
|
14
21
|
}
|
15
22
|
|
16
|
-
|
23
|
+
begin
|
24
|
+
VzcdnApp.invoke(args)
|
25
|
+
rescue Exception => e
|
26
|
+
if e.class != SystemExit
|
27
|
+
puts "ERROR:" + e.message
|
28
|
+
if $debug
|
29
|
+
raise e
|
30
|
+
else
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/bin/vzcdn
CHANGED
@@ -8,9 +8,26 @@ if ARGV[0] == "-v"
|
|
8
8
|
exit
|
9
9
|
end
|
10
10
|
|
11
|
+
if ARGV[0] == "-d"
|
12
|
+
$debug = true
|
13
|
+
ARGV.shift
|
14
|
+
else
|
15
|
+
$debug = false
|
16
|
+
end
|
17
|
+
|
11
18
|
args = []
|
12
19
|
ARGV.each { |arg|
|
13
20
|
args << arg
|
14
21
|
}
|
15
22
|
|
16
|
-
|
23
|
+
begin
|
24
|
+
VzcdnApp.invoke(args)
|
25
|
+
rescue Exception => e
|
26
|
+
if e.class != SystemExit
|
27
|
+
puts "ERROR:" + e.message
|
28
|
+
if $debug
|
29
|
+
raise e
|
30
|
+
else
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/args.rb
CHANGED
@@ -218,63 +218,21 @@ class Flow
|
|
218
218
|
puts result
|
219
219
|
print_flow(node.next_node)
|
220
220
|
end
|
221
|
-
end
|
222
|
-
|
223
|
-
|
224
|
-
def get_named(array, name)
|
225
|
-
array.each { |elt|
|
226
|
-
if elt.name == name
|
227
|
-
return elt
|
228
|
-
end
|
229
|
-
}
|
230
|
-
end
|
231
221
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
[:url]
|
239
|
-
else
|
240
|
-
[:ip]
|
241
|
-
end
|
222
|
+
def parse_line(line)
|
223
|
+
idx = line.index('=')
|
224
|
+
if (idx)
|
225
|
+
return line[0...idx], line[idx+1..-1]
|
226
|
+
else
|
227
|
+
line
|
242
228
|
end
|
243
|
-
result
|
244
229
|
end
|
245
|
-
end
|
246
230
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
flow.add(Arg.new("type", desc: "record type", required: true, validator: ["A", "AAAA", "CNAME"]))
|
253
|
-
http_decision = Decision.new(http_decider, :ip, :url)
|
254
|
-
flow.add(http_decision)
|
255
|
-
http_decision.add(:ip, Arg.new("ip", desc: "IP address", required: false, validator: /\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z/))
|
256
|
-
http_decision.add(:url, Arg.new("url", desc: "URL of cname", required: false, validator: /.*/))
|
257
|
-
email = Arg.new("email", desc: "Email Address", required: false, validator: /.*/)
|
258
|
-
http_decision.add(:url, email)
|
259
|
-
http_decision.add(:ip, email)
|
260
|
-
|
261
|
-
http_decision.flow = flow
|
262
|
-
|
263
|
-
puts flow.to_s
|
264
|
-
|
265
|
-
def parse_line(line)
|
266
|
-
idx = line.index('=')
|
267
|
-
if (idx)
|
268
|
-
return line[0...idx], line[idx+1..-1]
|
269
|
-
else
|
270
|
-
line
|
231
|
+
def parse(args)
|
232
|
+
args.each { |arg|
|
233
|
+
name, value = parse_line(arg)
|
234
|
+
set(name, value)
|
235
|
+
}
|
271
236
|
end
|
272
|
-
end
|
273
237
|
|
274
|
-
|
275
|
-
name, value = parse_line(arg)
|
276
|
-
flow.set(name,value)
|
277
|
-
}
|
278
|
-
|
279
|
-
puts "after args:"
|
280
|
-
puts flow.to_s
|
238
|
+
end
|
data/lib/command_proc.rb
CHANGED
@@ -41,15 +41,16 @@ module CommandProc
|
|
41
41
|
end
|
42
42
|
if instance.respond_to?(command)
|
43
43
|
instance.send(command, args)
|
44
|
-
|
44
|
+
elsif args.length >= 1 && instance.respond_to?(args[0])
|
45
45
|
name = command
|
46
46
|
instance = get_instance(name)
|
47
47
|
command = args.shift
|
48
48
|
instance.send(command, args)
|
49
|
+
else
|
50
|
+
puts "argument '" + command + "' not recognized as command"
|
49
51
|
end
|
50
52
|
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
53
|
|
54
|
+
end
|
55
|
+
|
55
56
|
end
|
data/lib/common.rb
CHANGED
@@ -23,20 +23,23 @@ class CommonRestUtils
|
|
23
23
|
else
|
24
24
|
"unsupported http method:" + http_method
|
25
25
|
end
|
26
|
-
rescue
|
27
|
-
puts "
|
28
|
-
if
|
29
|
-
puts "
|
26
|
+
rescue Exception => e
|
27
|
+
puts "Unable to connect to REST server " + param("rest_base_url")
|
28
|
+
if $debug
|
29
|
+
puts "full URL is:" + url
|
30
|
+
if (body)
|
31
|
+
puts "body is: json_body"
|
32
|
+
end
|
30
33
|
end
|
31
|
-
raise
|
34
|
+
raise e.message + " (" + e.class.to_s + ")"
|
32
35
|
end
|
33
|
-
if (response.code != 200)
|
36
|
+
if ( ! response.nil? && response.respond_to?(:code) && response.code != 200)
|
34
37
|
raise "Bad response code:" + response.code.to_s
|
35
38
|
end
|
36
39
|
if (response.length > 0)
|
37
40
|
JSON.parse response
|
38
41
|
else
|
39
|
-
|
42
|
+
nil
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
data/lib/config_handler.rb
CHANGED
@@ -18,10 +18,10 @@ class ConfigHandler
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def replace_nv(name, value, new_file,
|
22
|
-
new_config_line = name + '=' + value
|
21
|
+
def replace_nv(name, value, new_file, orig_file)
|
22
|
+
new_config_line = name + '=' + value.to_s
|
23
23
|
wrote_line = false
|
24
|
-
|
24
|
+
orig_file.each { |line|
|
25
25
|
old_name, old_value = parse_line(line)
|
26
26
|
if (old_name == name)
|
27
27
|
if ! value.nil?
|
@@ -37,14 +37,6 @@ class ConfigHandler
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
def file_contents(filename)
|
41
|
-
if (File.file? filename)
|
42
|
-
File.open(filename, "r")
|
43
|
-
else
|
44
|
-
[]
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
40
|
def load_config_values
|
49
41
|
if defined? @@config_values
|
50
42
|
return
|
@@ -80,10 +72,16 @@ class ConfigHandler
|
|
80
72
|
|
81
73
|
def set(name, value)
|
82
74
|
config_file = get_config_file
|
75
|
+
if ! File.exists? config_file
|
76
|
+
# make empty file
|
77
|
+
File.open(config_file, "w").close
|
78
|
+
end
|
83
79
|
new_config_file = config_file + ".tmp"
|
84
80
|
updated_file = File.open(new_config_file, "w")
|
85
|
-
|
81
|
+
orig_file = File.open(config_file)
|
82
|
+
replace_nv(name, value, updated_file, orig_file)
|
86
83
|
updated_file.close
|
84
|
+
orig_file.close
|
87
85
|
FileUtils.rm(config_file, force: true)
|
88
86
|
FileUtils.mv(new_config_file, config_file, :force => true)
|
89
87
|
end
|
data/lib/config_reader.rb
CHANGED
@@ -3,4 +3,20 @@ module ConfigReader
|
|
3
3
|
def param(name)
|
4
4
|
ConfigHandler.config_parameter(name)
|
5
5
|
end
|
6
|
+
|
7
|
+
def config_dir
|
8
|
+
ConfigHandler::CONFIG_DIRECTORY
|
9
|
+
end
|
10
|
+
|
11
|
+
def mkdir(*dirs)
|
12
|
+
path = config_file(*dirs)
|
13
|
+
if ! Dir.exists?(path)
|
14
|
+
Dir.mkdir path
|
15
|
+
end
|
16
|
+
path
|
17
|
+
end
|
18
|
+
|
19
|
+
def config_file(*dirs_file)
|
20
|
+
File.join(config_dir, *dirs_file)
|
21
|
+
end
|
6
22
|
end
|
data/lib/route.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require_relative 'config_reader'
|
3
3
|
require_relative 'common'
|
4
|
-
require 'pp'
|
5
4
|
|
6
5
|
class Route
|
7
6
|
include ConfigReader
|
@@ -17,7 +16,11 @@ class Route
|
|
17
16
|
end
|
18
17
|
|
19
18
|
def initialize
|
20
|
-
|
19
|
+
rest_base_url = param("rest_base_url")
|
20
|
+
if (rest_base_url.nil? || rest_base_url.length == 0)
|
21
|
+
raise "configuration file does not contain expected parameters -- try config init"
|
22
|
+
end
|
23
|
+
@common = CommonRestUtils.new(rest_base_url + "mcc/")
|
21
24
|
@availables = { }
|
22
25
|
end
|
23
26
|
|
@@ -42,9 +45,80 @@ class Route
|
|
42
45
|
end
|
43
46
|
|
44
47
|
def get_zone(id, name)
|
45
|
-
suffix = "dns/routezone?
|
48
|
+
suffix = "dns/routezone?"
|
49
|
+
if id
|
50
|
+
suffix = suffix + "id=" + id.to_s
|
51
|
+
else
|
52
|
+
suffix = suffix + "name=" + name
|
53
|
+
end
|
46
54
|
@common.callMethod(customer_suffix(suffix), :get)
|
47
55
|
end
|
56
|
+
|
57
|
+
def translate_value(data, hash, key)
|
58
|
+
if hash.has_key?(key)
|
59
|
+
hash[key] = xlate_id(data, hash[key])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def untranslate_value(data, hash, key)
|
64
|
+
if hash.has_key?(key)
|
65
|
+
hash[key] = xlate_name(data, hash[key])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def translate_hc(rec_array)
|
70
|
+
rec_array.each { |rec|
|
71
|
+
hc = rec["HealthCheck"]
|
72
|
+
translate_value(:hc_type, hc, "CheckTypeId")
|
73
|
+
translate_value(:http_method, hc, "HTTPMethodId")
|
74
|
+
translate_value(:ip_version, hc, "IPVersion")
|
75
|
+
translate_value(:hc_rm, hc, "ReintegrationMethodId")
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def untranslate_hc(rec_array)
|
80
|
+
rec_array.each { |rec|
|
81
|
+
hc = rec["HealthCheck"]
|
82
|
+
untranslate_value(:hc_type, hc, "CheckTypeId")
|
83
|
+
untranslate_value(:http_method, hc, "HTTPMethodId")
|
84
|
+
untranslate_value(:ip_version, hc, "IPVersion")
|
85
|
+
untranslate_value(:hc_rm, hc, "ReintegrationMethodId")
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
def translate_groups(group_array)
|
90
|
+
group_array.each { |group|
|
91
|
+
group_element = group["Group"]
|
92
|
+
["A", "AAAA", "CNAME"].each { |record_type|
|
93
|
+
translate_hc(group_element[record_type])
|
94
|
+
}
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def untranslate_groups(group_array)
|
99
|
+
group_array.each { |group|
|
100
|
+
group_element = group["Group"]
|
101
|
+
["A", "AAAA", "CNAME"].each { |record_type|
|
102
|
+
untranslate_hc(group_element[record_type])
|
103
|
+
}
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def translate_zone(zone)
|
108
|
+
return nil if zone.nil?
|
109
|
+
translate_value(:zone_status, zone, "Status")
|
110
|
+
translate_value(:zone_type, zone, "ZoneType")
|
111
|
+
translate_groups zone["LoadBalancingGroups"]
|
112
|
+
translate_groups zone["FailoverGroups"]
|
113
|
+
end
|
114
|
+
|
115
|
+
def untranslate_zone(zone)
|
116
|
+
return nil if zone.nil?
|
117
|
+
untranslate_value(:zone_status, zone, "Status")
|
118
|
+
untranslate_value(:zone_type, zone, "ZoneType")
|
119
|
+
untranslate_groups zone["LoadBalancingGroups"]
|
120
|
+
untranslate_groups zone["FailoverGroups"]
|
121
|
+
end
|
48
122
|
|
49
123
|
def copy_zone(from, to)
|
50
124
|
suffix = customer_suffix("dns/routezone/copy")
|
@@ -59,6 +133,11 @@ class Route
|
|
59
133
|
|
60
134
|
def add_zone()
|
61
135
|
end
|
136
|
+
|
137
|
+
def update_zone(zone)
|
138
|
+
suffix = customer_suffix("dns/routezone")
|
139
|
+
@common.callMethod(suffix, :put, zone)
|
140
|
+
end
|
62
141
|
|
63
142
|
def xlate_name(symbol, name)
|
64
143
|
get_available(symbol).each { |hash|
|
@@ -76,9 +155,25 @@ class Route
|
|
76
155
|
}
|
77
156
|
end
|
78
157
|
|
158
|
+
def cache_filename(data)
|
159
|
+
config_file(data.to_s + ".data")
|
160
|
+
end
|
161
|
+
|
162
|
+
def available_file(data)
|
163
|
+
fname = cache_filename(data)
|
164
|
+
if File.exists?(fname)
|
165
|
+
days_old = (Time.new - File.mtime(fname)) / (24*60*60)
|
166
|
+
if days_old < 7.0
|
167
|
+
fname
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
79
172
|
def get_available(data)
|
80
173
|
if @availables[data]
|
81
174
|
@availables[data]
|
175
|
+
elsif available_file(data)
|
176
|
+
@availables[data] = JSON.parse File.read(cache_filename(data))
|
82
177
|
else
|
83
178
|
suffix =
|
84
179
|
{:zone_type => "routezonetypes",
|
@@ -89,7 +184,9 @@ class Route
|
|
89
184
|
:ip_version => "routehealthcheckipversion",
|
90
185
|
:hc_type => "routehealthchecktypes",
|
91
186
|
:hc_rm => "routereintegrationmethodtypes"}[data]
|
92
|
-
|
187
|
+
result = @common.callMethod(non_customer_suffix(suffix), :get)
|
188
|
+
File.write(cache_filename(data), JSON.generate(result))
|
189
|
+
@availables[data] = result
|
93
190
|
end
|
94
191
|
end
|
95
192
|
|
data/lib/table_print.rb
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
require_relative 'util'
|
2
|
+
|
3
|
+
class TablePrint
|
4
|
+
DELIM = '|'
|
5
|
+
|
6
|
+
def char_repeat(n, char)
|
7
|
+
result = ""
|
8
|
+
(1..n).each { |i|
|
9
|
+
result = result + char
|
10
|
+
}
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
def spaces(n)
|
15
|
+
char_repeat(n, ' ')
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(*titles)
|
19
|
+
@ncols = titles.length
|
20
|
+
@lines = [ ]
|
21
|
+
@width = nil
|
22
|
+
@lines << titles
|
23
|
+
separator = [ ]
|
24
|
+
titles.each { |title|
|
25
|
+
separator << char_repeat(title.length, '-')
|
26
|
+
}
|
27
|
+
@lines << separator
|
28
|
+
end
|
29
|
+
|
30
|
+
def append(*columns)
|
31
|
+
@lines << columns
|
32
|
+
end
|
33
|
+
|
34
|
+
def indent(column)
|
35
|
+
if column == 0
|
36
|
+
""
|
37
|
+
else
|
38
|
+
segment = spaces(@width-1) + DELIM
|
39
|
+
segment * column
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def strip(line)
|
44
|
+
regexp = Regexp.new(' *' + Regexp.escape(DELIM) + '*\Z')
|
45
|
+
line.sub(regexp, "")
|
46
|
+
end
|
47
|
+
|
48
|
+
def calc_column(line)
|
49
|
+
line.length / @width
|
50
|
+
end
|
51
|
+
|
52
|
+
def fill_to_next_column(line)
|
53
|
+
tab = @width - (line.length % @width)
|
54
|
+
line = line + spaces(tab-1) + DELIM
|
55
|
+
end
|
56
|
+
|
57
|
+
# prints a line with DELIMs following in proper columns
|
58
|
+
def println(line)
|
59
|
+
column = calc_column(line)
|
60
|
+
if (column < @ncols)
|
61
|
+
line = fill_to_next_column(line)
|
62
|
+
column = calc_column(line)
|
63
|
+
end
|
64
|
+
if (column < @ncols)
|
65
|
+
segment = spaces(@width-1) + DELIM
|
66
|
+
line = line + segment * (@ncols - column)
|
67
|
+
end
|
68
|
+
puts strip(line)
|
69
|
+
end
|
70
|
+
|
71
|
+
def next_unprinted_column(col_array, start=0)
|
72
|
+
for i in (start...col_array.length)
|
73
|
+
return i if col_array[i]
|
74
|
+
end
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def calc_max_widths
|
79
|
+
maxwidth = Array.new(@ncols, 0)
|
80
|
+
@lines.each { |line|
|
81
|
+
line.each_with_index { |value, index|
|
82
|
+
maxwidth[index] = [value.to_s.length, maxwidth[index]].max
|
83
|
+
}
|
84
|
+
}
|
85
|
+
maxwidth
|
86
|
+
end
|
87
|
+
|
88
|
+
def print_table_normally(maxwidth)
|
89
|
+
@lines.each { |line|
|
90
|
+
output = ""
|
91
|
+
line.each_with_index { |value, index|
|
92
|
+
output = output + value.to_s + spaces(maxwidth[index] - value.to_s.length + 2)
|
93
|
+
}
|
94
|
+
puts output[0...-2]
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def separator(width)
|
99
|
+
char_repeat(width, '-')
|
100
|
+
end
|
101
|
+
|
102
|
+
def print_staggered(maxwidth, term_width)
|
103
|
+
minw = term_width
|
104
|
+
maxwidth.each_with_index { |w, index|
|
105
|
+
next if index == 0
|
106
|
+
width = (term_width - w) / index
|
107
|
+
minw = [width, minw].min
|
108
|
+
}
|
109
|
+
@width = minw
|
110
|
+
puts separator(term_width)
|
111
|
+
@lines.each_with_index { |line, lineno|
|
112
|
+
next if lineno == 1 # skip line of separators
|
113
|
+
output = ""
|
114
|
+
cols_left = Array.new(@ncols, true)
|
115
|
+
while column = next_unprinted_column(cols_left)
|
116
|
+
output = indent(column) if output.length == 0
|
117
|
+
while column
|
118
|
+
value = line[column].to_s
|
119
|
+
cols_left[column] = false # indicate this column has been printed
|
120
|
+
output = output + value
|
121
|
+
output = fill_to_next_column(output)
|
122
|
+
next_column = calc_column(output)
|
123
|
+
column = next_unprinted_column(cols_left, next_column)
|
124
|
+
if column && (column > next_column)
|
125
|
+
output = output + (spaces(@width-1) + DELIM) * (column - next_column)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
println(output)
|
129
|
+
output = ""
|
130
|
+
end
|
131
|
+
puts separator(term_width)
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
def print_old_staggered(maxwidth, term_width)
|
136
|
+
puts separator(term_width)
|
137
|
+
@lines.each_with_index { |line, index|
|
138
|
+
next if index == 1
|
139
|
+
output = ""
|
140
|
+
column = 0
|
141
|
+
line.each_with_index { |value, column|
|
142
|
+
value = value.to_s
|
143
|
+
output = indent(column) if output.length == 0
|
144
|
+
if value.length > (@width - 1)
|
145
|
+
output = output + value
|
146
|
+
println(output)
|
147
|
+
output = ""
|
148
|
+
else
|
149
|
+
output = output + value + spaces(@width - value.length - 1) + DELIM
|
150
|
+
end
|
151
|
+
column += 1
|
152
|
+
}
|
153
|
+
println(output) if output.length > 0
|
154
|
+
puts separator(term_width)
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
def print_table
|
159
|
+
return if @lines.nil?
|
160
|
+
return if @ncols == 0
|
161
|
+
if @ncols == 1
|
162
|
+
@lines.each { |line| puts line }
|
163
|
+
return
|
164
|
+
end
|
165
|
+
|
166
|
+
maxwidth = calc_max_widths
|
167
|
+
# will lines fit in terminal
|
168
|
+
width_needed = maxwidth.reduce(:+) + (@ncols-1) * 2
|
169
|
+
term_width, h = Util.detect_terminal_size
|
170
|
+
if width_needed <= term_width
|
171
|
+
print_table_normally(maxwidth)
|
172
|
+
else
|
173
|
+
print_staggered(maxwidth, term_width)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
data/lib/util.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
class Util
|
2
|
+
# Determines if a shell command exists by searching for it in ENV['PATH'].
|
3
|
+
def self.command_exists?(command)
|
4
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).any? {|d| File.exists? File.join(d, command) }
|
5
|
+
end
|
6
|
+
|
7
|
+
# Returns [width, height] of terminal when detected, nil if not detected.
|
8
|
+
# Think of this as a simpler version of Highline's Highline::SystemExtensions.terminal_size()
|
9
|
+
def self.detect_terminal_size
|
10
|
+
if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
|
11
|
+
[ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
|
12
|
+
elsif (RUBY_PLATFORM =~ /java/ || (!STDIN.tty? && ENV['TERM'])) && command_exists?('tput')
|
13
|
+
[`tput cols`.to_i, `tput lines`.to_i]
|
14
|
+
elsif STDIN.tty? && command_exists?('stty')
|
15
|
+
`stty size`.scan(/\d+/).map { |s| s.to_i }.reverse
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
rescue
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class String
|
25
|
+
def full_match(re)
|
26
|
+
m = re.match(self)
|
27
|
+
m && (m.begin(0) == 0) && (m.end(0) == self.length)
|
28
|
+
end
|
29
|
+
end
|
data/lib/vzcdn/version.rb
CHANGED
data/lib/zone.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require_relative 'route'
|
2
|
+
require_relative 'util'
|
3
|
+
require_relative 'table_print'
|
2
4
|
|
3
5
|
class Zone
|
4
6
|
include CommandProc
|
7
|
+
include ConfigReader
|
5
8
|
|
6
9
|
def initialize(name)
|
7
|
-
@lines = nil
|
8
10
|
@zname = name
|
9
11
|
@usage = { :list => "list zones"}
|
10
12
|
@argflows = [ {:name => "list", :usage => "list zones", :args=>[]},
|
@@ -16,14 +18,32 @@ class Zone
|
|
16
18
|
puts "unimplemented"
|
17
19
|
else
|
18
20
|
zones = Route.do.get_all_zones
|
19
|
-
|
21
|
+
table = TablePrint.new("ZONE", "ID", "STATUS")
|
20
22
|
zones.each {|zone|
|
21
|
-
|
23
|
+
table.append(zone["DomainName"], zone["ZoneId"].to_s, Route.do.xlate_id(:zone_status, zone["Status"]))
|
22
24
|
}
|
23
|
-
|
25
|
+
table.print_table
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
29
|
+
# let user lowercase and abbreviate key; abbreviation must match one key
|
30
|
+
def match_key(abbrev, struct)
|
31
|
+
abbrev = abbrev.downcase
|
32
|
+
key = nil
|
33
|
+
struct.keys.each { |fullkey|
|
34
|
+
testkey = fullkey.downcase
|
35
|
+
return fullkey if abbrev == testkey
|
36
|
+
if fullkey.downcase.start_with?(abbrev)
|
37
|
+
if (! key)
|
38
|
+
key = fullkey
|
39
|
+
else
|
40
|
+
return nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
}
|
44
|
+
key
|
45
|
+
end
|
46
|
+
|
27
47
|
def structure_print(struct, args, header)
|
28
48
|
if (struct.class == Array)
|
29
49
|
# puts "printing array of " + struct.length.to_s + " elts"
|
@@ -36,12 +56,14 @@ class Zone
|
|
36
56
|
if (args.length == 0)
|
37
57
|
# print top level elements of hash
|
38
58
|
if (header)
|
39
|
-
|
59
|
+
@table = TablePrint.new(*struct.keys)
|
40
60
|
end
|
41
61
|
values = []
|
42
62
|
struct.keys.each { |key|
|
43
63
|
value = struct[key]
|
44
|
-
if (value.
|
64
|
+
if (value.nil?)
|
65
|
+
value = "null"
|
66
|
+
elsif (value.class == Array)
|
45
67
|
value = value.length.to_s + " elements"
|
46
68
|
elsif (value.class == String)
|
47
69
|
elsif (value.class == Fixnum)
|
@@ -53,10 +75,13 @@ class Zone
|
|
53
75
|
end
|
54
76
|
values << value
|
55
77
|
}
|
56
|
-
|
78
|
+
@table.append(*values)
|
57
79
|
else
|
80
|
+
args = args.clone
|
58
81
|
key = args.shift
|
59
|
-
|
82
|
+
fullkey = match_key(key, struct)
|
83
|
+
raise "no (unique) key matches " + key if ! fullkey
|
84
|
+
structure_print(struct[fullkey], args, header)
|
60
85
|
end
|
61
86
|
else
|
62
87
|
if (args.length == 0)
|
@@ -67,21 +92,79 @@ class Zone
|
|
67
92
|
end
|
68
93
|
end
|
69
94
|
|
95
|
+
def id_and_name
|
96
|
+
id = name = nil
|
97
|
+
if @zname.full_match /\d+/
|
98
|
+
id = @zname
|
99
|
+
else
|
100
|
+
name = @zname
|
101
|
+
end
|
102
|
+
name = name.sub(/\.\Z/, "")
|
103
|
+
return id, name
|
104
|
+
end
|
105
|
+
|
106
|
+
def get_zone(forceRest = false)
|
107
|
+
zonedir = mkdir("zones")
|
108
|
+
zone = nil
|
109
|
+
id, name = id_and_name
|
110
|
+
if @zname
|
111
|
+
if ! forceRest
|
112
|
+
if id.nil?
|
113
|
+
r = name + '\.\d+'
|
114
|
+
else
|
115
|
+
r = '.*\.' + id
|
116
|
+
end
|
117
|
+
regex = Regexp.new(r)
|
118
|
+
Dir.new(zonedir).each { |file|
|
119
|
+
if file.full_match regex
|
120
|
+
path = File.join(zonedir, file)
|
121
|
+
zone = JSON.parse(File.open(path).read)
|
122
|
+
end
|
123
|
+
}
|
124
|
+
end
|
125
|
+
if (zone.nil?)
|
126
|
+
zone = Route.do.get_zone(id, name)
|
127
|
+
File.open("orig.zone", "w").write(JSON.pretty_generate zone)
|
128
|
+
Route.do.translate_zone(zone)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
zone
|
132
|
+
end
|
133
|
+
|
134
|
+
def push(args)
|
135
|
+
zone = get_zone
|
136
|
+
Route.do.untranslate_zone(zone)
|
137
|
+
File.open("untranslated.zone","w").write(JSON.pretty_generate zone)
|
138
|
+
Route.do.update_zone(zone)
|
139
|
+
end
|
140
|
+
|
141
|
+
def pull(args)
|
142
|
+
raise("Illegal arguments:" + args.to_s) if args.length != 0
|
143
|
+
raise("Must specify zone") if @zname.nil?
|
144
|
+
zone = get_zone(true)
|
145
|
+
file_name = zone["DomainName"].sub(/\.\Z/, '')
|
146
|
+
file_name = file_name + '.' + zone["ZoneId"].to_s
|
147
|
+
file_name = config_file("zones", file_name)
|
148
|
+
File.delete(file_name) if File.exists?(file_name)
|
149
|
+
File.open(file_name, "w").write(JSON.pretty_generate zone)
|
150
|
+
end
|
151
|
+
|
70
152
|
def print(args)
|
71
153
|
if @zname
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
154
|
+
zone = get_zone
|
155
|
+
if (zone.nil?)
|
156
|
+
puts "zone empty"
|
157
|
+
return
|
76
158
|
end
|
77
|
-
if (args.length
|
159
|
+
if (args.length == 1 && args[0] == "-l")
|
78
160
|
puts JSON.pretty_generate(zone)
|
79
161
|
else
|
162
|
+
@table = nil
|
80
163
|
structure_print(zone, args, true)
|
81
|
-
|
164
|
+
@table.print_table if @table
|
82
165
|
end
|
83
166
|
else
|
84
|
-
puts "
|
167
|
+
puts "need zone name or id"
|
85
168
|
end
|
86
169
|
end
|
87
170
|
|
@@ -101,59 +184,4 @@ class Zone
|
|
101
184
|
|
102
185
|
end
|
103
186
|
end
|
104
|
-
|
105
|
-
def char_repeat(n, char)
|
106
|
-
result = ""
|
107
|
-
(1..n).each { |i|
|
108
|
-
result = result + char
|
109
|
-
}
|
110
|
-
result
|
111
|
-
end
|
112
|
-
|
113
|
-
def spaces(n)
|
114
|
-
char_repeat(n, ' ')
|
115
|
-
end
|
116
|
-
|
117
|
-
def pp_table_start_cols(titles)
|
118
|
-
@lines = []
|
119
|
-
@lines << titles
|
120
|
-
separator = []
|
121
|
-
titles.each { |title|
|
122
|
-
separator << char_repeat(title.length, '-')
|
123
|
-
}
|
124
|
-
@lines << separator
|
125
|
-
end
|
126
|
-
|
127
|
-
def pp_table_start(*titles)
|
128
|
-
pp_table_start_cols(titles)
|
129
|
-
end
|
130
|
-
|
131
|
-
def pp_table_append_cols(columns)
|
132
|
-
@lines << columns
|
133
|
-
end
|
134
|
-
|
135
|
-
def pp_table_append(*columns)
|
136
|
-
@lines << columns
|
137
|
-
end
|
138
|
-
|
139
|
-
def pp_table
|
140
|
-
if @lines.nil?
|
141
|
-
return
|
142
|
-
end
|
143
|
-
ncols = @lines[0].length
|
144
|
-
maxwidths = Array.new(ncols, 0)
|
145
|
-
@lines.each { |line|
|
146
|
-
line.each_with_index { |col, index|
|
147
|
-
maxwidths[index] = [col.to_s.length, maxwidths[index]].max
|
148
|
-
}
|
149
|
-
}
|
150
|
-
@lines.each { |line|
|
151
|
-
output = ""
|
152
|
-
line.each_with_index {|col, index|
|
153
|
-
output = output + col.to_s + spaces(maxwidths[index] - col.to_s.length + 2)
|
154
|
-
}
|
155
|
-
puts output
|
156
|
-
}
|
157
|
-
@lines = nil
|
158
|
-
end
|
159
187
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vzcdn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Preston
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-04-
|
13
|
+
date: 2014-04-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|
@@ -81,9 +81,10 @@ files:
|
|
81
81
|
- lib/realTimeStats.rb
|
82
82
|
- lib/reporting.rb
|
83
83
|
- lib/route.rb
|
84
|
-
- lib/
|
84
|
+
- lib/table_print.rb
|
85
85
|
- lib/upload.rb
|
86
86
|
- lib/userInfo.rb
|
87
|
+
- lib/util.rb
|
87
88
|
- lib/vzcdn.rb
|
88
89
|
- lib/vzcdn/version.rb
|
89
90
|
- lib/zone.rb
|
data/lib/t.rb
DELETED