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.
@@ -0,0 +1,16 @@
1
+ require_relative 'cloptions'
2
+
3
+ options = [ { short_name: 'd', long_name: 'debug', method: :set_debug, takes_value: false},
4
+ { short_name: 'o', long_name: 'output-file', method: :set_output, takes_value: true}]
5
+
6
+ $debug=false
7
+ def set_debug
8
+ $debug = true
9
+ end
10
+ def set_output(file_name)
11
+ puts "file name = " + file_name
12
+ end
13
+ opts = ClOptions.new(self, options)
14
+ args = opts.handle(ARGV)
15
+ puts "args are:" + args.to_s
16
+ puts "$debug = " + $debug.to_s
data/lib/util.rb CHANGED
@@ -1,4 +1,14 @@
1
1
  class Util
2
+
3
+ def self.parse_line(line)
4
+ idx = line.index('=')
5
+ if (idx)
6
+ return line[0...idx], line[idx+1..-1]
7
+ else
8
+ line
9
+ end
10
+ end
11
+
2
12
  # Determines if a shell command exists by searching for it in ENV['PATH'].
3
13
  def self.command_exists?(command)
4
14
  ENV['PATH'].split(File::PATH_SEPARATOR).any? {|d| File.exists? File.join(d, command) }
data/lib/vzcdn.rb CHANGED
@@ -1,26 +1,43 @@
1
1
  #!/usr/bin/env ruby
2
- require_relative 'command_proc'
2
+ require_relative 'command'
3
+ require_relative 'args'
3
4
  require_relative 'clui_config'
4
5
  require_relative 'zone'
6
+ require_relative 'vzcdn/version'
5
7
 
6
- class VzcdnApp
7
- include CommandProc
8
+ $debug = false
8
9
 
9
- def initialize(name)
10
- @usage = {
11
- :zone => "zone related command",
12
- :config => "config related command"
13
- }
14
- @argtree = [ {:name => "zone", :usage => "zone related commands", :args=>[]},
15
- {:name => "config", :usage => "config related commands", :args=>[]}]
10
+ class VzcdnApp < Command
11
+ def add_options
12
+ add_option({ short_name: 'v', long_name: 'version', method: :print_version, takes_value: false})
13
+ add_option({ short_name: 'd', long_name: 'debug', method: :set_debug, takes_value: false})
16
14
  end
17
15
 
18
- def zone(args)
19
- Zone.invoke(args)
16
+ def print_version
17
+ puts "vzcdn version:" + Vzcdn::VERSION
20
18
  end
21
19
 
22
- def config(args)
23
- ConfigCommand.invoke(args)
20
+ def set_debug
21
+ $debug = true
22
+ end
23
+
24
+ def create_args
25
+ add_arg(:zone, Zone.new("zone", "zone"))
26
+ add_arg(:config, ConfigCommand.new("config", "config description"))
27
+ end
28
+
29
+ def create_flows
30
+ add_flow_from_args(:zone)
31
+ add_flow_from_args(:config)
32
+ end
33
+
34
+ def execute(args, subargs)
35
+ command = args["command"]
36
+ if command
37
+ command.run(subargs)
38
+ else
39
+ puts "command is nil"
40
+ end
24
41
  end
25
42
  end
26
43
 
data/lib/vzcdn/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vzcdn
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
data/lib/zone.rb CHANGED
@@ -1,100 +1,119 @@
1
1
  require_relative 'route'
2
2
  require_relative 'util'
3
- require_relative 'table_print'
3
+ require_relative 'print'
4
+ require_relative 'command'
5
+ require_relative 'args'
4
6
 
5
- class Zone
6
- include CommandProc
7
- include ConfigReader
7
+ class ZoneList < Command
8
+ def execute zone
9
+ zone.list
10
+ end
11
+ end
8
12
 
9
- def initialize(name)
10
- @zname = name
11
- @usage = { :list => "list zones"}
12
- @argflows = [ {:name => "list", :usage => "list zones", :args=>[]},
13
- {:name => "add", :usage => "", :args=>[]}]
13
+ class ZonePull < Command
14
+ def execute zone
15
+ zone.pull
14
16
  end
