topological_inventory-core 1.0.0 → 1.1.0

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 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