nightcrawler_swift 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ce783e76729a865b6b3cd1fffbed84cc287234e9
4
- data.tar.gz: 922f51e1130d4bb27b84bde8de018793c5b5a1c4
3
+ metadata.gz: 6210245e5388c7b1c73fa1c6ff58b2f7a2770320
4
+ data.tar.gz: 6071b7124b88f4293ea186b2755c99a7e6f3b407
5
5
  SHA512:
6
- metadata.gz: ba0dc5e45b62d8011f321aba5c0e28487d5b496cde054a2197db3db5baeb2c9936a542ef5ef02ad9b3d324261b8677b6520140df048045ed4f579fd5bdb8db8e
7
- data.tar.gz: a55710e1eddf95712cb5c3821b1853854b815ecf066ee6bf22c7b259e66f1dd7ad65f1f10405e4b8fe88b0b7c3482dbea3e05faaf9a1343fc1c7425af4152da1
6
+ metadata.gz: 65753c810f8691b5e06afe0db034d692ac9187d7d73e5b3be899a141fd1ffe3eb86114ebb2bcd4c6ebdffadc8760905a9a04d6da93a677f6c3db7a116824ee48
7
+ data.tar.gz: bd9c1a5bbc7dffd4e24c0d8efab7e50f0e8917af973b4b9798e2d9df14b9f61793d1414d196df03b292b6758e431a50c6b3913d22c5fbb198617d2492c587674
data/Changelog.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0
4
+
5
+ - Upload command allows a custom max-age (issue #23)
6
+ - List command allows the following parameters: ```limit```, ```marker```, ```end_marker```, ```prefix```, ```format```, ```delimiter``` and ```path``` (issue #22)
7
+ - Download command uses the internal_url by default (issue #25)
8
+ - CLI now supports a ```--max-age``` to override the default max_age
9
+ - Included ```Expires``` header to upload command based on max_age configuration (issue #9)
10
+ - The _password_ option can be defined by the env variable ```NSWIFT_PASSWORD``` (issue #21)
11
+ - Support for SSL Client Certificates through the options: ```ssl_client_cert```, ```ssl_client_key``` and ```ssl_ca_file```
12
+ - Configurable ```internal_url```
13
+
3
14
  ## 0.5.0
4
15
 
5
16
  - CLI now supports ```-b/--bucket``` to override the default bucket/container (issue #10)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nightcrawler_swift (0.5.0)
4
+ nightcrawler_swift (0.6.0)
5
5
  multi_mime (>= 1.0.1)
6
6
  rest-client
7
7
 
data/README.md CHANGED
@@ -41,16 +41,39 @@ config.nightcrawler_swift.password = "my_password1"
41
41
  config.nightcrawler_swift.auth_url = "https://auth.url.com:123/v2.0/tokens"
42
42
  ```
43
43
 
44
+ The __password__ option can be left blank and be defined by the env variable __NSWIFT_PASSWORD__. The env variable will take precedence if the option was set.
45
+
44
46
  __Optional configurations:__
45
47
 
46
48
  ```ruby
47
49
  config.nightcrawler_swift.max_age = 3600 # default: nil
48
- config.nightcrawler_swift.verify_ssl = true # default: false
49
50
  config.nightcrawler_swift.timeout = 10 # in seconds, default: nil
50
- config.nightcrawler_swift.admin_url = "https://api.host.com/v1/AUTH_1234" # default: uses the admin_url returned by authentication
51
- config.nightcrawler_swift.public_url = "http://asset.host.com/v1/AUTH_1234" # default: uses the public_url returned by authentication
52
- config.nightcrawler_swift.retries = 3 # default: 5, to disable set it to false
53
- config.nightcrawler_swift.max_retry_time = 64 # in seconds, default: 30
51
+
52
+ # default: uses the admin_url returned by authentication
53
+ config.nightcrawler_swift.admin_url = "https://api.host.com/v1/AUTH_1234"
54
+
55
+ # default: uses the public_url returned by authentication
56
+ config.nightcrawler_swift.public_url = "http://asset.host.com/v1/AUTH_1234"
57
+
58
+ # default: 5, to disable set it to false
59
+ config.nightcrawler_swift.retries = 3
60
+
61
+ # in seconds, default: 30
62
+ config.nightcrawler_swift.max_retry_time = 64
63
+
64
+ # default: false. You could use OpenSSL::SSL::VERIFY_PEER
65
+ config.nightcrawler_swift.verify_ssl = true
66
+
67
+ # default: nil
68
+ config.nightcrawler_swift.ssl_client_cert =
69
+ OpenSSL::X509::Certificate.new(File.read("cert.pem"))
70
+
71
+ # default: nil
72
+ config.nightcrawler_swift.ssl_client_key =
73
+ OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any")
74
+
75
+ # default: nil
76
+ config.nightcrawler_swift.ssl_ca_file = "ca_certificate.pem"
54
77
  ```
55
78
 
56
79
  By default it will use ```Rails.logger``` as logger, to change that use a different logger in configurations, like:
@@ -95,16 +118,40 @@ NightcrawlerSwift.configure({
95
118
  })
96
119
  ```
97
120
 
121
+ The __password__ option can be left blank and be defined by the env variable __NSWIFT_PASSWORD__. The env variable will take precedence if the option was set.
122
+
123
+
98
124
  __Optional configurations:__
99
125
 
100
126
  ```ruby
101
127
  max_age: 3600,
102
- verify_ssl: true,
103
128
  timeout: 10, # in seconds
104
- admin_url: "https://api.host.com/v1/AUTH_1234", # default: uses the admin_url returned by authentication
105
- public_url: "http://asset.host.com/v1/AUTH_1234", # default: uses the public_url returned by authentication
106
- retries: 3, # default: 5, to disable set it to false
107
- max_retry_time: 64 # in seconds, default: 30
129
+
130
+ # default: uses the admin_url returned by authentication
131
+ admin_url: "https://api.host.com/v1/AUTH_1234",
132
+
133
+ # default: uses the public_url returned by authentication
134
+ public_url: "http://asset.host.com/v1/AUTH_1234",
135
+
136
+ # default: 5, to disable set it to false
137
+ retries: 3,
138
+
139
+ # in seconds, default: 30
140
+ max_retry_time: 64
141
+
142
+ # default: false. You could use OpenSSL::SSL::VERIFY_PEER
143
+ verify_ssl: true,
144
+
145
+ # default: nil
146
+ ssl_client_cert:
147
+ OpenSSL::X509::Certificate.new(File.read("cert.pem")),
148
+
149
+ # default: nil
150
+ ssl_client_key:
151
+ OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any"),
152
+
153
+ # default: nil
154
+ ssl_ca_file: "ca_certificate.pem"
108
155
  ```
109
156
 
110
157
  By default it will use ```Logger.new(STDOUT)``` as logger, to change that use:
@@ -149,6 +196,13 @@ $ nswift list
149
196
  ```sh
150
197
  $ nswift upload <real_path> <swift_path> # nswift upload robots.txt assets/robots.txt
151
198
  ```
199
+
200
+ Upload also supports a custom max-age, to override the value defined in ".nswiftrc", example:
201
+
202
+ ```sh
203
+ $ nswift upload <real_path> <swift_path> --max-age VALUE # nswift upload readme assets/readme.md --max-age 300
204
+ ```
205
+
152
206
  ```sh
153
207
  $ nswift download <swift_path> # nswift download assets/robots.txt > my-robots.txt
154
208
  ```
@@ -183,7 +237,15 @@ upload.execute "my_file_path.txt", File.open("../my_file_fullpath.txt", "r")
183
237
  # true / false
184
238
  ```
185
239
 
186
- _This upload command was not designed to send very large files_
240
+ _This upload command was not designed to send very large files_.
241
+
242
+ It will accept a custom max-age, overriding the configured value through ```NightcrawlerSwift.configure```, example:
243
+
244
+ ```ruby
245
+ upload = NightcrawlerSwift::Upload.new
246
+ upload.execute "readme", File.open("readme.md", "r"), max_age: 300
247
+ # true / false
248
+ ```
187
249
 
188
250
  ### Download
189
251
 
@@ -203,6 +265,16 @@ list.execute
203
265
  # [{"hash": "...", "name": "my_file_path.txt"}, {}, {}, ...]
204
266
  ```
205
267
 
268
+ This command supports the following parameters: __limit, marker, end_marker, prefix, format, delimiter, path__
269
+
270
+ Example:
271
+
272
+ ```ruby
273
+ list = NightcrawlerSwift::List.new
274
+ list.execute prefix: '/some/path'
275
+ # [{"hash": "...", "name": "/some/path/with/my_file_path.txt"}, {}, {}, ...]
276
+ ```
277
+
206
278
  ### Delete
207
279
 
208
280
  ```ruby
@@ -1,3 +1,4 @@
1
+ require "cgi"
1
2
  require "date"
2
3
  require "logger"
3
4
  require "digest"
@@ -6,6 +7,8 @@ require "multi_mime"
6
7
  require "rest_client"
7
8
  require "nightcrawler_swift/version"
8
9
  require "nightcrawler_swift/exceptions"
10
+ require "nightcrawler_swift/ext/hash"
11
+ require "nightcrawler_swift/options"
9
12
  require "nightcrawler_swift/gateway"
10
13
  require "nightcrawler_swift/connection"
11
14
  require "nightcrawler_swift/command"
@@ -34,20 +37,19 @@ module NightcrawlerSwift
34
37
  # - auth_url
35
38
  #
36
39
  # - max_age (optional, default: nil)
37
- # - verify_ssl (optional, default: false)
38
40
  # - timeout (in seconds. Optional, default: nil)
39
41
  #
40
42
  # - retries (default: 3)
41
43
  # - max_retry_time (in seconds, default: 30)
42
44
  #
45
+ # - verify_ssl (optional, default: false)
46
+ # - ssl_client_cert (optional, default: nil)
47
+ # - ssl_client_key (optional, default: nil)
48
+ # - ssl_ca_file (optional, default: nil)
49
+ #
43
50
  def configure opts = {}
44
- defaults = {verify_ssl: false, retries: 5, max_retry_time: 30}
45
- @options = OpenStruct.new(defaults.merge(opts))
46
-
47
- if @options.max_age and not @options.max_age.is_a?(Numeric)
48
- raise Exceptions::ConfigurationError.new "max_age should be an Integer"
49
- end
50
-
51
+ opts.symbolize_keys!
52
+ @options = Options.new opts
51
53
  @connection = Connection.new
52
54
  end
53
55
 
@@ -34,6 +34,7 @@ module NightcrawlerSwift::CLI
34
34
  def configure_options
35
35
  @parser.separator "options:"
36
36
  configure_option_bucket
37
+ configure_option_max_age
37
38
  configure_option_config
38
39
  configure_option_help
39
40
  configure_option_version
@@ -43,8 +44,17 @@ module NightcrawlerSwift::CLI
43
44
  desc = "Alternative bucket/container name, overrides the '#{NightcrawlerSwift::CLI::CONFIG_FILE}' configuration"
44
45
  @parser.on("-b", "--bucket=NAME", String, desc) do |name|
45
46
  bucket = name.strip
46
- @runner.options.bucket = bucket
47
- @runner.log "Using bucket: #{@runner.options.bucket}"
47
+ @runner.options.config_hash[:bucket] = bucket
48
+ @runner.log "Using bucket: #{bucket}"
49
+ end
50
+ end
51
+
52
+ def configure_option_max_age
53
+ desc = "Custom max_age value, it overrides the value configured at '#{NightcrawlerSwift::CLI::CONFIG_FILE}'"
54
+ @parser.on("--max-age=VALUE", String, desc) do |value|
55
+ max_age = value.strip.to_i
56
+ @runner.options.config_hash[:max_age] = max_age
57
+ @runner.log "Using max_age: #{max_age}"
48
58
  end
49
59
  end
50
60
 
@@ -34,7 +34,7 @@ module NightcrawlerSwift::CLI
34
34
  @options.default_config_file = true
35
35
  @options.config_file = File.expand_path(File.join(user_home_dir, CONFIG_FILE))
36
36
  @options.cache_file = File.expand_path(File.join(user_home_dir, CACHE_FILE))
37
- @options.bucket = nil
37
+ @options.config_hash = {}
38
38
  end
39
39
 
40
40
  def validate_command_and_options
@@ -55,12 +55,11 @@ module NightcrawlerSwift::CLI
55
55
  end
56
56
 
57
57
  def config_hash
58
- @config_hash ||= JSON.parse(File.read(options.config_file))
58
+ @config_hash ||= JSON.parse(File.read(options.config_file), symbolize_names: true) rescue {}
59
59
  end
60
60
 
61
61
  def execute_command
62
- NightcrawlerSwift.configure config_hash
63
- NightcrawlerSwift.options.bucket = @options.bucket if @options.bucket
62
+ NightcrawlerSwift.configure config_hash.merge(@options.config_hash)
64
63
 
65
64
  connect_and_execute do
66
65
  command_method = "command_#{command_name_normalized}"
@@ -19,26 +19,30 @@ module NightcrawlerSwift
19
19
 
20
20
  protected
21
21
 
22
- def get url, params = {}
23
- prepare_params params
24
- Gateway.new(url).request {|r| r.get params[:headers]}
22
+ def get url, args = {}
23
+ prepare_args args
24
+ Gateway.new(url).request {|r| r.get headers_and_params(args)}
25
25
  end
26
26
 
27
- def put url, params = {}
28
- prepare_params params
29
- Gateway.new(url).request {|r| r.put params[:body], params[:headers]}
27
+ def put url, args = {}
28
+ prepare_args args
29
+ Gateway.new(url).request {|r| r.put args[:body], headers_and_params(args)}
30
30
  end
31
31
 
32
- def delete url, params
33
- prepare_params params
34
- Gateway.new(url).request {|r| r.delete params[:headers]}
32
+ def delete url, args = {}
33
+ prepare_args args
34
+ Gateway.new(url).request {|r| r.delete headers_and_params(args)}
35
35
  end
36
36
 
37
37
  private
38
+ def prepare_args args
39
+ args[:headers] ||= {}
40
+ args[:headers]["X-Storage-Token"] = connection.token_id
41
+ args[:params] ||= {}
42
+ end
38
43
 
39
- def prepare_params params
40
- params[:headers] ||= {}
41
- params[:headers]["X-Storage-Token"] = connection.token_id
44
+ def headers_and_params args
45
+ args[:headers].merge(params: args[:params])
42
46
  end
43
47
  end
44
48
  end
@@ -6,7 +6,7 @@ module NightcrawlerSwift
6
6
  raise Exceptions::ValidationError.new "Delete command requires a path parameter"
7
7
  end
8
8
 
9
- response = delete "#{connection.upload_url}/#{path}", headers: {accept: :json }
9
+ response = delete "#{connection.upload_url}/#{path}", headers: { accept: :json }
10
10
  [200, 201].include?(response.code)
11
11
  end
12
12
 
@@ -6,7 +6,7 @@ module NightcrawlerSwift
6
6
  raise Exceptions::ValidationError.new "Download command requires a path parameter"
7
7
  end
8
8
 
9
- response = get "#{connection.public_url}/#{options.bucket}/#{path}"
9
+ response = get "#{connection.internal_url}/#{options.bucket}/#{path}"
10
10
  response.body
11
11
  end
12
12
 
@@ -1,8 +1,16 @@
1
1
  module NightcrawlerSwift
2
2
  class List < Command
3
3
 
4
- def execute
5
- response = get connection.upload_url, headers: {accept: :json}
4
+ def execute args = {}
5
+ headers = { accept: :json }
6
+
7
+ # http://docs.openstack.org/api/openstack-object-storage/1.0/content/GET_showContainerDetails__v1__account___container__storage_container_services.html#GET_showContainerDetails__v1__account___container__storage_container_services-Request
8
+ params = {}
9
+ [:limit, :marker, :end_marker, :prefix, :format, :delimiter, :path].each do |accepted_parameter|
10
+ params[accepted_parameter] = args[accepted_parameter] if args[accepted_parameter]
11
+ end
12
+
13
+ response = get connection.upload_url, headers: headers, params: params
6
14
  JSON.parse(response.body)
7
15
  end
8
16
 
@@ -1,11 +1,14 @@
1
1
  module NightcrawlerSwift
2
2
  class Upload < Command
3
3
 
4
- def execute path, file
5
- content = file.read
6
- headers = {etag: etag(content), content_type: content_type(file)}
7
- headers.merge!(cache_control: "public, max-age=#{options.max_age}") if options.max_age
8
- response = put "#{connection.upload_url}/#{path}", body: content, headers: headers
4
+ def execute path, file, opts = {}
5
+ body = file.read
6
+ headers = {etag: etag(body), content_type: content_type(file)}
7
+
8
+ max_age = opts[:max_age] || options.max_age
9
+ headers.merge!(cache_control: "public, max-age=#{max_age}", expires: expires(max_age)) if max_age
10
+
11
+ response = put "#{connection.upload_url}/#{path}", body: body, headers: headers
9
12
  [200, 201].include?(response.code)
10
13
  end
11
14
 
@@ -18,5 +21,9 @@ module NightcrawlerSwift
18
21
  Digest::MD5.hexdigest(content)
19
22
  end
20
23
 
24
+ def expires max_age
25
+ CGI.rfc1123_date(Time.now + max_age)
26
+ end
27
+
21
28
  end
22
29
  end
@@ -1,7 +1,7 @@
1
1
  module NightcrawlerSwift
2
2
  class Connection
3
3
  attr_accessor :auth_response
4
- attr_reader :token_id, :expires_at, :catalog, :admin_url, :upload_url, :public_url
4
+ attr_reader :token_id, :expires_at, :catalog, :admin_url, :upload_url, :public_url, :internal_url
5
5
 
6
6
  def connect!
7
7
  authenticate!
@@ -65,6 +65,7 @@ module NightcrawlerSwift
65
65
  def configure_urls
66
66
  @admin_url = opts.admin_url || @endpoints["adminURL"]
67
67
  @public_url = opts.public_url || @endpoints["publicURL"]
68
+ @internal_url = opts.internal_url || @endpoints["internalURL"]
68
69
  @upload_url = "#{@admin_url}/#{opts.bucket}"
69
70
  end
70
71
  end
@@ -0,0 +1,38 @@
1
+ module NightcrawlerSwift
2
+ module Hash
3
+
4
+ unless {}.respond_to?(:symbolize_keys)
5
+ def symbolize_keys
6
+ {}.tap do |result|
7
+ keys.each {|k| result[k.to_sym] = self[k]}
8
+ end
9
+ end
10
+
11
+ def symbolize_keys!
12
+ self.tap do
13
+ keys.each {|k| self[k.to_sym] = delete(k)}
14
+ end
15
+ end
16
+ end
17
+
18
+ unless {}.respond_to?(:compact)
19
+ def compact
20
+ {}.tap do |result|
21
+ keys.each {|k| result[k] = self[k] unless self[k].nil?}
22
+ end
23
+ end
24
+
25
+ def compact!
26
+ self.tap do
27
+ keys.each do |k|
28
+ value = delete(k)
29
+ self[k] = value unless value.nil?
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+
38
+ Hash.send :include, NightcrawlerSwift::Hash
@@ -18,8 +18,7 @@ module NightcrawlerSwift
18
18
 
19
19
  @resource = RestClient::Resource.new(
20
20
  @url,
21
- verify_ssl: NightcrawlerSwift.options.verify_ssl,
22
- timeout: NightcrawlerSwift.options.timeout
21
+ {timeout: options.timeout}.merge(ssl_options)
23
22
  )
24
23
  end
25
24
 
@@ -51,6 +50,22 @@ module NightcrawlerSwift
51
50
  NightcrawlerSwift.logger.debug message
52
51
  end
53
52
 
53
+ def options
54
+ NightcrawlerSwift.options
55
+ end
56
+
57
+ def ssl_options
58
+ [
59
+ :verify_ssl,
60
+ :ssl_client_cert,
61
+ :ssl_client_key,
62
+ :ssl_ca_file
63
+
64
+ ].inject({}) {|hash, key|
65
+ hash.tap {hash[key] = options[key]}
66
+ }.compact
67
+ end
68
+
54
69
  def recoverable? e
55
70
  @retries and
56
71
  !RETRY_BLACKLIST.include?(e.class) and
@@ -0,0 +1,27 @@
1
+ module NightcrawlerSwift
2
+ class Options < OpenStruct
3
+
4
+ def initialize params = {}
5
+ params[:password] = ENV["NSWIFT_PASSWORD"] || params[:password]
6
+ super defaults.merge(params)
7
+ validate_max_age!
8
+ end
9
+
10
+ protected
11
+ def defaults
12
+ {
13
+ retries: 5,
14
+ max_retry_time: 30,
15
+ verify_ssl: false
16
+ }
17
+ end
18
+
19
+ private
20
+ def validate_max_age!
21
+ if self.max_age and not self.max_age.is_a?(Numeric)
22
+ raise Exceptions::ConfigurationError.new "max_age should be an Integer"
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module NightcrawlerSwift
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -4,7 +4,7 @@ require "nightcrawler_swift/cli"
4
4
  describe NightcrawlerSwift::CLI::OptParser do
5
5
 
6
6
  let :runner do
7
- instance_double "Runner", options: OpenStruct.new(bucket: nil, config_file: nil, default_config_file: true)
7
+ instance_double "Runner", options: OpenStruct.new(config_hash: {}, config_file: nil, default_config_file: true)
8
8
  end
9
9
 
10
10
  let :config_dir do
@@ -108,7 +108,26 @@ describe NightcrawlerSwift::CLI::OptParser do
108
108
  allow(runner).to receive(:argv).and_return([command])
109
109
  allow(runner).to receive(:log)
110
110
  subject.parse!
111
- expect(runner.options.bucket).to eql bucket_name
111
+ expect(runner.options.config_hash).to include(bucket: bucket_name)
112
+ end
113
+ end
114
+ end
115
+
116
+ ["--max-age=VALUE"].each do |switch|
117
+ context switch do
118
+ let :max_age do
119
+ 300
120
+ end
121
+
122
+ let :command do
123
+ switch.gsub(/VALUE/, max_age.to_s)
124
+ end
125
+
126
+ it "configures the max-age" do
127
+ allow(runner).to receive(:argv).and_return([command])
128
+ allow(runner).to receive(:log)
129
+ subject.parse!
130
+ expect(runner.options.config_hash).to include(max_age: max_age)
112
131
  end
113
132
  end
114
133
  end
@@ -101,7 +101,7 @@ describe NightcrawlerSwift::CLI::Runner do
101
101
  end
102
102
 
103
103
  it "configures NightcrawlerSwift" do
104
- expect(NightcrawlerSwift).to receive(:configure).with opts
104
+ expect(NightcrawlerSwift).to receive(:configure).with opts.symbolize_keys
105
105
  subject.run
106
106
  end
107
107
 
@@ -121,16 +121,31 @@ describe NightcrawlerSwift::CLI::Runner do
121
121
 
122
122
  before do
123
123
  subject.send :configure_default_options
124
- expect(subject.options.bucket).to be_nil
124
+ expect(subject.options.config_hash).to eql({})
125
125
  end
126
126
 
127
127
  it "overrides the default name" do
128
- allow(subject).to receive(:parse_parameters) { subject.options.bucket = bucket_name }
128
+ allow(subject).to receive(:parse_parameters) { subject.options.config_hash[:bucket] = bucket_name }
129
129
  subject.run
130
130
  expect(NightcrawlerSwift.options.bucket).to eql bucket_name
131
131
  end
132
132
  end
133
133
 
134
+ context "with a custom max-age" do
135
+ let(:max_age) { 300 }
136
+
137
+ before do
138
+ subject.send :configure_default_options
139
+ expect(subject.options.config_hash).to eql({})
140
+ end
141
+
142
+ it "overrides the default name" do
143
+ allow(subject).to receive(:parse_parameters) { subject.options.config_hash[:max_age] = max_age }
144
+ subject.run
145
+ expect(NightcrawlerSwift.options.max_age).to eql max_age
146
+ end
147
+ end
148
+
134
149
  it "writes the auth_response into cache file" do
135
150
  expect(File.exist?(cache_file)).to eql false
136
151
  expect(connection).to receive(:auth_response).and_return(OpenStruct.new(connection_success_json))
@@ -60,14 +60,24 @@ describe NightcrawlerSwift::Command do
60
60
 
61
61
  describe "#get" do
62
62
  let :execute_http do
63
- subject.send :get, url, headers: {content_type: :json}
63
+ subject.send :get, url, body: 'ignore_me', headers: { content_type: :json }, params: { b: 2 }
64
64
  end
65
65
 
66
66
  it_behaves_like "command with configured gateway"
67
67
 
68
+ it "ignores body" do
69
+ execute_http
70
+ expect(restclient).to have_received(:get).with(kind_of(Hash))
71
+ end
72
+
68
73
  it "sends headers with token" do
69
74
  execute_http
70
- expect(restclient).to have_received(:get).with(content_type: :json, "X-Storage-Token" => token)
75
+ expect(restclient).to have_received(:get).with(hash_including({ content_type: :json, "X-Storage-Token" => token }))
76
+ end
77
+
78
+ it "sends params" do
79
+ execute_http
80
+ expect(restclient).to have_received(:get).with(hash_including(params: { b: 2 }))
71
81
  end
72
82
 
73
83
  it "returns RestClient response" do
@@ -77,14 +87,24 @@ describe NightcrawlerSwift::Command do
77
87
 
78
88
  describe "#delete" do
79
89
  let :execute_http do
80
- subject.send :delete, url, headers: {content_type: :json}
90
+ subject.send :delete, url, body: 'ignore_me', headers: { content_type: :json }, params: { b: 2 }
81
91
  end
82
92
 
83
93
  it_behaves_like "command with configured gateway"
84
94
 
95
+ it "ignores body" do
96
+ execute_http
97
+ expect(restclient).to have_received(:delete).with(kind_of(Hash))
98
+ end
99
+
85
100
  it "sends headers with token" do
86
101
  execute_http
87
- expect(restclient).to have_received(:delete).with(content_type: :json, "X-Storage-Token" => token)
102
+ expect(restclient).to have_received(:delete).with(hash_including({ content_type: :json, "X-Storage-Token" => token }))
103
+ end
104
+
105
+ it "sends params" do
106
+ execute_http
107
+ expect(restclient).to have_received(:delete).with(hash_including(params: { b: 2 }))
88
108
  end
89
109
 
90
110
  it "returns RestClient response" do
@@ -94,7 +114,7 @@ describe NightcrawlerSwift::Command do
94
114
 
95
115
  describe "#put" do
96
116
  let :execute_http do
97
- subject.send(:put, url, body: 'content', headers: {a: 1})
117
+ subject.send :put, url, body: 'content', headers: { a: 1 }, params: { b: 2 }
98
118
  end
99
119
 
100
120
  it_behaves_like "command with configured gateway"
@@ -105,12 +125,17 @@ describe NightcrawlerSwift::Command do
105
125
 
106
126
  it "sends body" do
107
127
  execute_http
108
- expect(restclient).to have_received(:put).with('content', anything)
128
+ expect(restclient).to have_received(:put).with('content', kind_of(Hash))
109
129
  end
110
130
 
111
131
  it "sends headers with token" do
112
132
  execute_http
113
- expect(restclient).to have_received(:put).with(anything, {a: 1, "X-Storage-Token" => token})
133
+ expect(restclient).to have_received(:put).with(anything, hash_including({ a: 1, "X-Storage-Token" => token }))
134
+ end
135
+
136
+ it "sends params" do
137
+ execute_http
138
+ expect(restclient).to have_received(:put).with(anything, hash_including(params: { b: 2 }))
114
139
  end
115
140
  end
116
141
 
@@ -5,7 +5,7 @@ describe NightcrawlerSwift::Download do
5
5
  let(:connection) { NightcrawlerSwift::Connection.new }
6
6
  let(:token) { "token" }
7
7
  let(:expires_at) { (DateTime.now + 60).to_time }
8
- let(:public_url) { "server-url" }
8
+ let(:internal_url) { "server-url" }
9
9
  let(:bucket) { "rogue" }
10
10
 
11
11
  subject do
@@ -16,7 +16,7 @@ describe NightcrawlerSwift::Download do
16
16
  allow(NightcrawlerSwift).to receive(:connection).and_return(connection)
17
17
  allow(connection).to receive(:token_id).and_return(token)
18
18
  allow(connection).to receive(:expires_at).and_return(expires_at)
19
- allow(connection).to receive(:public_url).and_return(public_url)
19
+ allow(connection).to receive(:internal_url).and_return(internal_url)
20
20
  NightcrawlerSwift.configure bucket: bucket
21
21
  end
22
22
 
@@ -34,7 +34,7 @@ describe NightcrawlerSwift::Download do
34
34
  allow(subject).to receive(:get).and_return(response)
35
35
  end
36
36
 
37
- it "gets using public url" do
37
+ it "gets using internal url" do
38
38
  execute
39
39
  expect(subject).to have_received(:get).with("server-url/#{bucket}/file_path")
40
40
  end
@@ -31,9 +31,19 @@ describe NightcrawlerSwift::List do
31
31
  allow(subject).to receive(:get).and_return(response)
32
32
  end
33
33
 
34
- it "gets upload url" do
34
+ it "gets upload url without parameters" do
35
35
  subject.execute
36
- expect(subject).to have_received(:get).with(connection.upload_url, headers: {accept: :json})
36
+ expect(subject).to have_received(:get).with(connection.upload_url, headers: { accept: :json }, params: {})
37
+ end
38
+
39
+ it "gets upload url with accepted parameters" do
40
+ subject.execute prefix: 'some/prefix', limit: 2
41
+ expect(subject).to have_received(:get).with(connection.upload_url, headers: { accept: :json }, params: { prefix: 'some/prefix', limit: 2 })
42
+ end
43
+
44
+ it "gets upload url without unknown parameters" do
45
+ subject.execute prefix: 'some/prefix', a: 'b'
46
+ expect(subject).to have_received(:get).with(connection.upload_url, headers: { accept: :json }, params: { prefix: 'some/prefix' })
37
47
  end
38
48
 
39
49
  it "returns the parsed json" do
@@ -68,10 +68,47 @@ describe NightcrawlerSwift::Upload do
68
68
  expect(subject).to have_received(:put).with("server-url/file_name", anything)
69
69
  end
70
70
 
71
- it "sends max_age into headers" do
72
- NightcrawlerSwift.configure max_age: max_age
73
- execute
74
- expect(subject).to have_received(:put).with(anything, hash_including(headers: { content_type: "text/css", etag: etag, cache_control: "public, max-age=#{max_age}" }))
71
+ context "max_age" do
72
+ let :default_headers do
73
+ {content_type: "text/css", etag: etag}
74
+ end
75
+
76
+ it "sends default max_age into headers" do
77
+ NightcrawlerSwift.configure max_age: max_age
78
+ execute
79
+ expect(subject).to have_received(:put).with(
80
+ anything,
81
+ hash_including(
82
+ headers: hash_including(default_headers.merge(cache_control: "public, max-age=#{max_age}"))
83
+ )
84
+ )
85
+ end
86
+
87
+ it "allows custom max_age" do
88
+ NightcrawlerSwift.configure
89
+ subject.execute path, file, max_age: 1
90
+ expect(subject).to have_received(:put).with(
91
+ anything,
92
+ hash_including(
93
+ headers: hash_including(default_headers.merge(cache_control: "public, max-age=1"))
94
+ )
95
+ )
96
+ end
97
+
98
+ it "also sends the expires header based on max_age" do
99
+ now = Time.now
100
+ allow(Time).to receive(:now).and_return(now)
101
+ expires = CGI.rfc1123_date(Time.now + max_age)
102
+
103
+ NightcrawlerSwift.configure max_age: max_age
104
+ execute
105
+ expect(subject).to have_received(:put).with(
106
+ anything,
107
+ hash_including(
108
+ headers: default_headers.merge(cache_control: "public, max-age=#{max_age}", expires: expires)
109
+ )
110
+ )
111
+ end
75
112
  end
76
113
 
77
114
  context "when response code is 200" do
@@ -97,6 +97,11 @@ describe NightcrawlerSwift::Connection do
97
97
  expect(subject.public_url).to eql(auth_success_json["access"]["serviceCatalog"].first["endpoints"].first["publicURL"])
98
98
  end
99
99
 
100
+ it "stores the internal_url" do
101
+ subject.connect!
102
+ expect(subject.internal_url).to eql(auth_success_json["access"]["serviceCatalog"].first["endpoints"].first["internalURL"])
103
+ end
104
+
100
105
  it "returns self" do
101
106
  expect(subject.connect!).to eql(subject)
102
107
  end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe NightcrawlerSwift::Hash do
4
+
5
+ subject do
6
+ {"key1" => "value1", "key2" => "value2"}
7
+ end
8
+
9
+ describe "#symbolize_keys" do
10
+ it "creates a new hash with the symbolized keys" do
11
+ result = subject.symbolize_keys
12
+ expect(result).to include(key1: "value1", key2: "value2")
13
+ expect(subject).to include("key1" => "value1", "key2" => "value2")
14
+ end
15
+ end
16
+
17
+ describe "#symbolize_keys!" do
18
+ it "destructively convert all keys to symbols" do
19
+ result = subject.symbolize_keys!
20
+ expect(result).to include(key1: "value1", key2: "value2")
21
+ expect(subject).to include(key1: "value1", key2: "value2")
22
+ expect(result).to eql subject
23
+ end
24
+ end
25
+
26
+ describe "#compact" do
27
+ subject do
28
+ {key1: nil, key2: "value2", key3: nil}
29
+ end
30
+
31
+ it "creates a new hash without the nil items" do
32
+ result = subject.compact
33
+ expect(result).to_not include(:key1, :key3)
34
+ expect(result).to include(:key2)
35
+
36
+ expect(subject).to include(:key1, :key2, :key3)
37
+ end
38
+ end
39
+
40
+ describe "#compact!" do
41
+ subject do
42
+ {key1: nil, key2: "value2", key3: nil}
43
+ end
44
+
45
+ it "destructively remove the items with the nil value" do
46
+ result = subject.compact!
47
+ expect(result).to_not include(:key1, :key3)
48
+ expect(result).to include(:key2)
49
+ expect(subject).to_not include(:key1, :key3)
50
+ expect(subject).to include(:key2)
51
+
52
+ expect(result).to eql subject
53
+ end
54
+ end
55
+
56
+ end
@@ -10,12 +10,16 @@ describe NightcrawlerSwift::Gateway do
10
10
  subject.request {|r| r.get}
11
11
  end
12
12
 
13
+ let :opts do
14
+ {}
15
+ end
16
+
13
17
  subject do
14
18
  NightcrawlerSwift::Gateway.new url
15
19
  end
16
20
 
17
21
  before do
18
- NightcrawlerSwift.configure
22
+ NightcrawlerSwift.configure opts
19
23
  end
20
24
 
21
25
  describe "initialization" do
@@ -27,6 +31,79 @@ describe NightcrawlerSwift::Gateway do
27
31
  )
28
32
  subject
29
33
  end
34
+
35
+ context "with ssl options" do
36
+ context "but only 'ssl_client_cert'" do
37
+ let :opts do
38
+ {verify_ssl: true, ssl_client_cert: "somecert.pem"}
39
+ end
40
+
41
+ it "uses the configured option" do
42
+ expect(RestClient::Resource).to receive(:new).with(
43
+ url,
44
+ timeout: NightcrawlerSwift.options.timeout,
45
+ verify_ssl: NightcrawlerSwift.options.verify_ssl,
46
+ ssl_client_cert: NightcrawlerSwift.options.ssl_client_cert
47
+ )
48
+ subject
49
+ end
50
+ end
51
+
52
+ context "but only 'ssl_client_key'" do
53
+ let :opts do
54
+ {verify_ssl: true, ssl_client_key: "clientkey"}
55
+ end
56
+
57
+ it "uses the configured option" do
58
+ expect(RestClient::Resource).to receive(:new).with(
59
+ url,
60
+ timeout: NightcrawlerSwift.options.timeout,
61
+ verify_ssl: NightcrawlerSwift.options.verify_ssl,
62
+ ssl_client_key: NightcrawlerSwift.options.ssl_client_key
63
+ )
64
+ subject
65
+ end
66
+ end
67
+
68
+ context "but only 'ssl_ca_file'" do
69
+ let :opts do
70
+ {verify_ssl: true, ssl_ca_file: "Certificate Authority File"}
71
+ end
72
+
73
+ it "uses the configured option" do
74
+ expect(RestClient::Resource).to receive(:new).with(
75
+ url,
76
+ timeout: NightcrawlerSwift.options.timeout,
77
+ verify_ssl: NightcrawlerSwift.options.verify_ssl,
78
+ ssl_ca_file: NightcrawlerSwift.options.ssl_ca_file
79
+ )
80
+ subject
81
+ end
82
+ end
83
+
84
+ context "using all options" do
85
+ let :opts do
86
+ {
87
+ verify_ssl: true,
88
+ ssl_client_cert: "somecert.pem",
89
+ ssl_client_key: "clientkey",
90
+ ssl_ca_file: "Certificate Authority File"
91
+ }
92
+ end
93
+
94
+ it "uses the configured options" do
95
+ expect(RestClient::Resource).to receive(:new).with(
96
+ url,
97
+ timeout: NightcrawlerSwift.options.timeout,
98
+ verify_ssl: NightcrawlerSwift.options.verify_ssl,
99
+ ssl_client_cert: NightcrawlerSwift.options.ssl_client_cert,
100
+ ssl_client_key: NightcrawlerSwift.options.ssl_client_key,
101
+ ssl_ca_file: NightcrawlerSwift.options.ssl_ca_file
102
+ )
103
+ subject
104
+ end
105
+ end
106
+ end
30
107
  end
31
108
 
32
109
  describe "#request" do
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe NightcrawlerSwift::Options do
4
+
5
+ subject do
6
+ NightcrawlerSwift::Options.new opts
7
+ end
8
+
9
+ let :opts do
10
+ {}
11
+ end
12
+
13
+ describe "initialization" do
14
+ context "verify_ssl" do
15
+ it "defauts to false" do
16
+ expect(subject.verify_ssl).to eql false
17
+ end
18
+ end
19
+
20
+ context "retries" do
21
+ it "defauts to 5" do
22
+ expect(subject.retries).to eql 5
23
+ end
24
+ end
25
+
26
+ context "max_retry_time" do
27
+ it "defauts to 30" do
28
+ expect(subject.max_retry_time).to eql 30
29
+ end
30
+ end
31
+
32
+ context "password" do
33
+ before do
34
+ expect(ENV).to receive(:[]).with("NSWIFT_PASSWORD").and_return("123")
35
+ end
36
+
37
+ it "can be defined by the ENV variable 'NSWIFT_PASSWORD'" do
38
+ expect(subject.password).to eql "123"
39
+ end
40
+
41
+ context "when configured" do
42
+ let :opts do
43
+ {password: "345"}
44
+ end
45
+
46
+ it "takes the ENV variable in precedence" do
47
+ expect(subject.password).to eql "123"
48
+ end
49
+ end
50
+ end
51
+
52
+ context "and max_age isn't an integer" do
53
+ let(:opts) { {max_age: "a string"} }
54
+
55
+ it "raises NightcrawlerSwift::Exceptions::ConfigurationError" do
56
+ expect { subject }.to raise_error(NightcrawlerSwift::Exceptions::ConfigurationError)
57
+ end
58
+ end
59
+
60
+ context "when configured" do
61
+ let :opts do
62
+ {
63
+ bucket: "rogue",
64
+ password: "123",
65
+ retries: 2
66
+ }
67
+ end
68
+
69
+ it "creates with the given values" do
70
+ expect(subject.bucket).to eql "rogue"
71
+ expect(subject.password).to eql "123"
72
+ expect(subject.retries).to eql 2
73
+ end
74
+ end
75
+ end
76
+
77
+ end
@@ -29,7 +29,7 @@ describe NightcrawlerSwift do
29
29
  end
30
30
 
31
31
  describe "::configure" do
32
- it "creates the options struct with the given values" do
32
+ it "creates the options with the given values" do
33
33
  subject.configure opts
34
34
  expect(subject.options).to_not be_nil
35
35
  opts.keys.each do |key|
@@ -42,32 +42,6 @@ describe NightcrawlerSwift do
42
42
  subject.configure opts
43
43
  expect(subject.connection).to_not be_nil
44
44
  end
45
-
46
- context "verify_ssl" do
47
- it "defauts to false" do
48
- expect(subject.options.verify_ssl).to eql false
49
- end
50
- end
51
-
52
- context "retries" do
53
- it "defauts to 5" do
54
- expect(subject.options.retries).to eql 5
55
- end
56
- end
57
-
58
- context "max_retry_time" do
59
- it "defauts to 30" do
60
- expect(subject.options.max_retry_time).to eql 30
61
- end
62
- end
63
-
64
- context "and max_age isn't an integer" do
65
- let(:opts) { {max_age: "a string"} }
66
-
67
- it "raises NightcrawlerSwift::Exceptions::ConfigurationError" do
68
- expect { subject.configure(opts) }.to raise_error(NightcrawlerSwift::Exceptions::ConfigurationError)
69
- end
70
- end
71
45
  end
72
46
 
73
47
  describe "::connection" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nightcrawler_swift
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tulios
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-09-11 00:00:00.000000000 Z
12
+ date: 2014-09-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -145,7 +145,9 @@ files:
145
145
  - lib/nightcrawler_swift/commands/upload.rb
146
146
  - lib/nightcrawler_swift/connection.rb
147
147
  - lib/nightcrawler_swift/exceptions.rb
148
+ - lib/nightcrawler_swift/ext/hash.rb
148
149
  - lib/nightcrawler_swift/gateway.rb
150
+ - lib/nightcrawler_swift/options.rb
149
151
  - lib/nightcrawler_swift/railtie.rb
150
152
  - lib/nightcrawler_swift/tasks/asset_sync.rake
151
153
  - lib/nightcrawler_swift/version.rb
@@ -167,7 +169,9 @@ files:
167
169
  - spec/lib/nightcrawler_swift/commands/sync_spec.rb
168
170
  - spec/lib/nightcrawler_swift/commands/upload_spec.rb
169
171
  - spec/lib/nightcrawler_swift/connection_spec.rb
172
+ - spec/lib/nightcrawler_swift/ext/hash_spec.rb
170
173
  - spec/lib/nightcrawler_swift/gateway_spec.rb
174
+ - spec/lib/nightcrawler_swift/options_spec.rb
171
175
  - spec/lib/nightcrawler_swift/tasks/asset_sync_spec.rb
172
176
  - spec/lib/nightcrawler_swift_spec.rb
173
177
  - spec/spec_helper.rb
@@ -214,7 +218,9 @@ test_files:
214
218
  - spec/lib/nightcrawler_swift/commands/sync_spec.rb
215
219
  - spec/lib/nightcrawler_swift/commands/upload_spec.rb
216
220
  - spec/lib/nightcrawler_swift/connection_spec.rb
221
+ - spec/lib/nightcrawler_swift/ext/hash_spec.rb
217
222
  - spec/lib/nightcrawler_swift/gateway_spec.rb
223
+ - spec/lib/nightcrawler_swift/options_spec.rb
218
224
  - spec/lib/nightcrawler_swift/tasks/asset_sync_spec.rb
219
225
  - spec/lib/nightcrawler_swift_spec.rb
220
226
  - spec/spec_helper.rb