vzcdn 0.1.9 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a57e7a8b331b7ded73bccae8a4d2fccc3640ab6
4
- data.tar.gz: 5442f2e2e84bf6df14f05b498eee315f9bbe2dc0
3
+ metadata.gz: 908fd60bab73ffcb6b51ee5800cf18bc1f342497
4
+ data.tar.gz: e5977af1560fc83e7f2065c2665a70fc36faeec0
5
5
  SHA512:
6
- metadata.gz: 0f7424dd530ce0dbf3f53221510dfdc4a5522bc4a9feb1d730d6ab0452b5a4bc411d07b9c1268f8aa4e25af8fd8d4020281add0561f9b358e9ef2a6f5a4c8199
7
- data.tar.gz: 3d8dbc180663af1207657cc9fdd7f14b27f1d39b5adf0817b2fbf5e21e88bfe738ac7c1bdb8e1c077074f601b9db6f483c3856c6a68093ff26621eda4b8cdeaa
6
+ metadata.gz: 1157b4228fd58982be432b0a67f1a3c73ed1cd7850a2fd6f584afd305f2b935e68a375583879c4936ec1e18940267f567235cbae7d93f6c235e6bf01874304b1
7
+ data.tar.gz: f55a563fcb6999f967f4a14e3260635095275ec1191a734a23eb08c986e65e7a8978dffbc5e2de127bc5ca03870ef088036e02616e95aca68e8fdcabab93e166
data/README.md CHANGED
@@ -4,6 +4,10 @@ Commandline UI for Edgecast API
4
4
 
5
5
  ##RELEASE NOTES
6
6
 
7
+ 2014/05/02 0.2.0
8
+ * Add/Update/Delete for groups/records/health-checks in zone.
9
+ * Zone-list with local status
10
+
7
11
  2014/04/22 0.1.9
8
12
  * Create zone support
9
13
  * Add record support
@@ -39,7 +43,7 @@ Or install it yourself as:
39
43
  $ gem install vzcdn
40
44
 
41
45
  ## Usage
42
-
46
+ http://youtu.be/y8MnWYxZiiA
43
47
 
44
48
  ## Contributing
45
49
 
data/bin/ec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'vzcdn'
4
4
 
5
- # $debug = true
5
+ $debug = 0
6
6
 
7
7
  def add_prefix(prefix, text)
8
8
  result = ""
@@ -13,18 +13,28 @@ def add_prefix(prefix, text)
13
13
  end
14
14
 
15
15
  def dputs(*args)
16
- if $debug
16
+ if $debug > 0
17
17
  puts *args
18
18
  end
19
19
  end
20
20
 
21
+ def ddputs(*args)
22
+ if $debug > 1
23
+ puts *args
24
+ end
25
+ end
26
+
27
+
21
28
  begin
22
- VzcdnApp.new("vzcdn", "vzcdn").run(ARGV)
29
+ scriptname = File.basename $0
30
+ $USER_ENTERED_COMMAND = scriptname + ' ' + ARGV.join(' ')
31
+ VzcdnApp.new(scriptname, "(vzcdn or ec) EdgeCast command line interface").run(ARGV)
23
32
  exit 0
24
33
  rescue Exception => e
25
34
  if e.class != SystemExit
26
35
  puts add_prefix("ERROR:", e.message)
27
- if $debug
36
+ dputs e.backtrace[0]
37
+ if $debug > 1
28
38
  raise e
29
39
  else
30
40
  exit 1
data/bin/vzcdn CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'vzcdn'
4
4
 
5
- # $debug = true
5
+ $debug = 0
6
6
 
7
7
  def add_prefix(prefix, text)
8
8
  result = ""
@@ -13,18 +13,28 @@ def add_prefix(prefix, text)
13
13
  end
14
14
 
15
15
  def dputs(*args)
16
- if $debug
16
+ if $debug > 0
17
17
  puts *args
18
18
  end
19
19
  end
20
20
 
21
+ def ddputs(*args)
22
+ if $debug > 1
23
+ puts *args
24
+ end
25
+ end
26
+
27
+
21
28
  begin
22
- VzcdnApp.new("vzcdn", "vzcdn").run(ARGV)
29
+ scriptname = File.basename $0
30
+ $USER_ENTERED_COMMAND = scriptname + ' ' + ARGV.join(' ')
31
+ VzcdnApp.new(scriptname, "(vzcdn or ec) EdgeCast command line interface").run(ARGV)
23
32
  exit 0
