seiso-import_master 0.0.12 → 3.0.0.M1
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.
- checksums.yaml +8 -8
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/README.md +12 -11
- data/Rakefile +3 -3
- data/bin/seiso-import-master +30 -13
- data/lib/seiso/import_master.rb +114 -90
- data/lib/seiso/import_master/importers.rb +5 -0
- data/lib/seiso/import_master/importers/base_importer.rb +91 -30
- data/lib/seiso/import_master/importers/data_center_importer.rb +31 -0
- data/lib/seiso/import_master/importers/environment_importer.rb +25 -0
- data/lib/seiso/import_master/importers/health_status_importer.rb +25 -0
- data/lib/seiso/import_master/importers/infrastructure_provider_importer.rb +25 -0
- data/lib/seiso/import_master/importers/ip_address_role_importer.rb +41 -0
- data/lib/seiso/import_master/importers/load_balancer_importer.rb +25 -0
- data/lib/seiso/import_master/importers/machine_importer.rb +25 -0
- data/lib/seiso/import_master/importers/node_importer.rb +94 -56
- data/lib/seiso/import_master/importers/node_ip_address_importer.rb +46 -0
- data/lib/seiso/import_master/importers/region_importer.rb +31 -0
- data/lib/seiso/import_master/importers/rotation_status_importer.rb +25 -0
- data/lib/seiso/import_master/importers/service_group_importer.rb +25 -0
- data/lib/seiso/import_master/importers/service_importer.rb +38 -143
- data/lib/seiso/import_master/importers/service_instance_importer.rb +60 -213
- data/lib/seiso/import_master/importers/service_instance_port_importer.rb +41 -0
- data/lib/seiso/import_master/importers/service_type_importer.rb +25 -0
- data/lib/seiso/import_master/importers/status_type_importer.rb +25 -0
- data/lib/seiso/import_master/mappers.rb +1 -0
- data/lib/seiso/import_master/mappers/data_center_mapper.rb +19 -0
- data/lib/seiso/import_master/mappers/environment_mapper.rb +20 -0
- data/lib/seiso/import_master/mappers/health_status_mapper.rb +20 -0
- data/lib/seiso/import_master/mappers/infrastructure_provider_mapper.rb +18 -0
- data/lib/seiso/import_master/mappers/ip_address_role_mapper.rb +18 -0
- data/lib/seiso/import_master/mappers/load_balancer_mapper.rb +21 -0
- data/lib/seiso/import_master/mappers/machine_mapper.rb +27 -0
- data/lib/seiso/import_master/mappers/node_ip_address_mapper.rb +38 -0
- data/lib/seiso/import_master/mappers/node_mapper.rb +31 -31
- data/lib/seiso/import_master/mappers/region_mapper.rb +20 -0
- data/lib/seiso/import_master/mappers/rotation_status_mapper.rb +20 -0
- data/lib/seiso/import_master/mappers/service_group_mapper.rb +18 -0
- data/lib/seiso/import_master/mappers/service_instance_mapper.rb +26 -73
- data/lib/seiso/import_master/mappers/service_instance_port_mapper.rb +19 -0
- data/lib/seiso/import_master/mappers/service_mapper.rb +23 -32
- data/lib/seiso/import_master/mappers/service_type_mapper.rb +19 -0
- data/lib/seiso/import_master/mappers/status_type_mapper.rb +18 -0
- data/lib/seiso/import_master/util.rb +1 -0
- data/lib/seiso/import_master/util/invalid_document_error.rb +9 -0
- data/lib/seiso/import_master/util/item_resolver.rb +54 -0
- data/lib/seiso/import_master/util/logger.rb +59 -0
- data/lib/seiso/import_master/util/rest_util.rb +49 -0
- data/lib/seiso/import_master/validators.rb +1 -0
- data/lib/seiso/import_master/validators/base_validator.rb +11 -18
- data/lib/seiso/import_master/validators/node_validator.rb +54 -45
- data/lib/seiso/import_master/validators/service_validator.rb +38 -44
- data/sample_conf/seiso3.yml.sample +6 -0
- data/seiso-import_master.gemspec +16 -13
- data/test/seiso/import_master/importers/test_node_importer.rb +21 -0
- metadata +66 -21
- data/lib/seiso/import_master/errors/invalid_document_error.rb +0 -11
- data/lib/seiso/import_master/importers/simple_importer.rb +0 -28
- data/lib/seiso/import_master/mappers/master_item_mapper.rb +0 -194
- data/sample_conf/seiso.yml.sample +0 -9
- data/test/test_master_item_mapper.rb +0 -257
- data/test/test_node_mapper.rb +0 -40
@@ -0,0 +1,19 @@
|
|
1
|
+
class Seiso::ImportMaster
|
2
|
+
# Maps a SDM IP address role to a Seiso IP address role.
|
3
|
+
#
|
4
|
+
# Author:: Willie Wheeler
|
5
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
6
|
+
# License:: Apache 2.0
|
7
|
+
class Mappers::ServiceInstancePortMapper
|
8
|
+
|
9
|
+
def map(doc_sip, context)
|
10
|
+
si_uri = context['serviceInstance'].href
|
11
|
+
{
|
12
|
+
'serviceInstance' => si_uri,
|
13
|
+
'number' => doc_sip['number'],
|
14
|
+
'protocol' => doc_sip['protocol'],
|
15
|
+
'description' => doc_sip['description']
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,35 +1,26 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
class Seiso::ImportMaster
|
2
|
+
# Author:: Willie Wheeler
|
3
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
4
|
+
# License:: Apache 2.0
|
5
|
+
class Mappers::ServiceMapper
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
|
9
|
-
# License:: Apache 2.0
|
10
|
-
class ServiceMapper
|
7
|
+
def initialize(resolver)
|
8
|
+
@resolver = resolver
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
owner = s['owner']
|
28
|
-
seiso_service['owner'] = { 'username' => owner } unless owner.nil?
|
29
|
-
|
30
|
-
seiso_service
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
11
|
+
# Maps a document service to a Seiso service.
|
12
|
+
#
|
13
|
+
# - doc_service : document service
|
14
|
+
def map(doc_service, context)
|
15
|
+
{
|
16
|
+
'key' => doc_service['key'],
|
17
|
+
'name' => doc_service['name'],
|
18
|
+
'platform' => doc_service['platform'],
|
19
|
+
'scmRepository' => doc_service['scmRepository'],
|
20
|
+
'group' => @resolver.item_uri('serviceGroups', doc_service['group']),
|
21
|
+
'type' => @resolver.item_uri('serviceTypes', doc_service['type']),
|
22
|
+
'owner' => @resolver.item_uri('persons', doc_service['owner'])
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
35
26
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Seiso::ImportMaster
|
2
|
+
# Author:: Willie Wheeler
|
3
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
4
|
+
# License:: Apache 2.0
|
5
|
+
class Mappers::ServiceTypeMapper
|
6
|
+
|
7
|
+
def initialize(resolver)
|
8
|
+
@resolver = resolver
|
9
|
+
end
|
10
|
+
|
11
|
+
def map(doc_st, context)
|
12
|
+
{
|
13
|
+
'key' => doc_st['key'],
|
14
|
+
'name' => doc_st['name'],
|
15
|
+
'description' => doc_st['description']
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Seiso::ImportMaster
|
2
|
+
# Author:: Willie Wheeler
|
3
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
4
|
+
# License:: Apache 2.0
|
5
|
+
class Mappers::StatusTypeMapper
|
6
|
+
|
7
|
+
def initialize(resolver)
|
8
|
+
@resolver = resolver
|
9
|
+
end
|
10
|
+
|
11
|
+
def map(doc_st, context)
|
12
|
+
{
|
13
|
+
'key' => doc_st['key'],
|
14
|
+
'name' => doc_st['name']
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
module Seiso::ImportMaster::Util; end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class Seiso::ImportMaster
|
2
|
+
|
3
|
+
# Resolves item keys to their URIs.
|
4
|
+
#
|
5
|
+
# Author:: Willie Wheeler
|
6
|
+
# Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
|
7
|
+
# License:: Apache 2.0
|
8
|
+
#
|
9
|
+
class Util::ItemResolver
|
10
|
+
|
11
|
+
def initialize(api)
|
12
|
+
@log = Util::Logger.new "ItemResolver"
|
13
|
+
@api = api
|
14
|
+
|
15
|
+
# Note that this initialization doesn't generate any HTTP requests.
|
16
|
+
@special_searches = {
|
17
|
+
# http://ruby-journal.com/becareful-with-space-in-lambda-hash-rocket-syntax-between-ruby-1-dot-9-and-2-dot-0/
|
18
|
+
'loadBalancers' => ->(k) { @api.loadBalancers.search.findByName(name: k) },
|
19
|
+
'machines' => ->(k) { @api.machines.search.findByName(name: k) },
|
20
|
+
'persons' => ->(k) { @api.persons.search.findByUsername(username: k) }
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the item URI, or nil if either key is nil or the item doesn't exist.
|
25
|
+
def item_uri(type, key)
|
26
|
+
@log.info "Getting item URI: type=#{type}, key=#{key}"
|
27
|
+
return nil if key.nil?
|
28
|
+
search = @special_searches[type]
|
29
|
+
|
30
|
+
if search == nil
|
31
|
+
item = @api.send(type).search.findByKey(key: key)
|
32
|
+
else # special search
|
33
|
+
item = search.call key
|
34
|
+
end
|
35
|
+
|
36
|
+
begin
|
37
|
+
# This returns the item's canonical URI, which is what we want.
|
38
|
+
item.links.self.href
|
39
|
+
rescue HyperResource::ClientError => e
|
40
|
+
status = e.response.status
|
41
|
+
body = e.response.body
|
42
|
+
raise "Response error: status=#{status}, body=#{body}" unless status == 404
|
43
|
+
@log.warn "#{type}/#{key} not found. Returning nil."
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# TODO Implementation based on HTTP 1.1 keepalive. The resolution above is too slow.
|
49
|
+
def item_uri_via_keepalive(type, key)
|
50
|
+
@log.info "Getting item URL: type=#{type}, key=#{key}"
|
51
|
+
# TODO
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Seiso::ImportMaster
|
2
|
+
|
3
|
+
# TODO Allow clients to enable/disable color codes. [WLW]
|
4
|
+
class Util::Logger
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
|
10
|
+
def info(message)
|
11
|
+
puts "[INFO] #{@name} : #{message}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def success(message)
|
15
|
+
puts "[SUCCESS] #{@name} : #{message}".green
|
16
|
+
end
|
17
|
+
|
18
|
+
def warn(message)
|
19
|
+
puts "[WARN] #{@name} : #{message}".yellow
|
20
|
+
end
|
21
|
+
|
22
|
+
def error(message)
|
23
|
+
STDERR.puts "[ERROR] #{@name} : #{message}".red
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# http://stackoverflow.com/questions/1489183/colorized-ruby-output
|
29
|
+
# FIXME Move to more appropriate location. Not sure where something like this should go. [WLW]
|
30
|
+
class String
|
31
|
+
|
32
|
+
def colorize(color_code)
|
33
|
+
"\e[#{color_code}m#{self}\e[0m"
|
34
|
+
end
|
35
|
+
|
36
|
+
def red
|
37
|
+
colorize(31)
|
38
|
+
end
|
39
|
+
|
40
|
+
def green
|
41
|
+
colorize(32)
|
42
|
+
end
|
43
|
+
|
44
|
+
def yellow
|
45
|
+
colorize(33)
|
46
|
+
end
|
47
|
+
|
48
|
+
def blue
|
49
|
+
colorize(34)
|
50
|
+
end
|
51
|
+
|
52
|
+
def pink
|
53
|
+
colorize(35)
|
54
|
+
end
|
55
|
+
|
56
|
+
def light_blue
|
57
|
+
colorize(36)
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'awesome_print'
|
2
|
+
|
3
|
+
class Seiso::ImportMaster
|
4
|
+
# Author:: Willie Wheeler
|
5
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
6
|
+
# License:: Apache 2.0
|
7
|
+
class Util::RestUtil
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@log = Util::Logger.new "RestUtil"
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_or_nil(resource, description)
|
14
|
+
resource_uri = resource.links.self.href
|
15
|
+
begin
|
16
|
+
@log.info "GET #{resource_uri} (#{description})"
|
17
|
+
return resource.get
|
18
|
+
rescue HyperResource::ClientError => e
|
19
|
+
status = e.response.status
|
20
|
+
body = e.response.body
|
21
|
+
raise "Response error: status=#{status}, body=#{body}" unless status == 404
|
22
|
+
@log.warn "Resource #{description} not found. Returning nil."
|
23
|
+
return nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def post(repo_resource, data, description)
|
28
|
+
repo_resource_uri = repo_resource.links.self.href
|
29
|
+
@log.info "POST #{repo_resource_uri} (#{description})"
|
30
|
+
response = repo_resource.post data
|
31
|
+
# TODO Read the status from the response if possible. [WLW]
|
32
|
+
@log.info " 201 Created: #{response.href}"
|
33
|
+
# response.href
|
34
|
+
response
|
35
|
+
end
|
36
|
+
|
37
|
+
def put(resource, data, description)
|
38
|
+
resource_uri = resource.links.self.href
|
39
|
+
@log.info "PUT #{resource_uri} (#{description})"
|
40
|
+
resource.put data
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(resource, description)
|
44
|
+
resource_uri = resource.links.self.href
|
45
|
+
@log.info "DELETE #{resource_uri} (#{description})"
|
46
|
+
resource.delete
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
module Seiso::ImportMaster::Validators; end
|
@@ -1,19 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
1
|
+
class Seiso::ImportMaster
|
2
|
+
# Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
|
3
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
4
|
+
# License:: Apache 2.0
|
5
|
+
class Validators::BaseValidator
|
6
|
+
# Raises an InvalidDocumentError with the given message.
|
7
|
+
# TODO Move to module method instead?
|
8
|
+
def error(msg)
|
9
|
+
fail Util::InvalidDocumentError.new msg
|
10
|
+
end
|
11
|
+
end
|
19
12
|
end
|
@@ -1,46 +1,55 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
1
|
+
module Seiso::ImportMaster::Validators
|
2
|
+
# Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
|
3
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
4
|
+
# License:: Apache 2.0
|
5
|
+
class NodeValidator < BaseValidator
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@log = Seiso::ImportMaster::Util::Logger.new "NodeValidator"
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate(doc)
|
12
|
+
# @log.info "Validating nodes"
|
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
|
+
nodes.each do |n|
|
35
|
+
node_name = n['name']
|
36
|
+
|
37
|
+
if node_name.nil?
|
38
|
+
error "Every node must have a name."
|
39
|
+
end
|
40
|
+
|
41
|
+
# Fail if the node has a serviceInstance field. This is legacy, and we don't want it anymore, because
|
42
|
+
# people will think that they can move a node from one service instance to another by changing this field.
|
43
|
+
if n['serviceInstance']
|
44
|
+
error "Node #{node_name} must not contain a serviceInstance field. " \
|
45
|
+
"Specify the service instance using the document-level serviceInstance field."
|
46
|
+
end
|
47
|
+
|
48
|
+
if n['machine'].nil?
|
49
|
+
error "Node #{node_name} must have a machine."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
46
55
|
end
|
@@ -1,45 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
1
|
+
module Seiso::ImportMaster::Validators
|
2
|
+
# Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
|
3
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
4
|
+
# License:: Apache 2.0
|
5
|
+
class ServiceValidator < BaseValidator
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@log = Seiso::ImportMaster::Util::Logger.new "ServiceValidator"
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate(doc)
|
12
|
+
# @log.info "Validating services"
|
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
|
+
error 'Service must have a key' if key.nil?
|
31
|
+
name = s['name']
|
32
|
+
error 'Service must have a name' if name.nil?
|
33
|
+
|
34
|
+
# This isn't required!
|
35
|
+
# type = s['type']
|
36
|
+
# error 'Service must have a type' if type.nil?
|
37
|
+
end
|
38
|
+
end
|
44
39
|
end
|
45
|
-
|