15
-
16
- def list(args)
17
- if @zname
18
- puts "unimplemented"
17
+ end
18
+
19
+ class ZonePrint < Command
20
+ attr_writer :struct, :level, :sep_char
21
+
22
+ def create_flows
23
+ add_flow(Flow.new)
24
+ end
25
+
26
+ def add_options
27
+ add_option({ short_name: 'j', long_name: 'json', method: :set_format, takes_value: false})
28
+ # add_option({ short_name: 'f', long_name: 'force-online', method: :force_online, takes_value: false})
29
+ end
30
+
31
+ def set_format
32
+ @format = :json
33
+ end
34
+
35
+ def execute(args, subargs)
36
+ if @format == :json
37
+ puts JSON.pretty_generate(@struct)
19
38
  else
20
- zones = Route.do.get_all_zones
21
- table = TablePrint.new("ZONE", "ID", "STATUS")
22
- zones.each {|zone|
23
- table.append(zone["DomainName"], zone["ZoneId"].to_s, Route.do.xlate_id(:zone_status, zone["Status"]))
24
- }
25
- table.print_table
39
+ StructurePrint.new(@sep_char).structure_print(@struct, @level)
26
40
  end
27
41
  end
42
+ end
28
43
 
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
44
+ class ZonePush < Command
45
+ def execute zone
46
+ zone.push
47
+ end
48
+ end
49
+
50
+ class Zone < Command
51
+ include ConfigReader
52
+
53
+ def create_args
54
+ add_arg(:list, ZoneList.new("list", "list all owned zones"))
55
+ add_arg(:pull, ZonePull.new(:pull, "retrieve local copy of zone data"))
56
+ add_arg(:push, ZonePush.new(:push, "push local changes to server"))
57
+ arg = ZonePrint.new(:print, "print zone data. ~~~~ online, ---- local copy")
58
+ arg.required = false
59
+ add_arg(:print, arg)
60
+ add_arg(:zname, Arg.new("zname", desc: "name or id of zone to pull", required: true, validator: /[[:alnum:]]+/))
61
+ add_arg(:zname2, Arg.new("zname", desc: "name or id of zone to pull", required: true, validator: /[[:alnum:]]+/))
62
+ add_arg(:drill_down, Arg.new("drill-down-param", desc: "drill down the zone structure", required: true, repeatable: true, validator: :ddverify ))
45
63
  end
46
64
 
47
- def structure_print(struct, args, header)
48
- if (struct.class == Array)
49
- # puts "printing array of " + struct.length.to_s + " elts"
50
- struct.each { |elt|
51
- # puts "calling struct_print with header = " + header.to_s + ", and elt = " + elt.to_s
52
- structure_print(elt, args, header)
53
- header = false
54
- }
55
- elsif (struct.class == Hash)
56
- if (args.length == 0)
57
- # print top level elements of hash
58
- if (header)
59
- @table = TablePrint.new(*struct.keys)
60
- end
61
- values = []
62
- struct.keys.each { |key|
63
- value = struct[key]
64
- if (value.nil?)
65
- value = "null"
66
- elsif (value.class == Array)
67
- value = value.length.to_s + " elements"
68
- elsif (value.class == String)
69
- elsif (value.class == Fixnum)
70
- value = value.to_s
71
- elsif (value.class == Hash)
72
- value = "<object>"
73
- else
74
- value = "<" + value.class.to_s + ">"
75
- end
76
- values << value
77
- }
78
- @table.append(*values)
65
+ def create_flows
66
+ add_flow_from_args(:list)
67
+ add_flow_from_args(:zname, :pull)
68
+ add_flow_from_args(:zname2, :push)
69
+ add_flow_from_args(:drill_down, :print)
70
+ end
71
+
72
+ def ddverify(value)
73
+ test = value =~ /[[:alnum:]]+/
74
+ if test
75
+ if @arghash[value.to_sym].is_a? Command
76
+ return "name of command", false
79
77
  else