24
33
  rescue Exception => e
25
34
  if e.class != SystemExit
26
35
  puts add_prefix("ERROR:", e.message)
27
- if $debug
36
+ dputs e.backtrace[0]
37
+ if $debug > 1
28
38
  raise e
29
39
  else
30
40
  exit 1
@@ -55,7 +55,12 @@ class Cell
55
55
  set(@default, nil)
56
56
  end
57
57
  return false unless @required
58
- @value.nil?
58
+ # @required is true
59
+ if @repeatable && @value == [ ]
60
+ true
61
+ else
62
+ @value.nil?
63
+ end
59
64
  end
60
65
 
61
66
  def name
@@ -92,9 +97,9 @@ class Arg
92
97
  test = @validator.has_key? value
93
98
  on_error = "Invalid choice for #{@name}, must be one of #{@validator.keys}"
94
99
  elsif vclass == String
95
- result = {}
100
+ result = [ ]
96
101
  Route.new.send("get_available_" + @validator).each { |hash|
97
- result[hash["Name"]] = hash["Id"]
102
+ result << hash["Name"]
98
103
  }
99
104
  @validator = result
100
105
  test = validate?(value, obj)
@@ -119,7 +124,7 @@ class Arg
119
124
  end
120
125
 
121
126
  class Flow
122
- attr_accessor :usage_string
127
+ attr_accessor :usage_string, :pre_cond, :rest, :error
123
128
 
124
129
  def initialize
125
130
  @cells = [ ]
@@ -133,30 +138,35 @@ class Flow
133
138
 
134
139
  def parse(args, obj = nil)
135
140
  @target = obj
136
- rest = [ ]
141
+ @rest = [ ]
137
142
  args.each_with_index { |arg, index|
143
+ if finished || @error
144
+ @rest = args[index..-1]
145
+ break
146
+ end
138
147
  name, value = Util.parse_line(arg)
139
148
  if value.nil?
140
149
  value = name
141
- error, finished = setvalue(value)
150
+ setvalue(value)
142
151
  else
143
- error, finished = set(name, value)
144
- end
145
- if error
146
- result = add_errline(result, error)
147
- finished = :finished
148
- end
149
- if finished
150
- rest = args[index..-1]
151
- break
152
+ set(name, value)
152
153
  end
153
154
  }
154
155
  missing = missing_args
155
- unless missing.empty?
156
- result = add_errline(result, "missing args: #{missing}")
156
+ @error.nil?
157
+ end
158
+
159
+ def finished
160
+ if command && @cells[-1].full?
161
+ # the command was seen
162
+ return true
157
163
  end
158
- # dputs "parse for class #{obj.class} result=#{result}, rest=#{rest}"
159
- return result, rest
164
+ @cells.each { |cell|
165
+ if ! cell.full?
166
+ return false
167
+ end
168
+ }
169
+ return true
160
170
  end
161
171
 
162
172
  def setvalue(value)
@@ -165,13 +175,18 @@ class Flow
165
175
  next
166
176
  else
167
177
  error = cell.set(value, @target)
168
- if error && cell.repeatable
169
- next
170
- end
171
- return error, nil
178
+ if error
179
+ if cell.repeatable
180
+ next # repeatable cell is now full; try to set next cell
181
+ else
182
+ add_errline(error)
183
+ return
184
+ end
185
+ end
186
+ return
172
187
  end
173
188
  }
174
- return nil, :finished
189
+ return
175
190
  end
176
191
 
177
192
  def missing_args
@@ -181,16 +196,19 @@ class Flow
181
196
  missing << cell.name
182
197
  end
183
198
  }
184
- missing
199
+ if missing.length > 0
200
+ add_errline("missing args: #{missing}")
201
+ end
185
202
  end
186
203
 
187
204
  def set(name, value)
188
205
  @cells.each { |cell|
189
206
  if cell.name == name
190
- return cell.set(value, @target), nil
207
+ add_errline(cell.set(value, @target))
208
+ return
191
209
  end
192
210
  }
193
- return "argument named #{name} not found", nil
211
+ add_errline("argument named #{name} not found")
194
212
  end
195
213
 
