topological_inventory-core 1.0.0 → 1.1.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
  SHA256:
3
- metadata.gz: 63b1ec93fd5f7ebb021670fe8184db0945eed00385bafd718d3587aa25a171a7
4
- data.tar.gz: 37df3df19aa75c724464eb04b2639d07caa8078543435c9edee5e5fc3dc0aa24
3
+ metadata.gz: 14973202e680d9bf035a3c85d5ef856140bf11d934bfc488cbade6932c8239c1
4
+ data.tar.gz: 7493112f3e945f0d0e20cb86385add9f45f623e2825c08b8a3a4ac2a62994822
5
5
  SHA512:
6
- metadata.gz: 9bc2bd484466880aed1fc578bc5dc1f6b1578e288d430e386a089f505caa51d7585ba668dfcee0d4db5f04f58ec58bad2502db460f258ca2b6127284f05a08c0
7
- data.tar.gz: aa83f7119b8b1e2570c965a01fed2abda0d1218b14a0cba6b5f6b66ef97e8cfff6c1161902da72e6ee28aba2a8d66740bea61c0a3fb66f3494ae099401786e73
6
+ metadata.gz: '08de615e242bc7dd1ec6f4349386064855b947602986736a8095c3b4802adc0fbeabd5aeb03dcc3d965d3a882f8a989c646624482c45de5235a5457797cef871'
7
+ data.tar.gz: fb1e4895ac6ecb98b6564ed411f5107417b5b2f68ee5a1346312f59b32598065d46d300ed158750fa0df2e85868958e7e347b2f82818e00d39db01cf1a414869
@@ -77,6 +77,9 @@ class Source < ApplicationRecord
77
77
  has_many :volume_attachments, :through => :volumes
78
78
  has_many :volume_types
79
79
 
80
+ # Tasks
81
+ has_many :tasks
82
+
80
83
  ALLOWED_REFRESH_STATUS_VALUES = ["deployed", "quota_limited"].freeze
81
84
  validates :refresh_status, :allow_nil => true, :inclusion => {:in => ALLOWED_REFRESH_STATUS_VALUES, :message => "%{value} is not included in #{ALLOWED_REFRESH_STATUS_VALUES}"}
82
85
  end
@@ -1,5 +1,6 @@
1
1
  class Task < ApplicationRecord
2
2
  belongs_to :tenant
3
+ belongs_to :source, :optional => true
3
4
 
4
5
  validates :state, :inclusion => {:in => %w(pending queued running completed)}
5
6
  validates :status, :inclusion => {:in => %w(ok warn error)}
@@ -0,0 +1,20 @@
1
+ default: &default
2
+ adapter: postgresql
3
+ encoding: utf8
4
+ username: root
5
+ pool: 5
6
+ wait_timeout: 5
7
+ min_messages: warning
8
+
9
+ development:
10
+ <<: *default
11
+ database: topological_inventory_core_development
12
+ min_messages: notice
13
+
14
+ test:
15
+ <<: *default
16
+ database: topological_inventory_core_test
17
+
18
+ production:
19
+ <<: *default
20
+ database: topological_inventory_core_production
@@ -0,0 +1,10 @@
1
+ class AddTargetAndSourceToTask < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :tasks, :target_source_ref, :string, :null => true
4
+ add_column :tasks, :target_type, :string, :null => true
5
+
6
+ add_index :tasks, %i[target_type target_source_ref]
7
+
8
+ add_reference :tasks, :source, :index => true, :null => true, :foreign_key => { :on_delete => :nullify }
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ class ExtractTasksSourceRefFromContext < ActiveRecord::Migration[5.2]
2
+ def up
3
+ Task.find_each do |task|
4
+ source_ref = task.context&.dig('service_instance', 'source_ref')
5
+ next if source_ref.nil?
6
+
7
+ say "Task: #{task.id}, Source ref: #{source_ref}"
8
+ source_id = task.context&.dig('service_instance', 'source_id')
9
+
10
+ task.update_attributes(:target_source_ref => source_ref.to_s,
11
+ :target_type => 'ServiceInstance',
12
+ :source_id => source_id)
13
+ end
14
+ end
15
+
16
+ def down
17
+ Task.update_all(:source_id => nil, :target_type => nil, :target_source_ref => nil)
18
+ end
19
+ end
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 2020_03_17_082640) do
13
+ ActiveRecord::Schema.define(version: 2020_04_14_123737) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -1187,6 +1187,11 @@ ActiveRecord::Schema.define(version: 2020_03_17_082640) do
1187
1187
  t.datetime "completed_at"
