seiso-import_master 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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