196
214
  def command
@@ -218,11 +236,12 @@ class Flow
218
236
  return names, desc
219
237
  end
220
238
 
221
- def add_errline(str, error)
222
- if str
223
- str + "\n" + error
239
+ def add_errline(errmsg)
240
+ return if errmsg.nil?
241
+ if @error.nil?
242
+ @error = errmsg
224
243
  else
225
- error
244
+ @error = @error + "\n" + errmsg
226
245
  end
227
246
  end
228
247
  end
@@ -8,7 +8,7 @@ class ConfigInit < Command
8
8
 
9
9
  def create_args
10
10
  add_arg("acct-num", "EdgeCast account number", /[[:alnum:]]+/)
11
- add_arg("token", "Web Services REST API Token (see my.edgecase.com)", /.*/)
11
+ add_arg("token", "Web Services REST API Token (see my.edgecast.com)", /.*/)
12
12
  end
13
13
 
14
14
  def create_flows
@@ -23,7 +23,6 @@ class ConfigInit < Command
23
23
 
24
24
  print_cfg = {
25
25
  "zone" => ["ZoneId", "DomainName", "ZoneType", "Status", "Version", "Records", "FailoverGroups", "LoadBalancingGroups"],
26
- "zone.FailoverGroups.Group.AAAA" => ["Record", "IsPrimary", "HealthCheck"],
27
26
  "zonelist" => ["DomainName", "ZoneId", "Status"]
28
27
  }
29
28
  File.open(config_file("print.cfg"), "w").write(JSON.pretty_generate print_cfg)
@@ -45,28 +45,18 @@ class Command
45
45
  @options << option
46
46
  end
47
47
 
48
- def show_help_option
49
- show_help
50
- raise CancelExecution
51
- end
52
-
53
- def get_args_used(usage, args_used)
54
- line = usage
55
- re = /<(?<argname>[[:alnum:]-]+)>/
56
- while m = re.match(line)
57
- argname = m[:argname]
58
- unless args_used.include? argname
59
- args_used << argname
60
- end
61
- line = line[m.end(0)..-1]
62
- end
63
- end
64
-
65
48
  def show_help
66
49
  puts "#{@name} - #{@desc}"
50
+ valid_flows = @flows.select { |flow|
51
+ flow_passes_preconditions(flow)
52
+ }
53
+ if valid_flows.length == 0
54
+ puts "No usage of #{@name} is valid in this context"
55
+ valid_flows = @flows
56
+ end
67
57
  puts "Usage:"
68
58
  args_used = [ ]
69
- @flows.each { |flow|
59
+ valid_flows.each { |flow|
70
60
  puts " #{@name} #{flow.usage_string}"
71
61
  get_args_used(flow.usage_string, args_used)
72
62
  }
@@ -87,6 +77,27 @@ class Command
87
77
  puts " #{arg.name} : #{arg.desc}#{choice}"
88
78
  }
89
79
  end
80
+ puts "Options:"
81
+ @options.each { | o |
82
+ puts " -#{o[:short_name]} or --#{o[:long_name]}" + (o[:takes_value] ? " (takes value)" : "")
83
+ }
84
+ end
85
+
86
+ def show_help_option
87
+ show_help
88
+ raise CancelExecution
89
+ end
90
+
91
+ def get_args_used(usage, args_used)
92
+ line = usage
93
+ re = /<(?<argname>[[:alnum:]-]+)>/
94
+ while m = re.match(line)
95
+ argname = m[:argname]
96
+ unless args_used.include? argname
97
+ args_used << argname
98
+ end
99
+ line = line[m.end(0)..-1]
100
+ end
90
101
  end
91
102
 
92
103
  def add_arg(name, desc, validator)
@@ -106,9 +117,10 @@ class Command
106
117
  @subcommands.include?(str.to_s)
107
118
  end
108
119
 
109
- def add_flow_from_usage(usage)
120
+ def add_flow_from_usage(usage, *pre_cond)
110
121
  flow = Flow.new
111
122
  flow.usage_string = usage
123
+ flow.pre_cond = pre_cond
112
124
  line = usage
113
125
  re = /\A
