vzcdn 0.1.2 → 0.1.3
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/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