nightcrawler_swift 0.11.1 → 1.0.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: a01ca41080d2e2b24b9005e7fa2e4da34c6fef4b
4
- data.tar.gz: eae62f063a96a74260358ea140eba27ac03e219c
3
+ metadata.gz: 7368872bbed33a3a4928360a3162cbec161ad31d
4
+ data.tar.gz: 7599b6e39f3e7a0c376518beed4deb89978a68f9
5
5
  SHA512:
6
- metadata.gz: 73107c34d413732b19acb85ad51e5cf1e7bf1268cf3f73206d22d09cf6c66db95a94a3c5148638f2256db7955bf89d7f348c00478a482b92d1c9104d00da6f72
7
- data.tar.gz: a056ef9ea2ce5cef78410e93a368dc6aff253152ea40fa1b5987be66b8a33dde52f040e0167f173e231bdd24c5f1d1ef80671be6a010f9d2cc0c3e5cd55dd3a0
6
+ metadata.gz: c4d15c9c9fc23c71b7dfa04cceaa00bf0152603fae8372c5527a5a0cbfce9bbf54438d4c334d39ad483e94b4d2ff724f90e663273e7ca833aef65341243bcbc0
7
+ data.tar.gz: 866b75e3f995ce7754712bb12b13967ff5009d2db7a5e657aba7b14bc6865b9b5222b212ba7b21c96331d6b0ed9663b57ba6bcdd7853ac5502470e21c2348bb8
@@ -1 +1 @@
1
- ruby-2.1.2
1
+ ruby-2.4.1
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nightcrawler_swift (0.11.1)
4
+ nightcrawler_swift (1.0.0)
5
5
  concurrent-ruby (~> 0.8.0)
6
6
  multi_mime (>= 1.1.0)
7
7
  rest-client
@@ -21,7 +21,7 @@ GEM
21
21
  debugger-linecache (1.2.0)
22
22
  diff-lcs (1.2.5)
23
23
  docile (1.1.5)
24
- domain_name (0.5.20160826)
24
+ domain_name (0.5.20170404)
25
25
  unf (>= 0.0.5, < 1.0.0)
26
26
  http-cookie (1.0.3)
27
27
  domain_name (~> 0.5)
@@ -33,7 +33,7 @@ GEM
33
33
  netrc (0.11.0)
34
34
  rake (10.3.2)
35
35
  ref (1.0.5)
36
- rest-client (2.0.0)
36
+ rest-client (2.0.2)
37
37
  http-cookie (>= 1.0.2, < 2.0)
38
38
  mime-types (>= 1.16, < 4.0)
39
39
  netrc (~> 0.8)
@@ -58,7 +58,7 @@ GEM
58
58
  timecop (0.8.0)
59
59
  unf (0.1.4)
60
60
  unf_ext
61
- unf_ext (0.0.7.2)
61
+ unf_ext (0.0.7.4)
62
62
 
63
63
  PLATFORMS
64
64
  ruby
@@ -73,4 +73,4 @@ DEPENDENCIES
73
73
  timecop
74
74
 
75
75
  BUNDLED WITH
76
- 1.13.5
76
+ 1.15.3
data/README.md CHANGED
@@ -6,6 +6,10 @@
6
6
 
7
7
  Like the X-Men nightcrawler this gem teleports your assets to a OpenStack Swift bucket/container. It was designed to sync your assets with OpenStack Swift and allow some operations with your buckets/containers.
8
8
 