114
126
  ( # matches one arg spec
@@ -137,6 +149,34 @@ class Command
137
149
  @flows << flow
138
150
  end
139
151
 
152
+ def flow_passes_parse(flow, args)
153
+ desc = "usage \'#{@name} #{flow.usage_string}\'"
154
+ result = true
155
+ success = flow.parse args, self
156
+ if success
157
+ if flow.command.nil? && flow.rest.length > 0
158
+ result = false
159
+ ddputs "#{desc} failed (args=#{args}) due to superfluous arguments (#{flow.rest})"
160
+ else
161
+ ddputs "#{desc} passed parse, adding to candidate list (rest=#{flow.rest})"
162
+ end
163
+ else
164
+ result = false
165
+ ddputs "#{desc} failed to parse arguments (args=#{args}), #{flow.error}"
166
+ end
167
+ return result
168
+ end
169
+
170
+ def flow_passes_preconditions(flow)
171
+ if flow.pre_cond && flow.pre_cond.length > 0 && (error = send(*flow.pre_cond))
172
+ dputs "usage \'#{@name} #{flow.usage_string}\' failed due to precondition failure:#{error}"
173
+ false
174
+ else
175
+ ddputs "usage \'#{@name} #{flow.usage_string}\' passed any precondition"
176
+ true
177
+ end
178
+ end
179
+
140
180
  def run(args)
141
181
  begin
142
182
  args = ClOptions.new(self, @options).handle(args)
@@ -148,15 +188,28 @@ class Command
148
188
  raise error
149
189
  end
150
190
 
151
- @flows.each { |flow|
152
- error, rest = flow.parse args, self
153
- if error.nil?
154
- execute(flow.arghash, rest)
155
- return
156
- end
191
+ candidate_flows = @flows.select { |flow|
192
+ flow_passes_parse(flow, args)
157
193
  }
158
- puts "ERROR:no usage of #{@name} recognized"
159
- puts ""
160
- show_help
194
+
195
+ valid_flows = candidate_flows.select { |flow|
196
+ flow_passes_preconditions(flow)
197
+ }
198
+
199
+ if valid_flows.length == 1
200
+ flow = valid_flows[0]
201
+ ddputs "usage \'#{@name} #{flow.usage_string}\' matched, executing"
202
+ execute(flow.arghash, flow.rest)
203
+ elsif valid_flows.length > 1
204
+ puts "BUG FOUND: arguments #{args} match the following flows in class #{self.class}"
205
+ valid_flows.each { |flow|
206
+ puts " usage \'#{@name} #{flow.usage_string}\'"
207
+ }
208
+ else
209
+ unless args.length == 0
210
+ puts "ERROR:no usage of #{@name} recognized or allowed\n\n"
211
+ end
212
+ show_help
213
+ end
161
214
  end
162
215
  end
@@ -39,7 +39,7 @@ class CommonRestUtils
39
39
  end
40
40
  end
41
41
  exit
42
- if $debug
42
+ if $debug > 0
43
43
  puts "full URL is:" + url
44
44
  if (body)
45
45
  puts "body is: json_body"
@@ -51,7 +51,7 @@ class CommonRestUtils
51
51
  raise "Bad response code:" + response.code.to_s
52
52
  end
53
53
  if (response.length > 0)
54
- if $debug
54
+ if $debug > 1
55
55
  File.open("raw.json", "w").write(response)
56
56
  end
57
57
  JSON.parse response
@@ -8,26 +8,18 @@ module ConfigReader
8
8
  ConfigHandler::CONFIG_DIRECTORY
9
9
  end
10
10
 
11
- def imkdir(path)
12
- if ! Dir.exists?(path)
13
- Dir.mkdir path
14
- end
15
- path
16
- end
17
-
18
- def mk_user_dir(*dirs)
19
- imkdir user_file(*dirs)
20
- end
21
-
22
- def mk_config_dir(*dirs)
23
- imkdir config_file(*dirs)
11
+ def mkdir(filename)
12
+ FileUtils.mkdir_p(File.dirname(filename))
13
+ filename
24
14
  end
25
15
 
26
16
  def user_file(*dirs_file)
27
- File.join(*dirs_file)
17
+ result = File.join(*dirs_file)
18
+ mkdir result
28
19
  end
29
20
 
30
21
  def config_file(*dirs_file)
31
- File.join(config_dir, *dirs_file)
22
+ filename = File.join(config_dir, *dirs_file)
23
+ mkdir filename
32
24
  end
33
25
  end