1188
1188
  t.datetime "created_at", null: false
1189
1189
  t.datetime "updated_at", null: false
1190
+ t.string "target_source_ref"
1191
+ t.string "target_type"
1192
+ t.bigint "source_id"
1193
+ t.index ["source_id"], name: "index_tasks_on_source_id"
1194
+ t.index ["target_type", "target_source_ref"], name: "index_tasks_on_target_type_and_target_source_ref"
1190
1195
  t.index ["tenant_id"], name: "index_tasks_on_tenant_id"
1191
1196
  end
1192
1197
 
@@ -1561,6 +1566,7 @@ ActiveRecord::Schema.define(version: 2020_03_17_082640) do
1561
1566
  add_foreign_key "subscriptions", "tenants", on_delete: :cascade
1562
1567
  add_foreign_key "tags", "refresh_state_parts", on_delete: :nullify
1563
1568
  add_foreign_key "tags", "tenants", on_delete: :cascade
1569
+ add_foreign_key "tasks", "sources", on_delete: :nullify
1564
1570
  add_foreign_key "tasks", "tenants", on_delete: :cascade
1565
1571
  add_foreign_key "vm_security_groups", "refresh_state_parts", on_delete: :nullify
1566
1572
  add_foreign_key "vm_security_groups", "security_groups", on_delete: :cascade
@@ -1,5 +1,5 @@
1
1
  module TopologicalInventory
2
2
  module Core
3
- VERSION = '1.0.0'
3
+ VERSION = '1.1.0'
4
4
  end
5
5
  end
@@ -65,6 +65,7 @@ module TopologicalInventory
65
65
  add_volume_attachments
66
66
  add_cross_link_vms
67
67
  add_vm_security_groups
68
+ add_service_instance_tasks
68
69
  end
69
70
 
70
71
  def targeted?
@@ -123,6 +124,106 @@ module TopologicalInventory
123
124
  end
124
125
  end
125
126
 
