seiso-import_master 0.0.6 → 0.0.7

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,61 @@
1
+ require "uri"
2
+
3
+ module Seiso
4
+ class ImportMaster
5
+ module Util
6
+
7
+ # Seiso API v1 URI factory.
8
+ #
9
+ # URI templating (embodied here) is a temporary strategy for obtaining URIs. The plan is
10
+ # to adopt something like a Traverson-style strategy.
11
+ #
12
+ # Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
13
+ # Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
14
+ # License:: Apache 2.0
15
+ class UriFactoryV1
16
+
17
+ def initialize(base_uri)
18
+ @base_uri = base_uri
19
+ end
20
+
21
+ def nodes_uri(batch)
22
+ if batch
23
+ uri "/nodes?mode=batch"
24
+ else
25
+ uri "/nodes"
26
+ end
27
+ end
28
+
29
+ def node_uri(name)
30
+ uri "/nodes/#{name}"
31
+ end
32
+
33
+ def node_ip_address_uri(node_name, ip_address)
34
+ uri "/nodes/#{node_name}/ip-addresses/#{ip_address}"
35
+ end
36
+
37
+ def services_uri(batch)
38
+ if batch
39
+ uri "/services?mode=batch"
40
+ else
41
+ uri "/services"
42
+ end
43
+ end
44
+
45
+ def service_instances_uri(batch)
46
+ if batch
47
+ uri "/service-instances?mode=batch"
48
+ else
49
+ uri "/service-instances"
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def uri(path)
56
+ URI.parse "#{@base_uri}#{path}"
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,34 @@
1
+ require "uri"
2
+
3
+ module Seiso
4
+ class ImportMaster
5
+ module Util
6
+
7
+ # Seiso API v2 URI factory.
8
+ #
9
+ # URI templating (embodied here) is a temporary strategy for obtaining URIs. The plan is
10
+ # to adopt something like a Traverson-style strategy.
11
+ #
12
+ # Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
13
+ # Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
14
+ # License:: Apache 2.0
15
+ class UriFactoryV2
16
+
17
+ def initialize(base_uri)
18
+ @base_uri = base_uri
19
+ end
20
+
21
+ def doc_links_uri(service_key)
22
+ uri "/services/#{service_key}/doc-links"
23
+ end
24
+
25
+ private
26
+
27
+ def uri(path)
28
+ URI.parse "#{@base_uri}#{path}"
29
+ end
30
+
31
+ end # class UriFactoryV2
32
+ end # module Util
33
+ end # class ImportMaster
34
+ end # module Seiso
@@ -0,0 +1,19 @@
1
+ require_relative "../errors/invalid_document_error"
2
+
3
+ module Seiso
4
+ class ImportMaster
5
+ module Validators
6
+
7
+ # Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
8
+ # Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
9
+ # License:: Apache 2.0
10
+ class BaseValidator
11
+
12
+ # Raises an InvalidDocumentError with the given message.
13
+ def error(msg)
14
+ raise Seiso::ImportMaster::Errors::InvalidDocumentError.new msg
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,46 @@
1
+ require_relative "base_validator"
2
+
3
+ module Seiso
4
+ class ImportMaster
5
+ module Validators
6
+
7
+ # Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
8
+ # Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
9
+ # License:: Apache 2.0
10
+ class NodeValidator < BaseValidator
11
+
12
+ def validate(doc)
13
+ validate_si_key doc
14
+ validate_nodes doc
15
+ end
16
+
17
+ private
18
+
19
+ def validate_si_key(doc)
20
+ si_key = doc['serviceInstance']
21
+
22
+ if si_key.nil?
23
+ error "Node document must contain a serviceInstance field containing the service instance key."
24
+ end
25
+ end
26
+
27
+ def validate_nodes(doc)
28
+ nodes = doc['items']
29
+
30
+ if nodes.nil?
31
+ error "Node document must contain an items field containing the service instance's nodes."
32
+ end
33
+
34
+ # Fail if the node has a serviceInstance field. This is legacy, and we don't want it anymore, because
35
+ # people will think that they can move a node from one service instance to another by changing this field.
36
+ nodes.each do |n|
37
+ if n['serviceInstance']
38
+ error "Individual nodes must not contain a serviceInstance field. " \
39
+ "Specify the service instance using the document-level serviceInstance field."
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,45 @@
1
+ require_relative "base_validator"
2
+
3
+ module Seiso
4
+ class ImportMaster
5
+ module Validators
6
+
7
+ # Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
8
+ # Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
9
+ # License:: Apache 2.0
10
+ class ServiceValidator < BaseValidator
11
+
12
+ def validate(doc)
13
+ validate_services doc
14
+ end
15
+
16
+ private
17
+
18
+ def validate_services(doc)
19
+ services = doc['items']
20
+
21
+ if services.nil?
22
+ error "Service document must contain an items field containing the services."
23
+ end
24
+
25
+ services.each { |s| validate_service s }
26
+ end
27
+
28
+ def validate_service(s)
29
+ key = s['key']
30
+
31
+ if key.nil?
32
+ error "Service must have a key"
33
+ end
34
+
35
+ name = s['name']
36
+
37
+ if name.nil?
38
+ error "Service must have a name"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "seiso-import_master"
7
- spec.version = "0.0.6"
7
+ spec.version = "0.0.7"
8
8
  spec.authors = ["Willie Wheeler"]