80
- args = args.clone
81
- key = args.shift
82
- fullkey = match_key(key, struct)
83
- raise "no (unique) key matches " + key if ! fullkey
84
- structure_print(struct[fullkey], args, header)
78
+ return nil, true
85
79
  end
86
- else
87
- if (args.length == 0)
88
- puts struct.to_s
89
- else
90
- puts "unknown class <" + struct.class.to_s + ">"
80
+ end
81
+ return "invalid argument", false
82
+ end
83
+
84
+ def execute(args, subargs)
85
+ @zname = args["zname"]
86
+ command = args["command"]
87
+ ddparams = args["drill-down-param"]
88
+ if ddparams
89
+ @zname = ddparams.shift
90
+ zone = get_zone
91
+ @struct, @level = drill_down(zone, ddparams, "zone")
92
+ if command.nil?
93
+ command = @arghash[:print]
91
94
  end
95
+ command.struct = @struct
96
+ command.level = @level
97
+ command.sep_char = @sep_char
98
+ end
99
+ if command.class == ZonePrint
100
+ command.run subargs
101
+ elsif command
102
+ command.execute self
103
+ else
104
+ raise "error"
92
105
  end
93
106
  end
94
107
 
108
+ def list
109
+ zones = Route.do.get_all_zones
110
+ StructurePrint.new('~').structure_print(zones, "zonelist")
111
+ end
112
+
113
+
95
114
  def id_and_name
96
115
  id = name = nil
97
- if @zname.full_match /\d+/
116
+ if @zname.to_s.full_match /\d+/
98
117
  id = @zname
99
118
  else
100
119
  name = @zname
@@ -104,7 +123,8 @@ class Zone
104
123
  end
105
124
 
106
125
  def get_zone(forceRest = false)
107
- zonedir = mkdir("zones")
126
+ @sep_char = "-"
127
+ zonedir = mk_user_dir("zones")
108
128
  zone = nil
109
129
  id, name = id_and_name
110
130
  if @zname
@@ -116,57 +136,113 @@ class Zone
116
136
  end
117
137
  regex = Regexp.new(r)
118
138
  Dir.new(zonedir).each { |file|
119
- if file.full_match regex
139
+ if (file.full_match regex) && (! @force_online)
120
140
  path = File.join(zonedir, file)
121
141
  zone = JSON.parse(File.open(path).read)
122
142
  end
123
143
  }
124
144
  end
125
145
  if (zone.nil?)
146
+ dputs "getting zone with id=#{id} and name=#{name}"
147
+ @sep_char = "~"
126
148
  zone = Route.do.get_zone(id, name)
149
+ if zone.nil?
150
+ raise "zone doesn't exist or is empty"
151
+ end
152
+ File.open("raw.zone","w").write(zone)
127
153
  Route.do.translate_zone(zone)
128
154
  end
129
155
  end
130
156
  zone
131
157
  end
132
158
 
133
- def push(args)
159
+ def push
160
+ puts "in zone.push"
134
161
  zone = get_zone
135
162
  Route.do.untranslate_zone(zone)
136
163
  File.open("untranslated.zone","w").write(JSON.pretty_generate zone)
137
164
  Route.do.update_zone(zone)
138
165
  end
139
166
 
140
- def pull(args)
141
- raise("Illegal arguments:" + args.to_s) if args.length != 0
142
- raise("Must specify zone") if @zname.nil?
167
+ def pull
143
168
  zone = get_zone(true)
144
169
  file_name = zone["DomainName"].sub(/\.\Z/, '')
145
170
  file_name = file_name + '.' + zone["ZoneId"].to_s
146
- file_name = config_file("zones", file_name)
171
+ file_name = user_file("zones", file_name)
147
172
  File.delete(file_name) if File.exists?(file_name)
148
173
  File.open(file_name, "w").write(JSON.pretty_generate zone)
174
+ puts "'#{file_name}' saved locally"
149
175
  end
150
176
 