127
+ def add_service_instance_tasks
128
+ add_collection(:service_instance_tasks, inventory_collection_builder, {}, {:without_model_class => true}) do |builder|
129
+ add_default_properties(builder)
130
+ add_default_values(builder)
131
+
132
+ builder.add_dependency_attributes(
133
+ :service_instances => ->(persister) { [persister.collections[:service_instances]] }
134
+ )
135
+
136
+ save_block = lambda do |source, tasks_collection|
137
+ service_instance_tasks_custom_save(source, tasks_collection)
138
+ end
139
+
140
+ builder.add_properties(:custom_save_block => save_block)
141
+ end
142
+ end
143
+
144
+ def service_instance_tasks_custom_save(source, tasks_collection)
145
+ service_instance_collection = tasks_collection.dependency_attributes[:service_instances]&.first
146
+ src_refs = service_instance_collection&.data.to_a.collect { |inventory_object| inventory_object.source_ref }
147
+ return if src_refs.blank?
148
+
149
+ # Updating Tasks
150
+ # service_instance_tasks_update_effective()
151
+ service_instance_tasks_update_ineffective(source, src_refs)
152
+ end
153
+
154
+ def task_update_values(svc_instance_id, external_url, status, finished_timestamp)
155
+ {
156
+ :state => finished_timestamp.blank? ? 'running' : 'completed',
157
+ :status => %w[error failed].include?(status) ? 'error' : 'ok', # TODO: ansible-tower specific, normalize in collector
158
+ :context => {
159
+ :remote_status => status,
160
+ :service_instance => {
161
+ :id => svc_instance_id,
162
+ :url => external_url
163
+ }
164
+ }
165
+ }
166
+ end
167
+
168
+ # This method is updating one by one using ActiveRecord
169
+ def service_instance_tasks_update_ineffective(source, svc_instances_source_ref)
170
+ service_instances = ServiceInstance.where(:source_id => source.id, :source_ref => svc_instances_source_ref)
171
+ tasks_by_source_ref = Task.where(:state => 'running', :target_type => 'ServiceInstance', :source_id => source.id, :target_source_ref => service_instances.pluck(:source_ref)).index_by(&:target_source_ref)
172
+
173
+ service_instances.select(:id, :external_url, :source_ref, :extra).find_in_batches do |group|
174
+ ActiveRecord::Base.transaction do
175
+ group.each do |svc_instance|
176
+ next if tasks_by_source_ref[svc_instance.source_ref].nil?
177
+
178
+ values = task_update_values(svc_instance.id, svc_instance.external_url, svc_instance.extra['status'], svc_instance.extra['finished'])
179
+ tasks_by_source_ref[svc_instance.source_ref].update(values)
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ # This method is bulk updating by raw SQL query
186
+ def service_instance_tasks_update_effective
187
+ # Get running tasks
188
+ tasks_values = Task.where(:state => 'running', :target_type => 'ServiceInstance', :source_id => source.id)
189
+ .pluck(:id, :target_source_ref)
190
+ tasks_id, tasks_source_ref = [], []
191
+ tasks_values.each do |attrs|
192
+ tasks_id << attrs[0]
193
+ tasks_source_ref << attrs[1]
194
+ end
195
+
196
+ # Load saved service instances (IDs needed)
197
+ service_instances_values = ServiceInstance.where(:source_ref => tasks_source_ref).pluck(:id, :external_url, :source_ref, Arel.sql("extra->'finished'"), Arel.sql("extra->'status'"))
198
+ return if service_instances_values.blank?
199
+
200
+ sql_update_values = []
201
+
202
+ # Preparing SQL update values from loaded ServiceInstances
203
+ service_instances_values.each do |attrs|
204
+ id, external_url, source_ref, finished_timestamp, status = attrs[0], attrs[1], attrs[2], attrs[3], attrs[4]
205
+
206
+ values = task_update_values(id, external_url, status, finished_timestamp)
207
+ sql_update_values << "('#{source_ref}', '#{values[:state]}', '#{values[:status]}', '#{values[:context].to_json}'::json)"
208
+ end
209
+
210
+ # Update query.
211
+ # Pairs records by `Task.target_type` and `Task.target_source_ref`
212
+ sql = <<SQL
213
+ UPDATE tasks AS t SET
214
+ state = c.state,
215
+ status = c.status,
216
+ context = c.context
217
+ FROM (VALUES :values
218
+ ) AS c(source_ref, state, status, context)
219
+ WHERE t.target_source_ref = c.source_ref
220
+ AND t.target_type = 'ServiceInstance';
221
+ SQL
222
+ sql.sub!(':values', sql_update_values.join(','))
223
+
224
+ ActiveRecord::Base.connection.execute(sql)
225
+ end
226
+
126
227
  def add_vm_security_groups
127
228
  add_collection(:vm_security_groups) do |builder|
128
229
  add_default_properties(builder, manager_ref: [:vm, :security_group])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: topological_inventory-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Grare
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-16 00:00:00.000000000 Z
11
+ date: 2020-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acts_as_tenant
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.4
33
+ version: 0.3.5
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.3.4
40
+ version: 0.3.5
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: manageiq-messaging
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -249,6 +249,7 @@ files:
249
249
  - app/models/volume_type.rb
250
250
  - app/views/layouts/topological_inventory/application.html.erb
251
251
  - config/database.dev.yml
252
+ - config/database.yml
252
253
  - db/migrate/20180919170553_add_sources_and_endpoints.rb
253
254
  - db/migrate/20180927171624_add_container_models.rb
254
255
  - db/migrate/20180927205317_add_service_catalog_models.rb
@@ -351,6 +352,8 @@ files:
351
352
  - db/migrate/20200313124806_remove_extraneous_index_from_service_credential_join_tables.rb
352
353
  - db/migrate/20200313141215_add_refresh_state_part_to_persisted_models.rb
353
354
  - db/migrate/20200317082640_add_tracking_timestamps_to_refresh_state.rb
355
+ - db/migrate/20200403114310_add_target_and_source_to_task.rb
356
+ - db/migrate/20200414123737_extract_tasks_source_ref_from_context.rb
354
357
  - db/schema.rb
355
358
  - db/seeds.rb
356
359
  - lib/tasks/topological_inventory_tasks.rake