9
9
  spec.email = ["wwheeler@expedia.com"]
10
10
  spec.summary = "Imports Seiso data master files into Seiso."
@@ -17,8 +17,11 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
+ spec.required_ruby_version = '~> 1.9.3'
21
+
20
22
  spec.add_development_dependency "bundler", "~> 1.7"
21
23
  spec.add_development_dependency "rake", "~> 10.0"
22
24
 
23
25
  spec.add_runtime_dependency "seiso-connector", "~> 0.1.0"
26
+ spec.add_runtime_dependency "require_all", "~> 1.3.2"
24
27
  end
@@ -1,14 +1,14 @@
1
1
  require 'minitest/autorun'
2
- require 'seiso/import_master/master_item_mapper'
2
+ require 'seiso/import_master/mappers/master_item_mapper'
3
3
 
4
4
  # Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
5
5
  # Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
6
6
  # License:: Apache 2.0
7
-
8
7
  class TestMasterItemMapper < MiniTest::Unit::TestCase
9
8
 
9
+ =begin
10
10
  def setup
11
- @mapper = Seiso::ImportMaster::MasterItemMapper.new
11
+ @mapper = MasterItemMapper.new
12
12
  end
13
13
 
14
14
  def test_map_all_illegal_type
@@ -120,33 +120,6 @@ class TestMasterItemMapper < MiniTest::Unit::TestCase
120
120
  assert_equal(from['platformVersion'], to['platformVersion'])
121
121
  end
122
122
 
123
- def test_map_node
124
- from = {
125
- 'name' => 'seiso01-dev',
126
- 'serviceInstance' => 'seiso-dev',
127
- 'machine' => 'ip-1-2-3-4',
128
- 'ipAddresses' => [
129
- {
130
- 'ipAddressRole' => 'internal',
131
- 'ipAddress' => '1.2.10.1'
132
- }, {
133
- 'ipAddressRole' => 'partners',
134
- 'ipAddress' => '1.2.10.2'
135
- }
136
- ]
137
- }
138
- to = @mapper.map_one('nodes', from)
139
- assert_equal(from['name'], to['name'])
140
- refute_nil(to['serviceInstance'])
141
- refute_nil(to['machine'])
142
-
143
- # TODO Move these to a test_ip_address method
144
- # assert_equal(from['ipAddresses'][0]['ipAddressRole'], to['ipAddresses'][0]['ipAddressRole']['name'])
145
- # assert_equal(from['ipAddresses'][0]['ipAddress'], to['ipAddresses'][0]['ipAddress'])
146
- # assert_equal(from['ipAddresses'][1]['ipAddressRole'], to['ipAddresses'][1]['ipAddressRole']['name'])
147
- # assert_equal(from['ipAddresses'][1]['ipAddress'], to['ipAddresses'][1]['ipAddress'])
148
- end
149
-
150
123
  def test_map_region
