attsynaptic-synaptic4r 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,6 @@
1
+ *~
2
+ *.sw?
3
+ .DS_Store
4
+ coverage
5
+ rdoc
6
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Copyright (c) 2009 AT&T Intellectual Property.
2
+
3
+ All rights reserved.
4
+
5
+ AT&T, AT&T logo and all other AT&T marks contained herein
6
+ are trademarks of AT&T Intellectual Property and/or AT&T affiliated companies.
7
+
8
+ All other trademarks are the property of their owners.
9
+
10
+ The above copyright notice shall be included in all copies or
11
+ substantial portions of the Software.
@@ -0,0 +1,79 @@
1
+ = synaptic4r
2
+
3
+ Ruby REST Client and CLI for ATT Synaptic Storage. The CLI directly maps
4
+ onto the REST API and can be used to inspect request headers and payloads, as well as,
5
+ a reference for the REST API.
6
+
7
+ == Install
8
+
9
+ == Credentials
10
+
11
+ Save credentials to $HOME/.synaptic4r
12
+
13
+ single account
14
+
15
+ subtenant: SubtenantID
16
+ uid: UserID
17
+ key: SecretKey
18
+ site: https://storage.synaptic.att.com/rest
19
+
20
+ multiple accounts (the first is used by default, the dashes must
21
+ be included in the file)
22
+
23
+ -
24
+ account: myacct
25
+ subtenant: SubtenantID
26
+ uid: UserID
27
+ key: SecretKey
28
+ site: https://storage.synaptic.att.com/rest
29
+
30
+ -
31
+ account: myotheracct
32
+ subtenant: OtherSubtenantID
33
+ uid: OtherUserID
34
+ key: OtherSecretKey
35
+ site: https://storage.synaptic.att.com/rest
36
+
37
+ == Basic CLI Commands
38
+
39
+ list information here
40
+
41
+ synrest get-started
42
+
43
+ list all commands with descriptions
44
+
45
+ synrest
46
+
47
+ list contents of remote root directory
48
+
49
+ synrest get
50
+
51
+ create a remote directory named foo
52
+
53
+ synrest create-dir foo
54
+
55
+ upload a file to directory foo
56
+
57
+ synrest create-file file.txt foo/
58
+
59
+ list contents remote directory foo
60
+
61
+ synrest get foo
62
+
63
+ list contents remote file foo/file.txt
64
+
65
+ synrest get foo/file.txt
66
+
67
+ execute command for account other than default
68
+
69
+ synrest command args [options] -u myotheracct
70
+
71
+ show examples for a command
72
+
73
+ synrest command examples
74
+
75
+
76
+
77
+ == Copyright
78
+
79
+ Copyright (c) 2009 ATT. See LICENSE for details.
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "synaptic4r"
8
+ gem.summary = "CLI and Ruby REST Client for ATT Synaptic Storage"
9
+ gem.email = "troy.stribling@usi.com"
10
+ gem.homepage = "http://github.com/troystribling-att/synaptic4r"
11
+ gem.authors = ["troystribling-att"]
12
+ gem.add_dependency('rake', '>= 0.8.3')
13
+ gem.add_dependency('rest-client', '>= 1.0.2')
14
+ end
15
+
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/*_test.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ if File.exist?('VERSION.yml')
46
+ config = YAML.load(File.read('VERSION.yml'))
47
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "synaptic4r #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
57
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.4
@@ -0,0 +1,316 @@
1
+ #!/usr/bin/ruby
2
+
3
+ ####---------------------------------------------------------------------------------------------------------
4
+ SYNLIB = "#{File.dirname($0)}/../lib"
5
+ $:.unshift(SYNLIB) unless $:.include?(SYNLIB)
6
+
7
+ ####---------------------------------------------------------------------------------------------------------
8
+ require 'yaml'
9
+ require 'optparse'
10
+ require 'synaptic4r'
11
+ require 'logger'
12
+
13
+ #############################################################################################################
14
+ ####---------------------------------------------------------------------------------------------------------
15
+ def credentials_configured?
16
+ config_keys = %w(key site subtenant uid)
17
+ status = if File.exists?(Synaptic4r::Client.config_file)
18
+ config = File.open(Synaptic4r::Client.config_file){|yf| YAML::load(yf)}
19
+ if config.kind_of?(Hash)
20
+ config.keys.sort.eql?(config_keys) or config.keys.sort.eql?(config_keys.unshift('account'))
21
+ elsif config.kind_of?(Array)
22
+ config_keys.unshift('account')
23
+ config.select{|c| c.keys.sort.eql?(config_keys)}.length.eql?(config.length)
24
+ else
25
+ puts "#{Synaptic4r::Client.config_file} not formatted properly"
26
+ exit
27
+ end
28
+ else
29
+ puts "#{Synaptic4r::Client.config_file} not found"
30
+ exit
31
+ end
32
+ unless status
33
+ puts "#{Synaptic4r::Client.config_file} missing one of 'key', 'site', 'subtenant' or 'uid'"
34
+ exit
35
+ end
36
+ end
37
+
38
+ ####---------------------------------------------------------------------------------------------------------
39
+ def dump(cmd, input, result)
40
+ output = if input[:dump]
41
+ <<-DUMP
42
+ COMMAND: #{cmd}
43
+ ARGS: #{input.inspect}
44
+ SIGNING STRING: #{result.sign.inspect}
45
+ HTTP METHOD: #{result.http_request}
46
+ URL: #{result.url}
47
+ HEADERS: #{result.headers.inspect}
48
+ DUMP
49
+ else; ''; end
50
+ if input[:payload] and result.payload
51
+ output + "PAYLOAD:\n" + result.payload
52
+ else
53
+ output
54
+ end
55
+ end
56
+
57
+ ####---------------------------------------------------------------------------------------------------------
58
+ def run(cmd, input)
59
+ begin
60
+ result = Synaptic4r::Client.new(input[:account].nil? ? nil : {:account => input[:account]}).send(cmd, input)
61
+ {:out => (input[:dump] or input[:payload]) ? dump(cmd, input, result) : result.print, :logger => :info}
62
+ rescue RestClient::RequestFailed, RestClient::ResourceNotFound, RestClient::Unauthorized,
63
+ RestClient::NotModified => err
64
+ {:out => "#{err.message}\n" + Synaptic4r::RequestError.new(err).print, :logger => :error}
65
+ rescue RestClient::Redirect, RestClient::ServerBrokeConnection, RestClient::RequestTimeout => err
66
+ {:out => err.message, :logger => :error}
67
+ rescue ArgumentError => err
68
+ {:out => err.to_s, :logger => :error}
69
+ rescue Errno::ENOENT, Errno::EISDIR => err
70
+ {:out => err.to_s, :logger => :error}
71
+ end
72
+ end
73
+
74
+ ####---------------------------------------------------------------------------------------------------------
75
+ def extract_cmd(meths)
76
+ if ARGV.first
77
+ if meths.include?(ARGV.first.gsub(/-/,'_').to_sym)
78
+ ARGV.shift.gsub(/-/,'_').to_sym
79
+ else
80
+ puts "Error: '#{ARGV.first}' is not a valid command"
81
+ exit
82
+ end
83
+ end
84
+ end
85
+
86
+ ####---------------------------------------------------------------------------------------------------------
87
+ def format_required_args(args)
88
+ args.inject("") do |f,a|
89
+ aname = lambda{|v,l| arg_name(Synaptic4r::Request.rest_arg(v),l)}
90
+ if a.kind_of?(Array)
91
+ f + [aname[a.first,false],a[1..-1].map{|v| aname[v,true]}].join('|') + ' '
92
+ else
93
+ "#{f}#{aname[a, false]} "
94
+ end
95
+ end.chomp(' ')
96
+ end
97
+
98
+ ####---------------------------------------------------------------------------------------------------------
99
+ def diagnostic_args(opts, input, cmd)
100
+ if Synaptic4r::Request.diagnostics(cmd)
101
+ opts.separator "\ndiagnostic options"
102
+ opts.on('-q', '--dump', 'do not send request but print headers and service url to STDOUT'){|d| input[:dump] = true}
103
+ opts.on('-p', '--payload', 'do not send request print payload to STDOUT if present'){|p| input[:payload] = true}
104
+ opts.on('-l', '--log [file]', 'log request to file (by default file is synaptic4r.log)') do |file|
105
+ input[:log] = true
106
+ input[:log_file] = file
107
+ end
108
+ end
109
+ opts.on_tail('-h', '--help', "this listing\n") {
110
+ puts
111
+ puts opts
112
+ puts "Examples: synrest #{cmd.to_s.gsub(/_/,'-')} examples\n\n"
113
+ exit
114
+ }
115
+ end
116
+
117
+ ####---------------------------------------------------------------------------------------------------------
118
+ def set_opts(opts, input, opt_args)
119
+ opt_args = [opt_args].flatten
120
+ unless opt_args.empty?
121
+ opts.separator "\noptions"
122
+ opt_args.sort_by{|m| m.to_s}.each do |a|
123
+ arg_info = Synaptic4r::Request.rest_arg(a)
124
+ sopt = arg_info[:cli][1]
125
+ lopt = "--#{arg_info[:cli][0]}" + (arg_info[:cli][2].eql?(:flag) ? '' : " #{arg_info[:cli][0]}")
126
+ opts.on(sopt, lopt, arg_info[:desc]) do |v|
127
+ input[a] = arg_info[:map].nil? ? v : arg_info[:map][v]
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ ####---------------------------------------------------------------------------------------------------------
134
+ def set_args(opts, meths, input, cmd)
135
+ extract_positional_args(meths, input, cmd)
136
+ all_args = Synaptic4r::Request.required_rest_args(cmd)
137
+ fmt = " %-32s %s"
138
+ unless all_args.empty?
139
+ opts.separator "\nargs"
140
+ arg_row = lambda{|a,l| arg_info = Synaptic4r::Request.rest_arg(a)
141
+ opts.separator fmt % [arg_name(arg_info,l), arg_info[:desc]]}
142
+ all_args.each do |a|
143
+ if a.kind_of?(Array)
144
+ opts.separator "one of"
145
+ arg_row[a.first,false]
146
+ a[1..-1].each{|e| arg_row[e,true]}
147
+ else
148
+ arg_row[a,false]
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ ####---------------------------------------------------------------------------------------------------------
155
+ def prep_argv
156
+ add = true
157
+ inargs = ARGV.inject([]) do |o,a|
158
+ if /^-/.match(a)
159
+ i = ARGV.index(a)
160
+ n = ARGV[i+1]
161
+ if n and not /^-/.match(n)
162
+ add = false; o << [a,n].join(' ')
163
+ else
164
+ o << a
165
+ end
166
+ elsif add
167
+ o << a
168
+ else
169
+ add = true; o
170
+ end
171
+ end
172
+ end
173
+
174
+ ####---------------------------------------------------------------------------------------------------------
175
+ def extract_positional_args(meths, input, cmd)
176
+ eargs = Synaptic4r::Request.required_rest_args(cmd)
177
+ elength = eargs.length
178
+ pvals= prep_argv.first(elength)
179
+ nvals = if Synaptic4r::Request.map_required_args(cmd)
180
+ Synaptic4r::Request.map_required_args(cmd)[pvals]
181
+ else
182
+ {:pvals => pvals, :dlen => 0}
183
+ end
184
+ if pvals.include?('-h')
185
+ elsif ARGV.first.eql?('examples')
186
+ begin
187
+ send("#{cmd}_examples".to_sym)
188
+ exit
189
+ rescue NoMethodError
190
+ puts "'#{cmd.to_s.gsub(/_/,'-')}' examples are not availble"
191
+ exit
192
+ end
193
+ elsif nvals[:pvals].length < elength
194
+ puts "Error: expecting args '#{format_required_args(eargs)}'"
195
+ exit
196
+ else
197
+ set_positional_args(input, nvals, eargs)
198
+ end
199
+ end
200
+
201
+ ####---------------------------------------------------------------------------------------------------------
202
+ def set_positional_args(input, nvals, eargs)
203
+ assign_input = lambda{|a,v| info = Synaptic4r::Request.rest_arg(a);
204
+ input[a] = info[:map].nil? ? v : info[:map][v]}
205
+ length = 0
206
+ nvals[:pvals].each_index do |i|
207
+ pv = nvals[:pvals][i]
208
+ ea = eargs[i]
209
+ if ea.kind_of?(Array)
210
+ if /^-/.match(pv)
211
+ matched = false
212
+ ea[1..-1].each do |a|
213
+ info = Synaptic4r::Request.rest_arg(a)
214
+ flag = info[:cli][1]
215
+ next unless flag
216
+ if /^#{flag}/.match(pv)
217
+ input[a] = pv.split(/\s/).last
218
+ matched = true
219
+ length += 2
220
+ break
221
+ end
222
+ end
223
+ unless matched
224
+ puts "Error: expecting args '#{format_required_args(eargs)}'"
225
+ exit
226
+ end
227
+ else
228
+ length += 1
229
+ assign_input[ea.first,pv]
230
+ end
231
+ else
232
+ length += 1
233
+ assign_input[ea,pv]
234
+ end
235
+ end
236
+ ARGV.slice!(0, length - nvals[:dlen])
237
+ end
238
+
239
+ ####---------------------------------------------------------------------------------------------------------
240
+ def arg_name(arg_info, long=true)
241
+ cli = arg_info[:cli]
242
+ if cli.kind_of?(Array) and long
243
+ cli.length > 1 ? "#{cli[1]} #{cli[0]}" : cli.first
244
+ else; [cli].flatten.first; end
245
+ end
246
+
247
+ ####---------------------------------------------------------------------------------------------------------
248
+ def build_banner(opts, cmd)
249
+ exp_args = Synaptic4r::Request.required_rest_args(cmd)
250
+ opts.banner = Synaptic4r::Request.banner(cmd) || \
251
+ "\nUsage: synrest #{cmd.to_s.gsub(/_/,'-')} #{format_required_args(exp_args)} [options]"
252
+
253
+ end
254
+
255
+ ####---------------------------------------------------------------------------------------------------------
256
+ def process_input(opts, meths, input, cmd)
257
+ build_banner(opts, cmd)
258
+ set_args(opts, meths, input, cmd)
259
+ set_opts(opts, input, Synaptic4r::Request.optional_rest_args(cmd))
260
+ diagnostic_args(opts, input, cmd)
261
+ end
262
+
263
+
264
+ ####---------------------------------------------------------------------------------------------------------
265
+ def cmd_help(meths)
266
+ puts "\nUsage: synrest command args [options]"
267
+ puts "\nCommands"
268
+ meths.sort_by{|m| m.to_s}.each do |m|
269
+ next if m.eql?(:get_started)
270
+ meth_str = " %-30s" % m.to_s.gsub(/_/,'-')
271
+ puts "#{meth_str} #{Synaptic4r::Request.desc(m)}"
272
+ end
273
+ puts "\nCommand args and options\n synrest command -h"
274
+ puts "\nGet Started\n synrest get-started"
275
+ puts "\nCommand examples\n synrest command examples\n\n"
276
+ end
277
+
278
+ ####---------------------------------------------------------------------------------------------------------
279
+ meths = Synaptic4r::Request.rest_methods << :get_started
280
+ input = {}
281
+ cmd = extract_cmd(meths)
282
+
283
+ ####---------------------------------------------------------------------------------------------------------
284
+ if cmd.eql?(:get_started)
285
+ get_started
286
+ exit
287
+ elsif cmd
288
+ OptionParser.new do |opts|
289
+ process_input(opts, meths, input, cmd)
290
+ begin
291
+ credentials_configured?
292
+ opts.parse!(ARGV)
293
+ rescue OptionParser::MissingArgument, OptionParser::InvalidOption => err
294
+ puts err.to_s
295
+ exit
296
+ end
297
+ end
298
+ else
299
+ puts "\nsynrest provides a command line interface that maps directly onto the"
300
+ puts "synaptic storage rest API"
301
+ cmd_help(meths)
302
+ exit
303
+ end
304
+
305
+ ####---------------------------------------------------------------------------------------------------------
306
+ if input[:log]
307
+ log = Logger.new(input[:log_file] || 'synaptic4r.log')
308
+ request = run(cmd, input.merge(:dump => true))
309
+ end
310
+
311
+ ####---------------------------------------------------------------------------------------------------------
312
+ result = run(cmd, input)
313
+ puts result[:out] if result[:out]
314
+
315
+ ####---------------------------------------------------------------------------------------------------------
316
+ log.send(result[:logger], "\n#{request[:out]}#{result[:out]}") if input[:log]