seiso-import_master 0.0.12 → 3.0.0.M1
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MTk2ZjJlYzk0YTA2YzVhN2IwOWEyZWM3NWM3Y2MwMjc3MjI0ZTNkOA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTM0NDk1MTQ1YmIxM2Y5OTdmMzc4ZTE4MWY5ZmU0NjM4MjcxYmY3Ng==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTkwNmE2N2E5M2FlMzZkN2FmNGZjOGEyODFjNmNmOTJmMWMxMThiYmJmMTY2
|
10
|
+
ZGY2YmQwZTIxMjU3MTkwYWJjMGFlYjU0YWI3ZjM3MjRlYmVlYTUyMGVkY2Ux
|
11
|
+
MDQ0NDUzODhlZmVjYjFkNDJhNGQ5Mjk3N2Q5YjRmNTNjMTc5MDM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MTI5ZGI3Y2E4NmFkMzg4YjlkMGRjNWQwMDcyODMxMWQxZGU0ZTIxNjU2OWQw
|
14
|
+
OGE5YjM4YTEwNzhlNzM1NjhjMDcyMTdjNGNjNzM3YzA4MDMzNTcxMmM4M2Yx
|
15
|
+
MmZmMjFmOTk4MDRlMDFlZjllN2I3NTRhOThjMDk3YWNmYzBjNTc=
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -10,26 +10,20 @@ See [Manage Your Service Data with GitHub, Jenkins & Seiso](http://seiso.io/guid
|
|
10
10
|
|
11
11
|
See [Seiso Data Master Schemas](http://seiso.io/docs/current/user-manual/sdm-schemas/) for the data master schemas.
|
12
12
|
|
13
|
-
## Installation
|
14
|
-
|
15
|
-
Add this line to your application's Gemfile:
|
13
|
+
## Installation preliminaries
|
16
14
|
|
17
|
-
|
18
|
-
gem 'seiso-import_master'
|
19
|
-
```
|
15
|
+
First, I recommend using [RVM](http://rvm.io/) to install/manage your rubies so you can run multiple rubies without conflict.
|
20
16
|
|
21
|
-
|
17
|
+
You will need Ruby 1.9.3 as well as [Bundler](http://bundler.io).
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
Or install it yourself as:
|
19
|
+
## Installation
|
26
20
|
|
27
21
|
$ gem install seiso-import_master
|
28
22
|
|
29
23
|
## Usage
|
30
24
|
|
31
25
|
1. Create a directory `~/.seiso-importers`
|
32
|
-
2. Place appropriately modified copy of `
|
26
|
+
2. Place appropriately modified copy of `seiso3.yml.sample` in there. Note that you will need to get Seiso credentials from your Seiso administrator.
|
33
27
|
3. Run `seiso-import-master file [, file2, ...]` to perform the import. Note that you can use `-f yaml` for YAML files (the default is `-f json`).
|
34
28
|
|
35
29
|
## Contributing
|
@@ -53,3 +47,10 @@ In particular, run the unit tests using
|
|
53
47
|
Build and install the gem using Rake:
|
54
48
|
|
55
49
|
$ rake install
|
50
|
+
|
51
|
+
For local snapshot installations, you may want to clear out existing versions of the gem first.
|
52
|
+
|
53
|
+
## TODO
|
54
|
+
|
55
|
+
Figure out whether we want to use dependency injection for this project. There's debate within the Ruby community
|
56
|
+
whether DI makes sense for Ruby.
|
data/Rakefile
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
3
|
|
4
4
|
task :default => [ :test ]
|
5
5
|
|
@@ -11,7 +11,7 @@ end
|
|
11
11
|
|
12
12
|
Rake::TestTask.new do |t|
|
13
13
|
t.libs << 'test'
|
14
|
-
t.test_files = FileList[ 'test
|
14
|
+
t.test_files = FileList[ 'test/**/test_*.rb' ]
|
15
15
|
t.verbose = true
|
16
16
|
t.warning = true
|
17
17
|
end
|
data/bin/seiso-import-master
CHANGED
@@ -3,31 +3,33 @@
|
|
3
3
|
# vi: set ft=ruby :
|
4
4
|
|
5
5
|
require 'optparse'
|
6
|
-
require 'seiso/import_master'
|
7
6
|
require 'yaml'
|
7
|
+
require 'seiso/import_master'
|
8
8
|
|
9
9
|
# Imports Seiso data master files into Seiso.
|
10
10
|
#
|
11
11
|
# Author:: Willie Wheeler
|
12
|
-
# Copyright:: Copyright (c) 2014-
|
12
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
13
13
|
# License:: Apache 2.0
|
14
14
|
|
15
|
+
log = Seiso::ImportMaster::Util::Logger.new "seiso-import-master"
|
16
|
+
|
15
17
|
options = {}
|
16
18
|
option_parser = OptionParser.new do |opts|
|
17
19
|
executable_name = File.basename $PROGRAM_NAME
|
18
20
|
opts.banner = "Import one or more Seiso data master files into Seiso.
|
19
21
|
|
20
22
|
Usage: #{executable_name} [options] master_file ..."
|
21
|
-
options[:
|
22
|
-
opts.on("--
|
23
|
-
options[:
|
23
|
+
options[:seiso3_settings_path] = "#{Dir.home}/.seiso-importers/seiso3.yml"
|
24
|
+
opts.on("--seiso3 SEISO3_SETTINGS_PATH", "Path to Seiso API v3 settings file") do |path|
|
25
|
+
options[:seiso3_settings_path] = path
|
24
26
|
end
|
25
27
|
|
26
28
|
options[:format] = 'json'
|
27
29
|
opts.on("-f FORMAT", "--format FORMAT", "Document format, either 'json' (default) or 'yaml'") do |format|
|
28
30
|
options[:format] = format
|
29
31
|
end
|
30
|
-
|
32
|
+
|
31
33
|
opts.on("-h", "--help", "Display this screen") do
|
32
34
|
puts opts
|
33
35
|
exit
|
@@ -37,15 +39,30 @@ end
|
|
37
39
|
begin
|
38
40
|
option_parser.parse!
|
39
41
|
rescue OptionParser::InvalidOption => e
|
40
|
-
|
42
|
+
log.error "Invalid option."
|
43
|
+
puts option_parser.help
|
44
|
+
abort
|
41
45
|
end
|
42
46
|
|
43
|
-
|
44
|
-
|
47
|
+
log.info "Using: #{options[:seiso3_settings_path]}"
|
48
|
+
log.info "Using: format=#{options[:format]}"
|
45
49
|
|
46
50
|
files = ARGV
|
47
|
-
|
51
|
+
if files.empty?
|
52
|
+
log.error "You must supply a master file."
|
53
|
+
puts option_parser.help
|
54
|
+
abort
|
55
|
+
end
|
56
|
+
|
57
|
+
seiso3_settings = YAML.load_file(options[:seiso3_settings_path])
|
58
|
+
importer = Seiso::ImportMaster.new seiso3_settings
|
59
|
+
result = importer.import_files(files, options[:format])
|
48
60
|
|
49
|
-
|
50
|
-
|
51
|
-
|
61
|
+
if result == "success"
|
62
|
+
log.success "Import succeeded."
|
63
|
+
elsif result == "partial"
|
64
|
+
log.warn "Import succeeded, but with issues."
|
65
|
+
else
|
66
|
+
log.error "Import failed."
|
67
|
+
abort
|
68
|
+
end
|
data/lib/seiso/import_master.rb
CHANGED
@@ -1,114 +1,138 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
6
|
-
require_rel "import_master"
|
1
|
+
require 'json'
|
2
|
+
require 'yaml'
|
3
|
+
require 'hyper_resource'
|
4
|
+
require 'require_all'
|
5
|
+
require_rel './import_master'
|
7
6
|
|
7
|
+
# Imports Seiso data master files into Seiso.
|
8
|
+
#
|
9
|
+
# Author:: Willie Wheeler
|
10
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
11
|
+
# License:: Apache 2.0
|
8
12
|
module Seiso
|
9
|
-
|
10
|
-
# Imports Seiso data master files into Seiso.
|
11
|
-
#
|
12
|
-
# Author:: Willie Wheeler (mailto:wwheeler@expedia.com)
|
13
|
-
# Copyright:: Copyright (c) 2014-2015 Expedia, Inc.
|
14
|
-
# License:: Apache 2.0
|
15
13
|
class ImportMaster
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
|
15
|
+
def initialize(seiso3_settings)
|
16
|
+
@log = Util::Logger.new "ImportMaster"
|
19
17
|
@loaders = {
|
20
18
|
'json' => ->(file) { JSON.parse(IO.read(file)) },
|
21
19
|
'yaml' => ->(file) { YAML.load_file file }
|
22
20
|
}
|
21
|
+
@v3_api = HyperResource.new(
|
22
|
+
root: seiso3_settings['base_uri'],
|
23
|
+
headers: {
|
24
|
+
'Accept' => 'application/hal+json',
|
25
|
+
'Content-Type' => 'application/hal+json'
|
26
|
+
},
|
27
|
+
auth: {
|
28
|
+
basic: [ seiso3_settings['username'], seiso3_settings['password'] ]
|
29
|
+
}
|
30
|
+
)
|
31
|
+
@resolver = Util::ItemResolver.new @v3_api
|
32
|
+
@rest_util = Util::RestUtil.new
|
23
33
|
|
24
|
-
#
|
25
|
-
@
|
26
|
-
'nodes' => Validators::NodeValidator.new,
|
27
|
-
'services' => Validators::ServiceValidator.new
|
28
|
-
}
|
29
|
-
|
30
|
-
basic_mapper = Mappers::MasterItemMapper.new
|
31
|
-
node_mapper = Mappers::NodeMapper.new
|
32
|
-
service_mapper = Mappers::ServiceMapper.new
|
33
|
-
service_instance_mapper = Mappers::ServiceInstanceMapper.new
|
34
|
-
|
35
|
-
seiso = Seiso::Connector.new seiso_settings
|
36
|
-
uri_factory_v1 = uri_factory_v1 seiso_settings
|
37
|
-
uri_factory_v2 = uri_factory_v2 seiso_settings
|
38
|
-
rest_connector_v1 = rest_connector(seiso_settings, "application/json")
|
39
|
-
rest_connector_v2 = rest_connector(seiso_settings, "application/hal+json")
|
40
|
-
|
41
|
-
@simple_importer = Importers::SimpleImporter.new(basic_mapper, seiso, uri_factory_v1, rest_connector_v1)
|
42
|
-
|
43
|
-
# TODO Clean this up. Just use v2 URI factory and connector.
|
44
|
-
@importers = {
|
45
|
-
'nodes' => Importers::NodeImporter.new(node_mapper, uri_factory_v1, rest_connector_v1),
|
46
|
-
'services' => Importers::ServiceImporter.new(
|
47
|
-
basic_mapper,
|
48
|
-
service_mapper,
|
49
|
-
uri_factory_v1,
|
50
|
-
uri_factory_v2,
|
51
|
-
rest_connector_v1,
|
52
|
-
rest_connector_v2),
|
53
|
-
'service-instances' => Importers::ServiceInstanceImporter.new(
|
54
|
-
service_instance_mapper,
|
55
|
-
uri_factory_v1,
|
56
|
-
uri_factory_v2,
|
57
|
-
seiso,
|
58
|
-
rest_connector_v1,
|
59
|
-
rest_connector_v2)
|
60
|
-
}
|
34
|
+
# Importer cache, since they're expensive to initialize
|
35
|
+
@importers = {}
|
61
36
|
end
|
62
37
|
|
63
38
|
# Imports a list of master files in order. Legal formats are 'json' (default) and 'yaml'.
|
39
|
+
# Returns true if all file imports succeeded and false otherwise.
|
64
40
|
def import_files(files, format = 'json')
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
41
|
+
begin
|
42
|
+
all_failed = true
|
43
|
+
all_success = true
|
44
|
+
loop do
|
45
|
+
file = files.pop
|
46
|
+
success = import_file(file, format)
|
47
|
+
if success
|
48
|
+
all_failed = false
|
49
|
+
else
|
50
|
+
all_success = false
|
51
|
+
end
|
52
|
+
break if files.empty?
|
53
|
+
end
|
54
|
+
if all_success
|
55
|
+
return "success"
|
56
|
+
elsif all_failed
|
57
|
+
return "failed"
|
58
|
+
else
|
59
|
+
return "partial"
|
60
|
+
end
|
61
|
+
rescue Interrupt => e
|
62
|
+
@log.error "Import interrupted."
|
63
|
+
return "failed"
|
70
64
|
end
|
71
65
|
end
|
72
|
-
|
66
|
+
|
67
|
+
private
|
68
|
+
|
73
69
|
# Imports a data master file. Legal formats are 'json' (default) and 'yaml'.
|
70
|
+
# Returns true if the import succeeded and false otherwise.
|
74
71
|
def import_file(file, format = 'json')
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
validator = @validators[type]
|
80
|
-
validator.validate(doc) unless validator.nil?
|
81
|
-
(@importers[type] || @simple_importer).import doc
|
82
|
-
end
|
72
|
+
@log.info "Importing file #{file}"
|
73
|
+
begin
|
74
|
+
# Include this in the begin/rescue as it can raise a JSON::ParserError
|
75
|
+
loader = @loaders[format]
|
83
76
|
|
84
|
-
|
77
|
+
fail ArgumentError, "Illegal format: #{format}" if loader.nil?
|
85
78
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
scheme = use_ssl ? "https" : "http"
|
91
|
-
base_uri = "#{scheme}://#{host}:#{port}/v1"
|
92
|
-
Seiso::Connector::UriFactoryV1.new base_uri
|
93
|
-
end
|
79
|
+
doc = loader.call file
|
80
|
+
type = doc['type']
|
81
|
+
get_importer(type).import doc
|
82
|
+
return true
|
94
83
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
84
|
+
# Rescue StandardError here, not Exception, since we want ctrl-c to stop the program.
|
85
|
+
rescue StandardError => e
|
86
|
+
@log.error "Failed to import file #{file}: #{e.message}"
|
87
|
+
|
88
|
+
# FIXME For now, just re-raise the exception, as we want to see where the bugs are.
|
89
|
+
return false
|
90
|
+
# raise e
|
91
|
+
end
|
102
92
|
end
|
103
93
|
|
104
|
-
def
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
94
|
+
def get_importer(type)
|
95
|
+
# TODO Do a cleaner impl here--one that doesn't violate the open-closed principle. Note that we *don't* want to
|
96
|
+
# create these eagerly, as each one involves an expensive initialization.
|
97
|
+
importer = @importers[type]
|
98
|
+
|
99
|
+
if importer.nil?
|
100
|
+
importer = case type
|
101
|
+
when 'data-centers'
|
102
|
+
Importers::DataCenterImporter.new(@v3_api, @rest_util, @resolver)
|
103
|
+
when 'environments'
|
104
|
+
Importers::EnvironmentImporter.new(@v3_api, @rest_util, @resolver)
|
105
|
+
when 'health-statuses'
|
106
|
+
Importers::HealthStatusImporter.new(@v3_api, @rest_util, @resolver)
|
107
|
+
when 'infrastructure-providers'
|
108
|
+
Importers::InfrastructureProviderImporter.new(@v3_api, @rest_util, @resolver)
|
109
|
+
when 'load-balancers'
|
110
|
+
Importers::LoadBalancerImporter.new(@v3_api, @rest_util, @resolver)
|
111
|
+
when 'machines'
|
112
|
+
Importers::MachineImporter.new(@v3_api, @rest_util, @resolver)
|
113
|
+
when 'nodes'
|
114
|
+
Importers::NodeImporter.new(@v3_api, @rest_util, @resolver)
|
115
|
+
when 'regions'
|
116
|
+
Importers::RegionImporter.new(@v3_api, @rest_util, @resolver)
|
117
|
+
when 'rotation-statuses'
|
118
|
+
Importers::RotationStatusImporter.new(@v3_api, @rest_util, @resolver)
|
119
|
+
when 'services'
|
120
|
+
Importers::ServiceImporter.new(@v3_api, @rest_util, @resolver)
|
121
|
+
when 'service-groups'
|
122
|
+
Importers::ServiceGroupImporter.new(@v3_api, @rest_util, @resolver)
|
123
|
+
when 'service-instances'
|
124
|
+
Importers::ServiceInstanceImporter.new(@v3_api, @rest_util, @resolver)
|
125
|
+
when 'service-types'
|
126
|
+
Importers::ServiceTypeImporter.new(@v3_api, @rest_util, @resolver)
|
127
|
+
when 'status-types'
|
128
|
+
Importers::StatusTypeImporter.new(@v3_api, @rest_util, @resolver)
|
129
|
+
else
|
130
|
+
raise ArgumentError, "Illegal type: #{type}"
|
131
|
+
end
|
132
|
+
@importers['type'] = importer
|
133
|
+
end
|
134
|
+
|
135
|
+
importer
|
112
136
|
end
|
113
137
|
end
|
114
138
|
end
|
@@ -1,31 +1,92 @@
|
|
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
|
-
|
1
|
+
require 'hyper_resource'
|
2
|
+
|
3
|
+
class Seiso::ImportMaster
|
4
|
+
|
5
|
+
# Base importer for type-specific importers.
|
6
|
+
#
|
7
|
+
# Subclasses must set the @repo_resource variable to point to the type's repository resource.
|
8
|
+
#
|
9
|
+
# Additionally, subclasses must provide the following type-specific callback implementations:
|
10
|
+
#
|
11
|
+
# - to_search_params(doc_item, context) : Returns a hash containing HTTP params for the resource search.
|
12
|
+
# - find_resource(search_params) : Takes the search params above and returns the corresponding resource.
|
13
|
+
#
|
14
|
+
# If the type in question has child resources (e.g., service instances have IP address roles and service instance
|
15
|
+
# ports), then subclasses should provide the following callback implementations to handle them:
|
16
|
+
#
|
17
|
+
# - context_for(parent_resource, parent_context) : Returns a new context to support importing child resources.
|
18
|
+
# - import_children_of(doc_item, context) : Imports the child resources.
|
19
|
+
#
|
20
|
+
# See service_instance_importer.rb for an example that includes all four callbacks.
|
21
|
+
#
|
22
|
+
# Author:: Willie Wheeler
|
23
|
+
# Copyright:: Copyright (c) 2014-2016 Expedia, Inc.
|
24
|
+
# License:: Apache 2.0
|
25
|
+
class Importers::BaseImporter
|
26
|
+
|
27
|
+
# Imports a list of document items into Seiso.
|
28
|
+
#
|
29
|
+
# - items : Items in document format
|
30
|
+
# - context : Import context
|
31
|
+
def import_items(doc_items, context)
|
32
|
+
# TODO Perform orphan deletion here, centrally, and recursively?
|
33
|
+
doc_items.each { |doc_item| import_item(doc_item, context) }
|
34
|
+
end
|
35
|
+
|
36
|
+
# Imports a single document item into Seiso. Returns the imported item's URI
|
37
|
+
#
|
38
|
+
# - item : Item in document format
|
39
|
+
# - context : Import context
|
40
|
+
def import_item(doc_item, context)
|
41
|
+
data = mapper.map(doc_item, context)
|
42
|
+
search_params = to_search_params(doc_item, context)
|
43
|
+
begin
|
44
|
+
resource = find_resource search_params
|
45
|
+
|
46
|
+
# In the Seiso API, PUT will leave any unspecified associations alone. So for example we can handle node health
|
47
|
+
# status and rotation status like this. When we have node build version, though, we will have to do something
|
48
|
+
# else, like turn it into an association or else PATCH here. [WLW]
|
49
|
+
rest_util.put(resource, data, search_params)
|
50
|
+
|
51
|
+
rescue HyperResource::ClientError => e
|
52
|
+
status = e.response.status
|
53
|
+
body = e.response.body
|
54
|
+
fail "Client error: status=#{status}, body=#{body}" unless status == 404
|
55
|
+
|
56
|
+
# Seiso API returns the created resource in the response body, so grab that.
|
57
|
+
# TODO Clean up this implementation. E.g. don't used nested exception handling, and don't create the logger
|
58
|
+
# here. [WLW]
|
59
|
+
begin
|
60
|
+
resource = rest_util.post(repo_resource, data, search_params)
|
61
|
+
rescue HyperResource::ClientError => e2
|
62
|
+
# HTTP 409 is typical. It happens when client references nonexistent entities.
|
63
|
+
status2 = e2.response.status
|
64
|
+
body2 = e2.response.body
|
65
|
+
log = Util::Logger.new "BaseImporter"
|
66
|
+
log.warn "Client error: status=#{status2}, body=#{body2}. Failed to import item."
|
67
|
+
return
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# ================================================================================================================
|
72
|
+
# FIXME For puts, this is putting the *old* resource on the context, which isn't what we want! [WLW]
|
73
|
+
# ================================================================================================================
|
74
|
+
|
75
|
+
if respond_to?(:import_children_of)
|
76
|
+
new_context = respond_to?(:context_for) ? context_for(resource, context) : {}
|
77
|
+
# FIXME For NodeIpAddress, this is returning a resource whose self link is /search/findByNodeNameAndIpAddress,
|
78
|
+
# and we can't PUT to that.
|
79
|
+
import_children_of(doc_item, new_context)
|
80
|
+
end
|
81
|
+
|
82
|
+
resource.href
|
83
|
+
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
|
87
|
+
attr_accessor :api
|
88
|
+
attr_accessor :rest_util
|
89
|
+
attr_accessor :mapper
|
90
|
+
attr_accessor :repo_resource
|
91
|
+
end
|
31
92
|
end
|