9
+ ## Compatibility
10
+
11
+ nightcrawler_swift version 1.x is compatible with [Identity API v3](https://developer.openstack.org/api-ref/identity/v3/index.html). To use [API v2](https://developer.openstack.org/api-ref/identity/v2/index.html), you should install version 0.x.
12
+
9
13
  ## Installation
10
14
 
11
15
  Add this line to your application's Gemfile:
@@ -14,16 +18,28 @@ Add this line to your application's Gemfile:
14
18
  gem 'nightcrawler_swift'
15
19
  ```
16
20
 
21
+ Or, if you want to use Identity API v2:
22
+
23
+ ```ruby
24
+ gem 'nightcrawler_swift', '< 1.0'
25
+ ```
26
+
17
27
  And then execute:
18
28
 
19
29
  ```sh
20
30
  $ bundle
21
31
  ```
22
32
 
23
- Or install it yourself as:
33
+ Or install it manually:
34
+
35
+ ```sh
36
+ $ gem install nightcrawler_swift # Install latest version
37
+ ```
38
+
39
+ Or set a specific version:
24
40
 
25
41
  ```sh
26
- $ gem install nightcrawler_swift
42
+ $ gem install nightcrawler_swift -v 0.11.1
27
43
  ```
28
44
 
29
45
  ## Usage
@@ -7,7 +7,7 @@ module NightcrawlerSwift
7
7
  end
8
8
 
9
9
  response = delete "#{connection.upload_url}/#{path}", headers: { accept: :json }
10
- [200, 201].include?(response.code)
10
+ response.code >= 200 && response.code < 300
11
11
  end
12
12
 
13
13
  end
@@ -2,6 +2,10 @@ module NightcrawlerSwift
2
2
  class Upload < Command
3
3
 
4
4
  def execute path, file, opts = {}
5
+ if path.nil? or path.empty?
6
+ raise Exceptions::ValidationError.new "Upload command requires a path parameter"
7
+ end
8
+
5
9
  body = file.read
6
10
  headers = {etag: etag(body), content_type: content_type(file)}
7
11
 
@@ -18,7 +22,7 @@ module NightcrawlerSwift
18
22
  headers.merge!(custom_headers) if custom_headers
19
23
 
20
24
  response = put "#{connection.upload_url}/#{path}", body: body, headers: headers
21
- [200, 201].include?(response.code)
25
+ response.code >= 200 && response.code < 300
22
26
  end
23
27
 
24
28
  private
@@ -50,7 +50,7 @@ module NightcrawlerSwift
50
50
  headers = {content_type: :json, accept: :json}
51
51
  response = Gateway.new(url).request {|r| r.post(auth_options.to_json, headers)}
52
52
 
53
- @auth_response = OpenStruct.new(JSON.parse(response.body))
53
+ @auth_response = OpenStruct.new(headers: response.headers, body: JSON.parse(response.body))
54
54
  rescue StandardError => e
55
55
  raise Exceptions::ConnectionError.new(e)
56
56
  end
@@ -58,32 +58,52 @@ module NightcrawlerSwift
58
58
  def auth_options
59
59
  {
60
60
  auth: {
61
- tenantName: opts.tenant_name,
62
- passwordCredentials: {username: opts.username, password: opts.password}
61
+ identity: {
62
+ methods: [
63
+ "password"
64
+ ],
65
+ password: {
66
+ user: {
67
+ domain: {
68
+ id: "default"
69
+ },
70
+ name: opts.username,
71
+ password: opts.password
72
+ }
73
+ }
74
+ },
75
+ scope: {
76
+ project: {
77
+ domain: {
78
+ id: "default"
79
+ },
80
+ name: opts.tenant_name
81
+ }
82
+ }
63
83
  }
64
84
  }
65
85
  end
66
86
 
67
87
  def select_token
68
- @token_id = auth_response.access["token"]["id"]
69
- @expires_at = auth_response.access["token"]["expires"]
88
+ @token_id = auth_response.headers[:x_subject_token]
89
+ @expires_at = auth_response.body["token"]["expires_at"]
70
90
  @expires_at = DateTime.parse(@expires_at).to_time
71
91
  end
72
92
 
73
93
  def select_catalog
74
- catalogs = auth_response.access["serviceCatalog"]
94
+ catalogs = auth_response["body"]["token"]["catalog"]
75
95
  @catalog = catalogs.find {|catalog| catalog["type"] == "object-store"}
76
96
  end
77
97
 
78
98
  def select_endpoints
79
99
  raise Exceptions::ConfigurationError.new "No catalog of type 'object-store' found" if @catalog.nil?
80
- @endpoints = @catalog["endpoints"].first
100
+ @endpoints = @catalog["endpoints"]
81
101
  end
82
102
 
83
103
  def configure_urls
84
- @admin_url = opts.admin_url || @endpoints["adminURL"]
85
- @public_url = opts.public_url || @endpoints["publicURL"]
86
- @internal_url = opts.internal_url || @endpoints["internalURL"]
104
+ @admin_url = opts.admin_url || @endpoints.find {|e| e["interface"] == "admin"}["url"]
105
+ @public_url = opts.public_url || @endpoints.find {|e| e["interface"] == "public"}["url"]
106
+ @internal_url = opts.internal_url || @endpoints.find {|e| e["interface"] == "internal"}["url"]
87
107
  @upload_url = "#{@admin_url}/#{opts.bucket}"
88
108
  end
89
109
  end
@@ -1,3 +1,3 @@
1
1
  module NightcrawlerSwift
2
- VERSION = "0.11.1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,62 +1,87 @@
1
1
  {
2
- "access" : {
3
- "serviceCatalog" : [
4
- {
5
- "name" : "swift",
6
- "endpoints_links" : [],
7
- "type" : "object-store",
8
- "endpoints" : [
9
- {
10
- "publicURL" : "http://public-url-com",
11
- "internalURL" : "http://internal-url-com",
12
- "adminURL" : "http://api-url-com",
13
- "region" : "RegionOne",
14
- "id" : "1"
15
- }
16
- ]
17
- },
18
- {
19
- "name" : "keystone",
20
- "endpoints_links" : [],
21
- "type" : "identity",
22
- "endpoints" : [
23
- {
24
- "publicURL" : "http://auth-url-com:123/v2.0",
25
- "internalURL" : "https://auth-url-com:123/v2.0",
26
- "adminURL" : "https://auth-url-com:321/v2.0",
27
- "region" : "RegionOne",
28
- "id" : "2"
29
- }
30
- ]
31
- }
2
+ "headers": {
3
+ "X-Subject-Token": "12345"
4
+ },
5
+ "body": {
6
+ "token": {
7
+ "methods": [
8
+ "password"
32
9
  ],
33
- "user" : {
34
- "roles" : [
10
+ "roles": [
11
+ {
12
+ "id": "3fe2ff9ee4384b1894a90878d3e92bab",
13
+ "name": "_member_"
14
+ },
15
+ {
16
+ "id": "c573d00d11ed4f75a7cae8e7527eb1ed",
17
+ "name": "swiftoperator"
18
+ }
19
+ ],
20
+ "expires_at": "2017-07-06T18:24:31.037559Z",
21
+ "project": {
22
+ "domain": {
23
+ "id": "default",
24
+ "name": "Default"
25
+ },
26
+ "id": "5c6a4110f7f9436b8e1f6696f9f6a13f",
27
+ "name": "tenant_username1"
28
+ },
29
+ "catalog": [
30
+ {
31
+ "name" : "swift",
32
+ "id": "0f7d75e8a91249628ad63356002b4869",
33
+ "type" : "object-store",
34
+ "endpoints" : [
35
+ {
36
+ "region_id": "RegionOne",
37
+ "url": "http://auth-url-com:123/v3/admin",
38
+ "region": "RegionOne",
39
+ "interface": "admin",
40
+ "id": "a723954cc89d3e93a65c1f658132773d"
41
+ },
35
42
  {
36
- "name" : "swiftoperator"
43
+ "region_id": "RegionOne",
44
+ "url": "http://auth-url-com:123/v3/internal",
45
+ "region": "RegionOne",
46
+ "interface": "internal",
47
+ "id": "beea797b69fa47159e44a220ea05c61c"
48
+ },
49
+ {
50
+ "region_id": "RegionOne",
51
+ "url": "http://auth-url-com:123/v3/public",
52
+ "region": "RegionOne",
53
+ "interface": "public",
54
+ "id": "9e36056aba514263a1d1d8ae10cfb796"
37
55
  }
38
- ],
39
- "roles_links" : [],
40
- "name" : "User Name 1",
41
- "id" : "3",
42
- "username" : "username1"
43
- },
44
- "metadata" : {
45
- "roles" : [
46
- "4"
47
- ],
48
- "is_admin" : 0
56
+ ]
57
+ },
58
+ {
59
+ "name" : "keystone",
60
+ "id" : "7efb509d3a0b446fa324d0bc4503e6d3",
61
+ "type" : "identity",
62
+ "endpoints" : [
63
+ {
64
+ "region_id" : "RegionOne",
65
+ "url" : "http://auth-url-com:123/v3/public",
66
+ "interface": "public",
67
+ "id" : "29e36056aba514263a1d1d8ae10cfb79"
68
+ }
69
+ ]
70
+ }
71
+ ],
72
+ "extras": {},
73
+ "user": {
74
+ "domain": {
75
+ "id": "default",
76
+ "name": "Default"
77
+ },
78
+ "id": "83e2c39492e343f08b0621ddc2e46eab",
79
+ "name": "username1"
49
80
  },
50
- "token" : {
51
- "tenant" : {
52
- "name" : "tenant_username1",
53
- "id" : "5",
54
- "description" : "some desc",
55
- "enabled" : true
56
- },
57
- "issued_at" : "2014-08-25T17:53:26.667691",
58
- "id" : "5",
59
- "expires" : "2014-08-25T18:53:26Z"
60
- }
61
- }
81
+ "audit_ids": [
82
+ "B77HzuC7QimfKre8DhDrhw"
83
+ ],
84
+ "issued_at": "2017-07-06T17:24:31.037629Z"
85
+ }
86
+ }
62
87
  }
@@ -25,7 +25,7 @@ describe NightcrawlerSwift::Delete do
25
25
 
26
26
  context "success" do
27
27
  let :response do
28
- double(:response, code: 200)
28
+ double(:response, code: 204)
29
29
  end
30
30
 
31
31
  before do
@@ -42,6 +42,20 @@ describe NightcrawlerSwift::Delete do
42
42
  end
43
43
  end
44
44
 
45
+ context "failure" do
46
+ let :response do
47
+ double(:response, code: 404)
48
+ end
49
+
50
+ before do
51
+ allow(subject).to receive(:delete).and_return(response)
52
+ end
53
+
54
+ it "returns false" do
55
+ expect(execute).to eql false
56
+ end
57
+ end
58
+
45
59
  context "when the path was not informed" do
46
60
  it "raises NightcrawlerSwift::Exceptions::ValidationError" do
47
61
  expect { subject.execute nil }.to raise_error NightcrawlerSwift::Exceptions::ValidationError
@@ -165,6 +165,13 @@ describe NightcrawlerSwift::Upload do
165
165
  let(:response) { double(:response, code: 500) }
166
166
  it { expect(execute).to be false }
167
167
  end
168
+
169
+ context "when the path was not informed" do
170
+ it "raises NightcrawlerSwift::Exceptions::ValidationError" do
171
+ expect { subject.execute(nil, file) }.to raise_error NightcrawlerSwift::Exceptions::ValidationError
172
+ expect { subject.execute("", file) }.to raise_error NightcrawlerSwift::Exceptions::ValidationError
173
+ end
174
+ end
168
175
  end
169
176
 
170
177
  end
@@ -8,7 +8,7 @@ describe NightcrawlerSwift::Connection do
8
8
  tenant_name: "tenant_username1",
9
9
  username: "username1",
10
10
  password: "some-pass",
11
- auth_url: "https://auth-url-com:123/v2.0/tokens",
11
+ auth_url: "https://auth-url-com:123/v3/auth/tokens",
12
12
  max_age: 31536000 # 1 year
13
13
  }
14
14
  end
@@ -30,19 +30,48 @@ describe NightcrawlerSwift::Connection do
30
30
  let :auth_json do
31
31
  {
32
32
  auth: {
33
- tenantName: opts[:tenant_name],
34
- passwordCredentials: {username: opts[:username], password: opts[:password]}
33
+ identity: {
34
+ methods: [
35
+ "password"
36
+ ],
37
+ password: {
38
+ user: {
39
+ domain: {
40
+ id: "default"
41
+ },
42
+ name: opts[:username],
43
+ password: opts[:password]
44
+ }
45
+ }
46
+ },
47
+ scope: {
48
+ project: {
49
+ domain: {
50
+ id: "default"
51
+ },
52
+ name: opts[:tenant_name]
53
+ }
54
+ }
35
55
  }
36
56
  }.to_json
37
57
  end
38
58
 
39
59
  let :auth_success_response do
40
60
  path = File.join(File.dirname(__FILE__), "../..", "fixtures/auth_success.json")
41
- OpenStruct.new(body: File.read(File.expand_path(path)))
61
+ file_contents = JSON.parse(File.read(File.expand_path(path)))
62
+ headers = file_contents["headers"].reduce({}) do |h, item|
63
+ key, value = item
64
+ h[key.downcase.gsub("-", "_").to_sym] = value
65
+ h
66
+ end
67
+ OpenStruct.new(headers: headers, body: file_contents["body"].to_json)
42
68
  end
43
69
 
44
70
  let :auth_success_json do
45
- JSON.parse(auth_success_response.body)
71
+ {
72
+ "headers" => auth_success_response.headers,
73
+ "body" => JSON.parse(auth_success_response.body)
74
+ }
46
75
  end
47
76
 
48
77
  describe "when it connects" do
@@ -61,48 +90,55 @@ describe NightcrawlerSwift::Connection do
61
90
  and_return(auth_success_response)
62
91
  end
63
92
 
64
- it "stores the auth_response" do
93
+ it "stores the auth response body" do
65
94
  subject.connect!
66
95
  # This test uses 'eq' instead of 'eql' because in Ruby 1.9.x the method
67
96
  # 'equal?' is different than '==' making this test fail
68
- expect(subject.auth_response).to eq(OpenStruct.new(auth_success_json))
97
+ expect(subject.auth_response.body).to eq(auth_success_json["body"])
98
+ end
99
+
100
+ it "stores the auth response headers" do
101
+ subject.connect!
102
+ expect(subject.auth_response.headers).to eq(auth_success_json["headers"])
69
103
  end
70
104
 
71
105
  it "stores the token id" do
72
106
  subject.connect!
73
- expect(subject.token_id).to eql(auth_success_json["access"]["token"]["id"])
107
+ expect(subject.token_id).not_to be_nil
108
+ expect(subject.token_id).to eql(auth_success_json["headers"][:x_subject_token])
74
109
  end
75
110
 
76
111
  it "stores the expires_at" do
77
112
  subject.connect!
78
- expires_at = DateTime.parse(auth_success_json["access"]["token"]["expires"]).to_time
113
+ expires_at = DateTime.parse(auth_success_json["body"]["token"]["expires_at"]).to_time
79
114
  expect(subject.expires_at).to eql(expires_at)
80
115
  end
81
116
 
82
117
  it "stores the catalog" do
83
- expect(subject).to receive(:connect!).and_call_original
84
- expect(subject.catalog).to eql(auth_success_json["access"]["serviceCatalog"][0])
118
+ subject.connect!
119
+ expect(subject.catalog).to eql(auth_success_json["body"]["token"]["catalog"][0])
120
+ expect(subject.catalog["type"]).to eql("object-store")
85
121
  end
86
122
 
87
123
  it "stores the admin_url" do
88
- expect(subject).to receive(:connect!).and_call_original
89
- expect(subject.admin_url).to eql(auth_success_json["access"]["serviceCatalog"].first["endpoints"].first["adminURL"])
124
+ subject.connect!
125
+ expect(subject.admin_url).to eql(auth_success_json["body"]["token"]["catalog"][0]["endpoints"][0]["url"])
90
126
  end
91
127
 
92
128
  it "stores the upload_url" do
129
+ subject.connect!
93
130
  admin_url = subject.admin_url
94
- expect(subject).to receive(:connect!).and_call_original
95
131
  expect(subject.upload_url).to eql("#{admin_url}/#{opts[:bucket]}")
96
132
  end
97
133
 
98
134
  it "stores the public_url" do
99
- expect(subject).to receive(:connect!).and_call_original
100
- expect(subject.public_url).to eql(auth_success_json["access"]["serviceCatalog"].first["endpoints"].first["publicURL"])
135
+ subject.connect!
136
+ expect(subject.public_url).to eql(auth_success_json["body"]["token"]["catalog"][0]["endpoints"][2]["url"])
101
137
  end
102
138
 
103
139
  it "stores the internal_url" do
104
- expect(subject).to receive(:connect!).and_call_original
105
- expect(subject.internal_url).to eql(auth_success_json["access"]["serviceCatalog"].first["endpoints"].first["internalURL"])
140
+ subject.connect!
141
+ expect(subject.internal_url).to eql(auth_success_json["body"]["token"]["catalog"][0]["endpoints"][1]["url"])
106
142
  end
107
143
 
108
144
  it "returns self" do
@@ -111,7 +147,7 @@ describe NightcrawlerSwift::Connection do
111
147
 
112
148
  context "and there isn't any catalog configured" do
113
149
  before do
114
- auth_success_json["access"]["serviceCatalog"] = []
150
+ auth_success_json["body"]["token"]["catalog"] = []
115
151
  allow(subject).to receive(:auth_response).and_return(OpenStruct.new(auth_success_json))
116
152
  end
117
153
 
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.11.1
4
+ version: 1.0.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: 2016-10-19 00:00:00.000000000 Z
12
+ date: 2017-08-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -230,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
230
  version: '0'
231
231
  requirements: []
232
232
  rubyforge_project:
233
- rubygems_version: 2.5.1
233
+ rubygems_version: 2.5.2
234
234
  signing_key:
235
235
  specification_version: 4
236
236
  summary: Like the X-Men nightcrawler this gem teleports your assets to a OpenStack