151
- def print(args)
152
- if @zname
153
- zone = get_zone
154
- if (zone.nil?)
155
- puts "zone empty"
156
- return
177
+ # let user lowercase and abbreviate key; abbreviation must match one key
178
+ def match_key(abbrev, struct)
179
+ abbrev = abbrev.downcase
180
+ key = nil
181
+ struct.keys.each { |fullkey|
182
+ testkey = fullkey.downcase
183
+ return fullkey if abbrev == testkey
184
+ if fullkey.downcase.start_with?(abbrev)
185
+ if (! key)
186
+ key = fullkey
187
+ else
188
+ return nil
189
+ end
190
+ end
191
+ }
192
+ key
193
+ end
194
+
195
+ def drill_down(struct, args, level)
196
+ if struct.class == Array && struct.length > 1 && level =~ /\[\]/
197
+ raise "too many arrays"
198
+ end
199
+ return struct,level if args.length == 0
200
+ if (struct.class == Array)
201
+ if args[0] == 'all'
202
+ result = [ ]
203
+ result_level = nil
204
+ args.shift
205
+ struct.each { |elt|
206
+ drilled_elt, drilled_level = drill_down(elt, args, level + "[]")
207
+ result << drilled_elt
208
+ result_level = drilled_level
209
+ }
210
+ return result, result_level
157
211
  end
158
- if (args.length == 1 && args[0] == "-l")
159
- puts JSON.pretty_generate(zone)
212
+ if args[0] =~ /\A\d+\Z/
213
+ index = args.shift.to_i
214
+ if index > struct.length || index <= 0
215
+ raise "index #{index} out of bounds"
216
+ end
217
+ elsif struct.length == 1
218
+ index = 1
160
219
  else
161
- @table = nil
162
- structure_print(zone, args, true)
163
- @table.print_table if @table
220
+ args.unshift "all"
221
+ return drill_down(struct, args, level)
222
+ # raise "argument #{args[0]} not understood"
164
223
  end
224
+ drill_down(struct[index - 1], args, level + "[#{index}]")
225
+ elsif (struct.class == Hash)
226
+ args = args.clone
227
+ key = args.shift
228
+ fullkey = match_key(key, struct)
229
+ raise "no (unique) key matches " + key if ! fullkey
230
+ drill_down(struct[fullkey], args, level + ".#{fullkey}")
165
231
  else
166
- puts "need zone name or id"
232
+ raise "argument #{args[0]} not understood"
167
233
  end
168
234
  end
169
235
 
236
+ def set_format
237
+ puts "in zone.set_format"
238
+ @format = :json
239
+ end
240
+
241
+ def force_online
242
+ @force_online = true
243
+ end
244
+
245
+
170
246
  def add(args)
171
247
  if @zname
172
248
  puts "unimplemented"
