vzcdn 0.1.4 → 0.1.5
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/README.md +14 -1
- data/bin/ec +13 -16
- data/bin/vzcdn +13 -16
- data/lib/args.rb +151 -120
- data/lib/argtest.rb +29 -0
- data/lib/cloptions.rb +53 -59
- data/lib/clui_config.rb +70 -31
- data/lib/command.rb +126 -0
- data/lib/common.rb +1 -0
- data/lib/config_handler.rb +5 -11
- data/lib/config_reader.rb +13 -2
- data/lib/makeBind.sh +90 -0
- data/lib/method.rb +5 -0
- data/lib/print.rb +270 -0
- data/lib/route.rb +10 -7
- data/lib/test_options.rb +16 -0
- data/lib/util.rb +10 -0
- data/lib/vzcdn.rb +31 -14
- data/lib/vzcdn/version.rb +1 -1
- data/lib/zone.rb +173 -97
- data/test/test_all.rb +2 -0
- data/test/test_reporting.rb +142 -0
- metadata +12 -3
- data/lib/command_proc.rb +0 -60
data/lib/argtest.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'args'
|
2
|
+
require_relative 'command'
|
3
|
+
|
4
|
+
|
5
|
+
class MyCommand < Command
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
flow = Flow.new
|
10
|
+
flow.add(Arg.new("name", desc: "Entry name", required: true, validator: /.*/))
|
11
|
+
flow.add(Arg.new("ttl", desc: "time to live in seconds", required: true, validator: /\A\d+\Z/))
|
12
|
+
flow.add(Arg.new("ipv", desc: "ip version", required: true, validator: "ip_versions"))
|
13
|
+
flow.add(MyCommand.new("hello", "says hello"))
|
14
|
+
|
15
|
+
flow = Flow.new
|
16
|
+
flow.add(Arg.new("name", desc: "Entry name", required: true, validator: /.*/))
|
17
|
+
flow.add(Arg.new("ttl", desc: "time to live in seconds", required: true, validator: /\A\d+\Z/))
|
18
|
+
flow.add(Arg.new("ipv", desc: "ip version", required: true, validator: "ip_versions"))
|
19
|
+
flow.add(Arg.new("type", desc: "record type", required: true, validator: ["A", "AAAA", "CNAME"]))
|
20
|
+
|
21
|
+
puts flow.to_s
|
22
|
+
|
23
|
+
result, rest = flow.parse(ARGV)
|
24
|
+
|
25
|
+
puts "parse result=#{result}, remaining args=#{rest}"
|
26
|
+
|
27
|
+
puts "after args:"
|
28
|
+
puts flow.to_s
|
29
|
+
|
data/lib/cloptions.rb
CHANGED
@@ -4,27 +4,32 @@ class ClOptions
|
|
4
4
|
@options = options
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@options.each{|option|
|
12
|
-
if
|
13
|
-
|
14
|
-
if
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
7
|
+
def handle_option(type, name, attached, nextarg)
|
8
|
+
need_shift = false
|
9
|
+
valid_option = false
|
10
|
+
value = attached.nil? ? nextarg : attached
|
11
|
+
@options.each { |option|
|
12
|
+
if option[type] == name
|
13
|
+
valid_option = true
|
14
|
+
if option[:takes_value]
|
15
|
+
need_shift = attached.nil?
|
16
|
+
if value
|
17
|
+
@obj.send(option[:method], value)
|
18
|
+
else
|
19
|
+
return "value required for option"
|
20
|
+
end
|
20
21
|
else
|
21
|
-
|
22
|
+
if attached.nil?
|
23
|
+
@obj.send(option[:method])
|
24
|
+
else
|
25
|
+
return "Invalid option"
|
26
|
+
end
|
22
27
|
end
|
23
28
|
break
|
24
29
|
end
|
25
30
|
}
|
26
|
-
|
27
|
-
|
31
|
+
return "Invalid option" unless valid_option
|
32
|
+
need_shift
|
28
33
|
end
|
29
34
|
|
30
35
|
def parse_longname(arg, m)
|
@@ -37,13 +42,16 @@ class ClOptions
|
|
37
42
|
end
|
38
43
|
|
39
44
|
def parse_shortname (arg)
|
40
|
-
short_name = arg
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
short_name = if arg.length > 1
|
46
|
+
arg[1]
|
47
|
+
else
|
48
|
+
raise "no option given"
|
49
|
+
end
|
50
|
+
option_value = if arg.length > 2
|
51
|
+
arg[2...arg.length]
|
52
|
+
else
|
53
|
+
nil
|
54
|
+
end
|
47
55
|
return short_name, option_value
|
48
56
|
end
|
49
57
|
|
@@ -52,30 +60,33 @@ class ClOptions
|
|
52
60
|
i = 0
|
53
61
|
while i < args.length
|
54
62
|
arg = args[i]
|
55
|
-
|
56
|
-
if arg
|
63
|
+
found = nil
|
64
|
+
if arg.class != String
|
65
|
+
@args.concat args[i...args.length]
|
66
|
+
break
|
67
|
+
elsif arg == '--'
|
57
68
|
@args.concat args[i+1...args.length]
|
58
69
|
break
|
59
70
|
elsif m = arg.match(/\A--([a-z]+(-[a-z]+)*)/)
|
60
|
-
|
61
|
-
|
62
|
-
if (option_value == nil) && (i+1 < args.length)
|
63
|
-
option_value = args[i+1]
|
64
|
-
next_captured = true
|
65
|
-
end
|
66
|
-
took_value = handle_options long_name, option_value
|
67
|
-
i += 1 if took_value && next_captured
|
71
|
+
name, attached = parse_longname(arg, m)
|
72
|
+
found = :long_name
|
68
73
|
elsif arg[0] == '-'
|
69
|
-
|
70
|
-
|
71
|
-
if (option_value == nil) && (i+1 < args.length)
|
72
|
-
option_value = args[i+1]
|
73
|
-
next_captured = true
|
74
|
-
end
|
75
|
-
took_value = handle_options short_name, option_value
|
76
|
-
i += 1 if took_value && next_captured
|
74
|
+
name, attached = parse_shortname(arg)
|
75
|
+
found = :short_name
|
77
76
|
else
|
78
|
-
@args
|
77
|
+
@args.concat args[i...args.length]
|
78
|
+
break
|
79
|
+
end
|
80
|
+
if found
|
81
|
+
next_arg = (i+1 < args.length) ? args[i+1] : nil
|
82
|
+
begin
|
83
|
+
need_shift = handle_option found, name, attached, next_arg
|
84
|
+
if need_shift.class == String
|
85
|
+
errmsg = need_shift
|
86
|
+
return errmsg + ": " + arg.to_s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
i += 1 if need_shift == true
|
79
90
|
end
|
80
91
|
i += 1
|
81
92
|
end
|
@@ -83,21 +94,4 @@ class ClOptions
|
|
83
94
|
end
|
84
95
|
end
|
85
96
|
|
86
|
-
def parse_option(arg)
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
options = [ { short_name: 'd', long_name: 'debug', method: :set_debug, takes_value: false},
|
91
|
-
{ short_name: 'o', long_name: 'output-file', method: :set_output, takes_value: true}]
|
92
97
|
|
93
|
-
$debug=false
|
94
|
-
def set_debug
|
95
|
-
$debug = true
|
96
|
-
end
|
97
|
-
def set_output(file_name)
|
98
|
-
puts "file name = " + file_name
|
99
|
-
end
|
100
|
-
opts = ClOptions.new(self, options)
|
101
|
-
args = opts.handle(ARGV)
|
102
|
-
puts "args are:" + args.to_s
|
103
|
-
puts "$debug = " + $debug.to_s
|
data/lib/clui_config.rb
CHANGED
@@ -1,45 +1,84 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'command'
|
3
|
+
require_relative 'config_reader'
|
3
4
|
|
4
|
-
class
|
5
|
-
include CommandProc
|
5
|
+
class ConfigInit < Command
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
include ConfigReader
|
8
|
+
|
9
|
+
def create_flows
|
10
|
+
flow = Flow.new
|
11
|
+
flow.add(Arg.new("acct-num", desc: "EdgeCast account number", required: true, validator: /[[:alnum:]]+/))
|
12
|
+
flow.add(Arg.new("token", desc: "Web Services REST API Token (see my.edgecase.com)", required: true, validator: /.*/))
|
13
|
+
add_flow(flow)
|
9
14
|
end
|
10
15
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def execute(args, ignore)
|
17
|
+
handler = ConfigHandler.new
|
18
|
+
handler.set("acct-num", args["acct-num"])
|
19
|
+
handler.set("token", args["token"])
|
20
|
+
handler.set("rest_base_url", "https://api.edgecast.com/v2/")
|
21
|
+
|
22
|
+
print_cfg = {
|
23
|
+
"zone" => ["ZoneId", "DomainName", "ZoneType", "Status", "Version", "Records", "FailoverGroups", "LoadBalancingGroups"],
|
24
|
+
"zone.FailoverGroups.Group.AAAA" => ["Record", "IsPrimary", "HealthCheck"]
|
25
|
+
}
|
26
|
+
File.open(config_file("print.cfg"), "w").write(JSON.pretty_generate print_cfg)
|
20
27
|
end
|
28
|
+
end
|
21
29
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
puts @handler.get(args[0])
|
30
|
+
class ConfigGet < Command
|
31
|
+
def create_flows
|
32
|
+
flow = Flow.new
|
33
|
+
flow.add(Arg.new("param", desc: "name of configuration parameter", required: true, validator: /[-a-zA-Z]+/))
|
34
|
+
add_flow(flow)
|
28
35
|
end
|
29
36
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
37
|
+
def execute(args, ignore)
|
38
|
+
handler = ConfigHandler.new
|
39
|
+
puts handler.get(args["param"])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class ConfigDelete < Command
|
44
|
+
def create_flows
|
45
|
+
flow = Flow.new
|
46
|
+
flow.add(Arg.new("param", desc: "name of configuration parameter", required: true, validator: /[-a-zA-Z]+/))
|
47
|
+
add_flow(flow)
|
48
|
+
end
|
49
|
+
|
50
|
+
def execute(args, ignore)
|
51
|
+
handler = ConfigHandler.new
|
52
|
+
handler.delete(args["param"])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class ConfigSet < Command
|
57
|
+
def create_flows
|
58
|
+
flow = Flow.new
|
59
|
+
flow.add(Arg.new("param", desc: "name of configuration parameter", required: true, validator: /[-a-zA-Z]+/))
|
60
|
+
flow.add(Arg.new("value", desc: "value of configuration parameter", required: true, validator: /.*/))
|
61
|
+
add_flow(flow)
|
62
|
+
end
|
63
|
+
|
64
|
+
def execute(args, ignore)
|
65
|
+
handler = ConfigHandler.new
|
66
|
+
handler.set(args["param"], args["value"])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class ConfigCommand < Command
|
71
|
+
def create_flows
|
72
|
+
add_flow(Flow.new.add(ConfigInit.new(:init, "initialize in current directory")))
|
73
|
+
add_flow(Flow.new.add(ConfigGet.new(:get, "print configuration parameter's value")))
|
74
|
+
add_flow(Flow.new.add(ConfigDelete.new(:delete, "delete configuration parameter")))
|
75
|
+
add_flow(Flow.new.add(ConfigSet.new(:set, "set (or reset) a configuration parameter to specified value")))
|
36
76
|
end
|
37
77
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
78
|
+
def execute(args, subargs)
|
79
|
+
command = args["command"]
|
80
|
+
if command
|
81
|
+
command.run(subargs)
|
42
82
|
end
|
43
|
-
@handler.delete(args[0])
|
44
83
|
end
|
45
84
|
end
|
data/lib/command.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# template for a vzcdn command
|
2
|
+
require_relative 'args'
|
3
|
+
require_relative 'cloptions'
|
4
|
+
|
5
|
+
class Command
|
6
|
+
attr_reader :name, :desc
|
7
|
+
|
8
|
+
class CancelExecution < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(name, description)
|
12
|
+
@name = name
|
13
|
+
@desc = description
|
14
|
+
@options = [{ short_name: 'h', long_name: 'help', method: :show_help_option, takes_value: false }]
|
15
|
+
init
|
16
|
+
@flows = [ ]
|
17
|
+
@arghash = { }
|
18
|
+
add_options
|
19
|
+
create_args
|
20
|
+
create_flows
|
21
|
+
@args = nil
|
22
|
+
@full = false
|
23
|
+
@required = true
|
24
|
+
end
|
25
|
+
|
26
|
+
# TODO: make Flow keep track of next_node and fullness
|
27
|
+
def next_node
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def full?
|
32
|
+
return @full
|
33
|
+
end
|
34
|
+
|
35
|
+
def setfull
|
36
|
+
@full = true
|
37
|
+
end
|
38
|
+
|
39
|
+
def required?
|
40
|
+
@required
|
41
|
+
end
|
42
|
+
|
43
|
+
def required=(value)
|
44
|
+
@required = value
|
45
|
+
end
|
46
|
+
|
47
|
+
def init
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_options
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_args
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_flows
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_option(option)
|
60
|
+
@options << option
|
61
|
+
end
|
62
|
+
|
63
|
+
def show_help_option
|
64
|
+
show_help
|
65
|
+
raise CancelExecution
|
66
|
+
end
|
67
|
+
|
68
|
+
def show_help
|
69
|
+
puts "#{@name} - #{@desc}"
|
70
|
+
@flows.each { |flow|
|
71
|
+
names, desc = flow.usage
|
72
|
+
if (names.length > 0)
|
73
|
+
puts "usage:" + @name.to_s + " " + "#{[names].join(" ")}"
|
74
|
+
where_clause = ""
|
75
|
+
names.zip(desc).each { |name, description|
|
76
|
+
if name =~ /\A<.*>\B/
|
77
|
+
where_clause = where_clause + "\n #{name}: #{description}"
|
78
|
+
end
|
79
|
+
}
|
80
|
+
if where_clause.length > 0
|
81
|
+
puts "where:#{where_clause}"
|
82
|
+
puts ""
|
83
|
+
end
|
84
|
+
end
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_arg(name, arg)
|
89
|
+
@arghash[name] = arg
|
90
|
+
end
|
91
|
+
|
92
|
+
def add_flow_from_args(*keys)
|
93
|
+
flow = Flow.new
|
94
|
+
keys.each { |key|
|
95
|
+
flow.add(@arghash[key])
|
96
|
+
}
|
97
|
+
add_flow(flow)
|
98
|
+
end
|
99
|
+
|
100
|
+
def add_flow(flow)
|
101
|
+
@flows << flow
|
102
|
+
end
|
103
|
+
|
104
|
+
def run(args)
|
105
|
+
begin
|
106
|
+
args = ClOptions.new(self, @options).handle(args)
|
107
|
+
rescue CancelExecution
|
108
|
+
return nil
|
109
|
+
end
|
110
|
+
if args.class == String
|
111
|
+
error = args
|
112
|
+
raise error
|
113
|
+
end
|
114
|
+
|
115
|
+
@flows.each { |flow|
|
116
|
+
error, rest = flow.parse args, self
|
117
|
+
if error.nil?
|
118
|
+
execute(flow.args, rest)
|
119
|
+
return
|
120
|
+
end
|
121
|
+
}
|
122
|
+
puts "ERROR:no usage of #{@name} recognized"
|
123
|
+
puts ""
|
124
|
+
show_help
|
125
|
+
end
|
126
|
+
end
|
data/lib/common.rb
CHANGED
data/lib/config_handler.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'util'
|
2
|
+
|
1
3
|
class ConfigHandler
|
2
4
|
CONFIG_DIRECTORY = ".vdms.d"
|
3
5
|
CONFIG_FILENAME = "config"
|
@@ -9,20 +11,12 @@ class ConfigHandler
|
|
9
11
|
CONFIG_DIRECTORY + File::SEPARATOR + CONFIG_FILENAME
|
10
12
|
end
|
11
13
|
|
12
|
-
def parse_line(line)
|
13
|
-
idx = line.index('=')
|
14
|
-
if (idx)
|
15
|
-
return line[0...idx], line[idx+1..-1]
|
16
|
-
else
|
17
|
-
line
|
18
|
-
end
|
19
|
-
end
|
20
14
|
|
21
15
|
def replace_nv(name, value, new_file, orig_file)
|
22
16
|
new_config_line = name + '=' + value.to_s
|
23
17
|
wrote_line = false
|
24
18
|
orig_file.each { |line|
|
25
|
-
old_name, old_value = parse_line(line)
|
19
|
+
old_name, old_value = Util.parse_line(line)
|
26
20
|
if (old_name == name)
|
27
21
|
if ! value.nil?
|
28
22
|
new_file.puts(new_config_line)
|
@@ -48,9 +42,9 @@ class ConfigHandler
|
|
48
42
|
File.open(get_config_file).each { |line|
|
49
43
|
line = line.strip
|
50
44
|
if line[0] == '#'
|
51
|
-
|
45
|
+
next
|
52
46
|
end
|
53
|
-
name, value = parse_line(line)
|
47
|
+
name, value = Util.parse_line(line)
|
54
48
|
if value
|
55
49
|
@@config_values[name] = value
|
56
50
|
end
|