151
124
  from = {
152
125
  'key' => 'amazon-us-east-1',
@@ -279,4 +252,6 @@ class TestMasterItemMapper < MiniTest::Unit::TestCase
279
252
  assert_equal(from['key'], to['key'])
280
253
  assert_equal(from['name'], to['name'])
281
254
  end
255
+ =end
256
+
282
257
  end
@@ -0,0 +1,40 @@
1
+ require "minitest/autorun"
2
+ require "seiso/import_master/mappers/node_mapper"
3
+
4
+ # Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
5
+ # Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
6
+ # License:: Apache 2.0
7
+ class TestNodeMapper < MiniTest::Unit::TestCase
8
+
9
+ def setup
10
+ @mapper = Seiso::ImportMaster::Mappers::NodeMapper.new
11
+ end
12
+
13
+ def test_map_node
14
+ from = {
15
+ 'name' => 'seiso01-dev',
16
+ 'machine' => 'ip-1-2-3-4',
17
+ 'ipAddresses' => [
18
+ {
19
+ 'ipAddressRole' => 'internal',
20
+ 'ipAddress' => '1.2.10.1'
21
+ }, {
22
+ 'ipAddressRole' => 'partners',
23
+ 'ipAddress' => '1.2.10.2'
24
+ }
25
+ ]
26
+ }
27
+ to = @mapper.seiso_node(from)
28
+ assert_equal(from['name'], to['name'])
29
+ refute_nil(to['machine'])
30
+
31
+ # TODO Move these to a test_ip_address method
32
+ # assert_equal(from['ipAddresses'][0]['ipAddressRole'], to['ipAddresses'][0]['ipAddressRole']['name'])
33
+ # assert_equal(from['ipAddresses'][0]['ipAddress'], to['ipAddresses'][0]['ipAddress'])
34
+ # assert_equal(from['ipAddresses'][1]['ipAddressRole'], to['ipAddresses'][1]['ipAddressRole']['name'])
35
+ # assert_equal(from['ipAddresses'][1]['ipAddress'], to['ipAddresses'][1]['ipAddress'])
36
+ end
37
+
38
+ def test_map_node_ip_address
39
+ end
40
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: seiso-import_master
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willie Wheeler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-21 00:00:00.000000000 Z
11
+ date: 2015-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: require_all
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 1.3.2
55
69
  description: Supports self-service data management via version control, e.g. by using
56
70
  GitHub.
57
71
  email:
@@ -69,11 +83,26 @@ files:
69
83
  - Rakefile
70
84
  - bin/seiso-import-master
71
85
  - lib/seiso/import_master.rb
72
- - lib/seiso/import_master/master_item_mapper.rb
73
- - refresh
86
+ - lib/seiso/import_master/errors/invalid_document_error.rb
87
+ - lib/seiso/import_master/importers/base_importer.rb
88
+ - lib/seiso/import_master/importers/node_importer.rb
89
+ - lib/seiso/import_master/importers/service_importer.rb
90
+ - lib/seiso/import_master/importers/service_instance_importer.rb
91
+ - lib/seiso/import_master/importers/simple_importer.rb
92
+ - lib/seiso/import_master/mappers/master_item_mapper.rb
93
+ - lib/seiso/import_master/mappers/node_mapper.rb
94
+ - lib/seiso/import_master/mappers/service_instance_mapper.rb
95
+ - lib/seiso/import_master/mappers/service_mapper.rb
96
+ - lib/seiso/import_master/util/rest_connector.rb
97
+ - lib/seiso/import_master/util/uri_factory_v1.rb
98
+ - lib/seiso/import_master/util/uri_factory_v2.rb
99
+ - lib/seiso/import_master/validators/base_validator.rb
100
+ - lib/seiso/import_master/validators/node_validator.rb
101
+ - lib/seiso/import_master/validators/service_validator.rb
74
102
  - sample_conf/seiso.yml.sample
75
103
  - seiso-import_master.gemspec
76
104
  - test/test_master_item_mapper.rb
105
+ - test/test_node_mapper.rb
77
106
  homepage: http://seiso.io
78
107
  licenses:
79
108
  - Apache-2.0
@@ -84,9 +113,9 @@ require_paths:
84
113
  - lib
85
114
  required_ruby_version: !ruby/object:Gem::Requirement
86
115
  requirements:
87
- - - ! '>='
116
+ - - ~>
88
117
  - !ruby/object:Gem::Version
89
- version: '0'
118
+ version: 1.9.3
90
119
  required_rubygems_version: !ruby/object:Gem::Requirement
91
120
  requirements:
92
121
  - - ! '>='
@@ -100,3 +129,4 @@ specification_version: 4
100
129
  summary: Imports Seiso data master files into Seiso.
101
130
  test_files:
102
131
  - test/test_master_item_mapper.rb
132
+ - test/test_node_mapper.rb
@@ -1,295 +0,0 @@
1
- module Seiso
2
- class ImportMaster
3
-
4
- # Maps the data master format to the Seiso API format.
5
- #
6
- # Author:: Willie Wheeler
7
- # Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
8
- # License:: Apache 2.0
9
- class MasterItemMapper
10
-
11
- def initialize
12
- @mappers = {
13
- 'data-centers' => data_center_mapper,
14
- 'doc-links' => doc_link_mapper,
15
- 'environments' => environment_mapper,
16
- 'health-statuses' => health_status_mapper,
17
- 'infrastructure-providers' => infrastructure_provider_mapper,
18
- 'ip-address-roles' => ip_address_role_mapper,
19
- 'load-balancers' => load_balancer_mapper,
20
- 'machines' => machine_mapper,
21
- 'nodes' => node_mapper,
22
- 'node-ip-addresses' => node_ip_address_mapper,
23
- 'regions' => region_mapper,
24
- 'rotation-statuses' => rotation_status_mapper,
25
- 'services' => service_mapper,
26
- 'service-groups' => service_group_mapper,
27
- 'service-instances' => service_instance_mapper,
28
- 'service-instance-ports' => service_instance_port_mapper,
29
- 'service-types' => service_type_mapper,
30
- 'status-types' => status_type_mapper
31
- }
32
- end
33
-
34
- # Maps a list of items.
35
- # - type: Item type
36
- # - items: Item list
37
- def map_all(type, items)
38
- mapper = mapper_for type
39
- result = []
40
- items.each { |i| result << mapper.call(i) }
41
- result
42
- end
43
-
44
- # Maps a single item.
45
- # - type: Item type
46
- # - item: Item
47
- def map_one(type, item)
48
- mapper_for(type).call item
49
- end
50
-
51
- private
52
-
53
- # Returns a mapper lambda for the specified type.
54
- def mapper_for(type)
55
- mapper = @mappers[type]
56
- raise ArgumentError, "Unknown type: #{type}" if mapper.nil?
57
- mapper
58
- end
59
-
60
- def data_center_mapper
61
- ->(dc) {
62
- {
63
- 'key' => dc['key'],
64
- 'name' => dc['name'],
65
- 'region' => { 'key' => dc['region'] }
66
- }
67
- }
68
- end
69
-
70
- def doc_link_mapper
71
- ->(dl) {
72
- {
73
- 'title' => dl['title'],
74
- 'href' => dl['href'],
75
- 'description' => dl['description']
76
- }
77
- }
78
- end
79
-
80
- def environment_mapper
81
- ->(e) {
82
- {
83
- 'key' => e['key'],
84
- 'name' => e['name'],
85
- 'aka' => e['aka'],
86
- 'description' => e['description'],
87
-
88
- # FIXME Deprecated, don't use.
89
- 'rank' => e['rank']
90
- }
91
- }
92
- end
93
-
94
- def health_status_mapper
95
- ->(hs) {
96
- {
97
- 'key' => hs['key'],
98
- 'name' => hs['name'],
99
- 'statusType' => { 'key' => hs['statusType'] }
100
- }
101
- }
102
- end
103
-
104
- def infrastructure_provider_mapper
105
- ->(ip) {
106
- {
107
- 'key' => ip['key'],
108
- 'name' => ip['name']
109
- }
110
- }
111
- end
112
-
113
- def ip_address_role_mapper
114
- # Suppressing IP addresses since we don't import those from master files.
115
- ->(r) {
116
- {
117
- 'serviceInstance' => { 'key' => r['serviceInstance'] },
118
- 'name' => r['name'],
119
- 'description' => r['description']
120
- }
121
- }
122
- end
123
-
124
- def load_balancer_mapper
125
- ->(lb) {
126
- seiso_lb = {
127
- 'name' => lb['name'],
128
- 'type' => lb['type'],
129
- 'ipAddress' => lb['ipAddress'],
130
- 'apiUrl' => lb['apiUrl']
131
- }
132
-
133
- dc = lb['dataCenter']
134
- seiso_lb['dataCenter'] = { 'key' => dc } unless dc.nil?
135
-
136
- seiso_lb
137
- }
138
- end
139
-
140
- def machine_mapper
141
- ->(m) {
142
- {
143
- 'name' => m['name'],
144
- 'ipAddress' => m['ipAddress'],
145
- 'fqdn' => m['fqdn'],
146
- 'hostname' => m['hostname'],
147
- 'domain' => m['domain'],
148
- 'os' => m['os'],
149
- 'platform' => m['platform'],
150
- 'platformVersion' => m['platformVersion']
151
- }
152
- }
153
- end
154
-
155
- def node_mapper
156
- ->(n) {
157
- seiso_node = {
158
- 'name' => n['name'],
159
- 'serviceInstance' => { 'key' => n['serviceInstance'] }
160
- }
161
-
162
- machine = n['machine']
163
- seiso_node['machine'] = { 'name' => machine } unless machine.nil?
164
-
165
- seiso_node
166
- }
167
- end
168
-
169
- def node_ip_address_mapper
170
- # Currently suppressing rotation status and endpoints since we don't import those from master files
171
- ->(nip) {
172
- {
173
- 'node' => { 'name' => nip['node'] },
174
- 'ipAddressRole' => { 'name' => nip['ipAddressRole'] },
175
- 'ipAddress' => nip['ipAddress']
176
- }
177
- }
178
- end
179
-
180
- def region_mapper
181
- ->(r) {
182
- {
183
- 'key' => r['key'],
184
- 'name' => r['name'],
185
- 'regionKey' => r['regionKey'],
186
- 'infrastructureProvider' => { 'key' => r['infrastructureProvider'] }
187
- }
188
- }
189
- end
190
-
191
- def rotation_status_mapper
192
- ->(rs) {
193
- {
194
- 'key' => rs['key'],
195
- 'name' => rs['name'],
196
- 'statusType' => { 'key' => rs['statusType'] }
197
- }
198
- }
199
- end
200
-
201
- def service_mapper
202
- ->(s) {
203
- seiso_service = {
204
- 'key' => s['key'],
205
- 'name' => s['name'],
206
- 'description' => s['description'],
207
- 'platform' => s['platform'],
208
- 'scmRepository' => s['scmRepository']
209
- }
210
-
211
- group = s['group']
212
- seiso_service['group'] = { 'key' => group } unless group.nil?
213
-
214
- type = s['type']
215
- seiso_service['type'] = { 'key' => type } unless type.nil?
216
-
217
- owner = s['owner']
218
- seiso_service['owner'] = { 'username' => owner } unless owner.nil?
219
-
220
- seiso_service
221
- }
222
- end
223
-
224
- def service_group_mapper
225
- ->(sg) {
226
- {
227
- 'key' => sg['key'],
228
- 'name' => sg['name']
229
- }
230
- }
231
- end
232
-
233
- def service_instance_mapper
234
- ->(si) {
235
- key = si['key']
236
- ip_address_roles = si['ipAddressRoles']
237
- ports = si['ports']
238
-
239
- seiso_si = {
240
- 'key' => key,
241
- 'service' => { 'key' => si['service'] },
242
- 'environment' => { 'key' => si['environment'] },
243
- 'loadBalanced' => si['loadBalanced'],
244
- 'minCapacityDeploy' => si['minCapacityDeploy'],
245
- 'minCapacityOps' => si['minCapacityOps'],
246
-
247
- # FIXME Deprecated. This is a hardcoded field for an internal Expedia app, and we will remove it.
248
- 'eosManaged' => (si['eosManaged'] || false),
249
-
250
- # FIXME Deprecated. This is the old name for the minCapacityOps field.
251
- 'requiredCapacity' => si['minCapacityOps']
252
- }
253
-
254
- data_center = si['dataCenter']
255
- seiso_si['dataCenter'] = { 'key' => data_center } unless data_center.nil?
256
-
257
- load_balancer = si['loadBalancer']
258
- seiso_si['loadBalancer'] = { 'name' => load_balancer } unless load_balancer.nil?
259
-
260
- seiso_si
261
- }
262
- end
263
-
264
- def service_instance_port_mapper
265
- # Suppressing endpoints since we don't import those from master files.
266
- ->(p) {
267
- {
268
- 'serviceInstance' => { 'key' => p['serviceInstance'] },
269
- 'number' => p['number'],
270
- 'protocol' => p['protocol'],
271
- 'description' => p['description']
272
- }
273
- }
274
- end
275
-
276
- def service_type_mapper
277
- ->(st) {
278
- {
279
- 'key' => st['key'],
280
- 'name' => st['name']
281
- }
282
- }
283
- end
284
-
285
- def status_type_mapper
286
- ->(st) {
287
- {
288
- 'key' => st['key'],
289
- 'name' => st['name']
290
- }
291
- }
292
- end
293
- end
294
- end
295
- end