data/test/test_all.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require_relative 'test_reporting'
@@ -0,0 +1,142 @@
1
+ require 'reporting.rb'
2
+ require 'test/unit'
3
+ require 'pp'
4
+
5
+ class TestRestApi < Test::Unit::TestCase
6
+ def phasharray(name, arr)
7
+ puts name
8
+ PP.pp arr
9
+ end
10
+
11
+ def setup
12
+ @now = Time.new
13
+ puts ""
14
+ @media_fhh = [{:Name => "media: flash media, ", :id => MediaType::FLASH_MEDIA},
15
+ {:Name => "media: http large, ", :id => MediaType::HTTP_LARGE},
16
+ {:Name => "media: http small, ", :id => MediaType::HTTP_SMALL}]
17
+ @media_fhha = @media_fhh.clone.push({:Name => "media: adn, ", :id => MediaType::ADN})
18
+ @media_hha = @media_fhha.clone
19
+ @media_hha.shift
20
+ @media_fha = @media_fhh[0,2]
21
+ @media_fha.push(@media_fhha[3])
22
+ @media_afhha = [{:Name => "media: all, ", :id => nil}]
23
+ @media_fhha.each { |elt|
24
+ @media_afhha << elt
25
+ }
26
+
27
+ @units = [{:Name => "units: mbps, ", :id => TrafficUnits::MBPS},
28
+ {:Name => "units: GB, ", :id => TrafficUnits::GB}]
29
+ end
30
+
31
+ def test_traffic_usage
32
+ billing_month = @now - 50*24*60*60
33
+ puts "traffic usage for billing month in " + billing_month.strftime("%Y-%m-01")
34
+ @media_fhha.each { |media|
35
+ get_billing_regions.each { |region|
36
+ region_name = region["Name"]
37
+ if (region_name != "Global")
38
+ @units.each { |units|
39
+ puts media[:Name] + "region: " + region_name + ", " + units[:Name] +
40
+ get_traffic_usage(media[:id], region["Id"], units[:id], billing_month).to_s
41
+ }
42
+ end
43
+ }
44
+ }
45
+ end
46
+
47
+ def test_report_codes
48
+ puts "report codes"
49
+ @media_afhha.each { |media|
50
+ puts media[:Name] + get_report_codes(media[:id]).to_s
51
+ }
52
+ end
53
+
54
+ def test_maximum_storage_usage
55
+ puts "maximum storage usage"
56
+ puts get_maximum_storage_usage(@now-7*24*60*60, @now)
57
+ end
58
+
59
+ def test_download_activity
60
+ puts "download activity"
61
+ @media_fha.each { |media|
62
+ puts media[:Name] + get_download_activity(media[:id], @now-24*60*60, @now).to_s
63
+ }
64
+ end
65
+
66
+ def test_directory_activity
67
+ puts "directory activity"
68
+ @media_fha.each { |media|
69
+ puts media[:Name] + get_directory_activity(media[:id], @now-24*60*60, @now).to_s
70
+ }
71
+ end
72
+
73
+ def test_xferred_interval
74
+ puts "all regions: " + get_data_transferred_by_platform_and_interval(nil, @now-30*60, @now, nil, nil).to_s
75
+ regions = get_billing_regions
76
+ regions.each { |region|
77
+ puts "region: " + region["Name"] + ", " + get_data_transferred_by_platform_and_interval(nil, @now-30*60, @now, region["Id"], nil).to_s
78
+ }
79
+ puts "every 5 minutes: " + get_data_transferred_by_platform_and_interval(nil, @now-30*60, @now, nil, Interval::FIVE_MINUTE).to_s
80
+ puts "every hour: " + get_data_transferred_by_platform_and_interval(nil, @now-10*60*60, @now, nil, Interval::HOURLY).to_s
81
+ puts "every day: " + get_data_transferred_by_platform_and_interval(nil, @now-5*24*60*60, @now, nil, Interval::DAILY).to_s
82
+ puts "flash media: " + get_data_transferred_by_platform_and_interval(MediaType::FLASH_MEDIA, @now-30*60, @now, nil, nil).to_s
83
+ puts "http large: " + get_data_transferred_by_platform_and_interval(MediaType::HTTP_LARGE, @now-30*60, @now, nil, nil).to_s
84
+ puts "http large ssl only: " + get_data_transferred_by_platform_and_interval(MediaType::HTTP_LARGE_SSL, @now-30*60, @now, nil, nil).to_s
85
+ puts "http large dfw: " + get_data_transferred_by_platform_and_interval(MediaType::HTTP_LARGE, @now-30*60, @now, nil, nil, "dfw").to_s
86
+ puts "http large lax, dca, mia, dfw: " + get_data_transferred_by_platform_and_interval(MediaType::HTTP_LARGE, @now-30*60, @now, nil, nil, "lax", "dca", "mia", "dfw").to_s
87
+ puts "http small: " + get_data_transferred_by_platform_and_interval(MediaType::HTTP_SMALL, @now-30*60, @now, nil, nil).to_s
88
+ puts "http small ssl only: " + get_data_transferred_by_platform_and_interval(MediaType::HTTP_SMALL_SSL, @now-30*60, @now, nil, nil).to_s
89
+ puts "adn: " + get_data_transferred_by_platform_and_interval(MediaType::ADN, @now-30*60, @now, nil, nil).to_s
90
+ puts "adn ssl only: " + get_data_transferred_by_platform_and_interval(MediaType::ADN_SSL, @now-30*60, @now, nil, nil).to_s
91
+ end
92
+
93
+ def test_xferred
94
+ puts "flash media: " + get_data_transferred_by_platform(MediaType::FLASH_MEDIA, @now-24*60*60, @now).to_s
95
+ puts "http large: " + get_data_transferred_by_platform(MediaType::HTTP_LARGE, @now-24*60*60, @now).to_s
96
+ # puts "http large ssl only: " + get_data_transferred_by_platform(MediaType::HTTP_LARGE_SSL, @now-24*60*60, @now).to_s
97
+ puts "http large dfw: " + get_data_transferred_by_platform(MediaType::HTTP_LARGE, @now-24*60*60, @now, "dfw").to_s
98
+ puts "http large lax, dca, mia, dfw: " + get_data_transferred_by_platform(MediaType::HTTP_LARGE, @now-24*60*60, @now, "lax", "dca", "mia", "dfw").to_s
99
+ puts "http small: " + get_data_transferred_by_platform(MediaType::HTTP_SMALL, @now-24*60*60, @now).to_s
100
+ # puts "http small ssl only: " + get_data_transferred_by_platform(MediaType::HTTP_SMALL_SSL, @now-24*60*60, @now).to_s
101
+ puts "adn: " + get_data_transferred_by_platform(MediaType::ADN, @now-24*60*60, @now).to_s
102
+ # puts "adn ssl only: " + get_data_transferred_by_platform(MediaType::ADN_SSL, @now-24*60*60, @now).to_s
103
+ end
104
+
105
+ def test_xferred_codes
106
+ puts "flash media: " + get_data_transferred_and_hits_by_custom_report_codes(MediaType::FLASH_MEDIA, @now-24*60*60, @now).to_s
107
+ puts "http large: " + get_data_transferred_and_hits_by_custom_report_codes(MediaType::HTTP_LARGE, @now-24*60*60, @now).to_s
108
+ puts "http small: " + get_data_transferred_and_hits_by_custom_report_codes(MediaType::HTTP_SMALL, @now-24*60*60, @now).to_s
109
+ puts "adn: " + get_data_transferred_and_hits_by_custom_report_codes(MediaType::ADN, @now-24*60*60, @now).to_s
110
+ end
111
+
112
+ def test_xferred_all
113
+ puts get_all_data_transferred(@now-24*60*60, @now)
114
+ puts get_all_data_transferred(@now-4*60*60, @now, "dfw")
115
+ puts get_all_data_transferred(@now-60*60, @now, "lax", "dca", "mia", "dfw")
116
+ end
117
+
118
+ def test_customer_name
119
+ puts "customer name: " + get_customer_name.to_s
120
+ end
121
+
122
+ def test_account_number
123
+ # puts "account number: " + get_customer_account_number("NMK01").to_s
124
+ end
125
+
126
+ def test_assec_activity
127
+ puts "flash media: " + get_asset_activity(MediaType::FLASH_MEDIA, @now-24*60*60, @now).to_s
128
+ puts "http large: " + get_asset_activity(MediaType::HTTP_LARGE, @now-24*60*60, @now).to_s
129
+ puts "http small: " + get_asset_activity(MediaType::HTTP_SMALL, @now-24*60*60, @now).to_s
130
+ puts "ADN: " + get_asset_activity(MediaType::ADN, @now-24*60*60, @now).to_s
131
+ end
132
+
133
+ def test_status_activity
134
+ puts "http large: " + get_cache_status_activity(MediaType::HTTP_LARGE, @now-24*60*60, @now).to_s
135
+ puts "http small: " + get_cache_status_activity(MediaType::HTTP_SMALL, @now-24*60*60, @now).to_s
136
+ puts "ADN: " + get_cache_status_activity(MediaType::ADN, @now-24*60*60, @now).to_s
137
+ end
138
+
139
+ def test_storage_usage
140
+ puts "current_storage_usage: " + get_current_storage_usage.to_s
141
+ end
142
+ end