foreman_scc_manager 1.8.6 → 1.8.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -1
  3. data/app/controllers/api/v2/scc_accounts_controller.rb +1 -1
  4. data/app/controllers/scc_accounts_controller.rb +1 -1
  5. data/app/lib/actions/scc_manager/subscribe_product.rb +19 -7
  6. data/app/lib/actions/scc_manager/sync.rb +5 -5
  7. data/app/lib/actions/scc_manager/sync_products.rb +10 -13
  8. data/app/lib/actions/scc_manager/sync_repositories.rb +9 -13
  9. data/app/models/scc_account.rb +57 -10
  10. data/app/models/scc_repository.rb +7 -9
  11. data/app/views/scc_accounts/show.html.erb +5 -0
  12. data/db/migrate/20210205082733_add_subscription_valid_to_scc_products_and_repos.rb +6 -0
  13. data/db/migrate/20210210104407_add_root_repository_id_to_scc_repository.rb +6 -0
  14. data/db/migrate/20210224095050_connect_katello_root_repository_to_scc_repository.rb +28 -0
  15. data/db/migrate/20210713092440_add_permissions.rb +19 -0
  16. data/lib/foreman_scc_manager/engine.rb +4 -2
  17. data/lib/foreman_scc_manager/version.rb +1 -1
  18. data/locale/de/LC_MESSAGES/foreman_scc_manager.mo +0 -0
  19. data/locale/de/foreman_scc_manager.edit.po +574 -0
  20. data/locale/de/foreman_scc_manager.po +40 -21
  21. data/locale/de/foreman_scc_manager.po.time_stamp +0 -0
  22. data/locale/en/foreman_scc_manager.edit.po +566 -0
  23. data/locale/en/foreman_scc_manager.po +21 -3
  24. data/locale/en/foreman_scc_manager.po.time_stamp +0 -0
  25. data/locale/foreman_scc_manager.pot +62 -43
  26. data/test/controllers/api/v2/scc_accounts_test.rb +46 -1
  27. data/test/controllers/scc_accounts_controller_test.rb +51 -1
  28. data/test/fixtures/models/scc_accounts.yml +2 -0
  29. data/test/fixtures/models/scc_products.yml +4 -0
  30. data/test/models/scc_account_test.rb +6 -0
  31. data/test/unit/access_permissions_test.rb +16 -0
  32. metadata +12 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a0b1fc3df2a088cefb4344e848995955fb81a5478cf4500268c68f32ccf0bec
4
- data.tar.gz: ae3c19f91491ba06228c59f6314e28d5c8525d8936e89c5a82af092a71dd4e85
3
+ metadata.gz: d9bb11cd54075948f57fe205b39e75e2d2bac3092cdcd3c1f15e9101bfaa0b3c
4
+ data.tar.gz: 61351f372d614b5de85b9ec6f490f08bea0c7b1848b06b66b89ca78fd6b4ca29
5
5
  SHA512:
6
- metadata.gz: 57f473572bfc7342b44765343b168e94bb55ba479bb17d7a9236703bcb5cb7f2cad615b16d76934790a739037eb5b724e70ff637c17e7d95aaaa6dc993eb3bd2
7
- data.tar.gz: 6569d327e0ccb6c251a823ae3af6a3bd1a40d44edc9878fd4b538303ec242a8f594dffd0e8fb951ae371c8b22ae13f16a0120ac78a6f9cb4a5bf2dabd33781fb
6
+ metadata.gz: 8eb54567950e62fef53342af59aa070cf0f45c31832c8869b181250c20953b5850024ded8792ce2abd7a2c947b6317d86ac99a5038f97ffdb61f67728a2a50b8
7
+ data.tar.gz: ea314767654f27ab0d26097ccc235fbf83fb426e46ef242284f0da8572cc1dcdfe44d2966b471a177c45bf8fbe99c857105b653f61883e39441b021cf9f67c48
data/README.md CHANGED
@@ -13,6 +13,7 @@ for how to install Foreman plugins
13
13
 
14
14
  | Foreman Version | Katello Version | Plugin Version |
15
15
  | --------------- | --------------- | -------------- |
16
+ | 2.3 | 3.18 | ~> 1.8.9 |
16
17
  | 2.1 | 3.16 | ~> 1.8.5 |
17
18
  | 2.0 | 3.16 | ~> 1.8.4 |
18
19
  | 1.24 | 3.14 | ~> 1.8.0 |
@@ -28,13 +29,16 @@ for how to install Foreman plugins
28
29
  ## Documentation
29
30
  The plugin documentation can be found at https://docs.orcharhino.com/sources/management_ui/the_content_menu/suse_subscriptions.html.
30
31
 
32
+ A Hammer CLI extension is available for this plugin:
33
+ https://github.com/ATIX-AG/hammer-cli-foreman-scc-manager
34
+
31
35
  ## Contributing
32
36
 
33
37
  Fork and send a Pull Request. Thanks!
34
38
 
35
39
  ## Copyright
36
40
 
37
- Copyright (c) 2017 ATIX AG - http://www.atix.de
41
+ Copyright (c) 2021 ATIX AG - http://www.atix.de
38
42
 
39
43
  This program is free software: you can redistribute it and/or modify
40
44
  it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@ module Api
35
35
  param :base_url, String, :required => false, :desc => N_('URL of SUSE for scc_account')
36
36
  param :interval, ['never', 'daily', 'weekly', 'monthy'], :desc => N_('Interval for syncing scc_account')
37
37
  param :sync_date, String, :desc => N_('Date and time relative to which the sync interval is run')
38
- param :katello_gpg_key_id, :identifier, :required => false, :desc => N_('Associated gpg key of scc_account')
38
+ param :katello_gpg_key_id, :identifier, :required => false, :desc => N_('Associated GPG key of scc_account')
39
39
  end
40
40
  end
41
41
 
@@ -2,7 +2,7 @@ class SccAccountsController < ApplicationController
2
2
  helper_method :scc_filtered_products
3
3
  before_action :find_organization
4
4
  before_action :find_resource, only: %i[show edit update destroy sync bulk_subscribe]
5
- before_action :find_available_gpg_keys, only: %i[new edit]
5
+ before_action :find_available_gpg_keys, only: %i[new edit update create]
6
6
  include Foreman::Controller::AutoCompleteSearch
7
7
 
8
8
  # GET /scc_accounts
@@ -12,24 +12,34 @@ module Actions
12
12
  :product_description => scc_product.pretty_description,
13
13
  :organization_id => scc_product.organization.id,
14
14
  :gpg_key => scc_product.scc_account.katello_gpg_key_id)
15
+ katello_repos = {}
15
16
  scc_product.scc_repositories.each do |repo|
16
17
  arch = scc_product.arch || 'noarch'
17
- plan_action(CreateRepository,
18
- :product_id => product_create_action.output[:product_id],
19
- :uniq_name => repo.uniq_name(scc_product),
20
- :pretty_repo_name => repo.pretty_name,
21
- :url => repo.full_url,
22
- :arch => arch)
18
+ repo_create_action = plan_action(CreateRepository,
19
+ :product_id => product_create_action.output[:product_id],
20
+ :uniq_name => repo.uniq_name(scc_product),
21
+ :pretty_repo_name => repo.pretty_name,
22
+ :url => repo.full_url,
23
+ :arch => arch)
24
+ katello_repos[repo.id] = repo_create_action.output[:katello_root_repository_id]
23
25
  end
26
+ # connect action to resource (=> make parameters accessable in input)
24
27
  action_subject(scc_product, product_id: product_create_action.output[:product_id])
28
+ input.update(katello_repos: katello_repos)
25
29
  plan_self
26
30
  end
27
31
  end
28
32
 
29
33
  def finalize
34
+ # connect Scc products and Katello products
30
35
  scc_product = SccProduct.find(input[:scc_product][:id])
31
36
  product = ::Katello::Product.find(input[:product_id])
32
37
  scc_product.update!(product: product)
38
+ # extract Katello repo ids from input hash and store to database
39
+ input[:katello_repos].each do |scc_repo_id, katello_root_repository_id|
40
+ scc_repo = SccRepository.find(scc_repo_id)
41
+ scc_repo.update!(katello_root_repository_id: katello_root_repository_id)
42
+ end
33
43
  end
34
44
 
35
45
  def humanized_name
@@ -74,7 +84,9 @@ module Actions
74
84
  repository = product.add_repo(repo_param)
75
85
  repository.mirror_on_sync = true
76
86
  repository.verify_ssl_on_sync = true
77
- trigger(::Actions::Katello::Repository::CreateRoot, repository)
87
+ trigger(::Actions::Katello::Repository::CreateRoot, repository).tap do
88
+ output[:katello_root_repository_id] = repository.id
89
+ end
78
90
  end
79
91
  end
80
92
  end
@@ -1,21 +1,21 @@
1
1
  module Actions
2
2
  module SccManager
3
+ # for dynflow documentation see here: https://dynflow.github.io/documentation/
3
4
  class Sync < Actions::EntryAction
4
5
  def plan(scc_account)
5
6
  ::Foreman::Logging.logger('foreman_scc_manager')
6
7
  .info("Initiating 'sync' for SccAccount '#{scc_account.name}'.")
7
8
  action_subject(scc_account)
8
9
  sequence do
9
- sync_repo_action = plan_action(::Actions::SccManager::SyncRepositories, scc_account)
10
- sync_prod_action = plan_action(::Actions::SccManager::SyncProducts, scc_account)
11
- plan_self(repo_status: sync_repo_action.output[:status], prod_status: sync_prod_action.output[:status])
10
+ plan_action(::Actions::SccManager::SyncRepositories, scc_account)
11
+ plan_action(::Actions::SccManager::SyncProducts, scc_account)
12
+ plan_self
12
13
  end
13
14
  end
14
15
 
15
16
  def finalize
17
+ # this is only executed if run actions of SyncRepositories and SyncProducts were successful
16
18
  scc_account = SccAccount.find(input[:scc_account][:id])
17
- raise 'Updating failed' unless input[:repo_status] == 'SUCCESS' && input[:prod_status] == 'SUCCESS'
18
-
19
19
  scc_account.update! synced: Time.current
20
20
  end
21
21
 
@@ -13,22 +13,19 @@ module Actions
13
13
  end
14
14
 
15
15
  def run
16
- output[:status] = 'SUCCESS'
17
- begin
18
- products = ::SccManager.get_scc_data(input.fetch(:base_url),
19
- '/connect/organizations/products',
20
- input.fetch(:login),
21
- decrypt_field(input.fetch(:password)))
22
- output[:data] = ::SccManager.sanitize_products(products).values
23
- rescue StandardError => e
24
- ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Products: #{e}"
25
- output[:error] = e.to_s
26
- output[:status] = 'FAILURE'
27
- end
16
+ products = ::SccManager.get_scc_data(input.fetch(:base_url),
17
+ '/connect/organizations/products',
18
+ input.fetch(:login),
19
+ decrypt_field(input.fetch(:password)))
20
+ output[:data] = ::SccManager.sanitize_products(products).values
21
+ rescue StandardError => e
22
+ ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Products: #{e}"
23
+ error! e.to_s
28
24
  end
29
25
 
30
26
  def finalize
31
- SccAccount.find(input.fetch(:id)).update_scc_products(output.fetch(:data)) if output[:status] == 'SUCCESS'
27
+ # this is only executed if 'run' succeeds
28
+ SccAccount.find(input.fetch(:id)).update_scc_products(output.fetch(:data))
32
29
  end
33
30
 
34
31
  def rescue_strategy
@@ -12,22 +12,18 @@ module Actions
12
12
  end
13
13
 
14
14
  def run
15
- output[:status] = 'IN PROGRESS'
16
- begin
17
- output[:data] = ::SccManager.get_scc_data(input[:base_url],
18
- '/connect/organizations/repositories',
19
- input[:login],
20
- decrypt_field(input[:password]))
21
- output[:status] = 'SUCCESS'
22
- rescue StandardError => e
23
- ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Repositories: #{e}"
24
- output[:error] = e.to_s
25
- output[:status] = 'FAILURE'
26
- end
15
+ output[:data] = ::SccManager.get_scc_data(input[:base_url],
16
+ '/connect/organizations/repositories',
17
+ input[:login],
18
+ decrypt_field(input[:password]))
19
+ rescue StandardError => e
20
+ ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Repositories: #{e}"
21
+ error! e.to_s
27
22
  end
28
23
 
29
24
  def finalize
30
- SccAccount.find(input[:scc_account][:id]).update_scc_repositories(output[:data]) if output[:status] == 'SUCCESS'
25
+ # this is only executed if 'run' succeeds
26
+ SccAccount.find(input[:scc_account][:id]).update_scc_repositories(output[:data])
31
27
  end
32
28
 
33
29
  def rescue_strategy
@@ -45,12 +45,7 @@ class SccAccount < ApplicationRecord
45
45
  end
46
46
 
47
47
  def sync_date_is_valid_datetime
48
- errors.add(:sync_date, 'must be a valid datetime') if interval != NEVER &&
49
- sync_date.present? &&
50
- !sync_date.respond_to?(:min) &&
51
- !sync_date.respond_to?(:hour) &&
52
- !sync_date.respond_to?(:wday) &&
53
- !sync_date.respond_to?(:day)
48
+ errors.add(:sync_date, 'must be a valid datetime') if interval != NEVER && sync_date.blank?
54
49
  end
55
50
 
56
51
  def to_s
@@ -104,7 +99,7 @@ class SccAccount < ApplicationRecord
104
99
  end
105
100
 
106
101
  def add_recurring_logic(sync_date, interval)
107
- sd = sync_date
102
+ sd = sync_date.presence || Time.now
108
103
 
109
104
  raise _('Interval cannot be nil') if interval.nil?
110
105
 
@@ -176,6 +171,8 @@ class SccAccount < ApplicationRecord
176
171
 
177
172
  def update_scc_repositories(upstream_repositories)
178
173
  upstream_repo_ids = []
174
+ # initially invalidate all repositories and validate them during update
175
+ invalidated_repos = invalidate_subscription_status(scc_repositories)
179
176
  # import repositories
180
177
  upstream_repositories.each do |ur|
181
178
  cached_repository = scc_repositories.find_or_initialize_by(scc_id: ur['id'])
@@ -187,11 +184,21 @@ class SccAccount < ApplicationRecord
187
184
  cached_repository.installer_updates = ur['installer_updates']
188
185
  # should be called after all attributes are set in case of dependencies (currently: description)
189
186
  cached_repository.name = cached_repository.pretty_name
187
+ cached_repository.subscription_valid = true
190
188
  cached_repository.save!
191
189
  upstream_repo_ids << ur['id']
190
+ # set invalidated record to true, if exists
191
+ invalidated_repos = revalidate_subscription_status(invalidated_repos, ur[id])
192
192
  end
193
193
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_repo_ids.length} repositories"
194
- # delete repositories beeing removed upstream
194
+
195
+ # all scc repos that are kept but not available upstream need to be marked invalid
196
+ # subscription_valid can be set to nil
197
+ to_invalidate = invalidated_repos.select { |ir| ir.katello_root_repository_id.present? && !ir.subscription_valid }
198
+ ::Foreman::Logging.logger('foreman_scc_manager').debug "Invalidating #{to_invalidate.count} expired repositories"
199
+ invalidate_subscription_status(to_invalidate, true)
200
+
201
+ # delete repositories being removed upstream and that are not subscribed to
195
202
  to_delete = scc_repositories.where.not(scc_id: upstream_repo_ids)
196
203
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old repositories"
197
204
  to_delete.destroy_all
@@ -199,6 +206,8 @@ class SccAccount < ApplicationRecord
199
206
 
200
207
  def update_scc_products(upstream_products)
201
208
  upstream_product_ids = []
209
+ # initially invalidate all products and validate them during update
210
+ invalidated_products = invalidate_subscription_status(scc_products)
202
211
  # import products
203
212
  upstream_products.each do |up|
204
213
  cached_product = scc_products.find_or_initialize_by(scc_id: up['id'])
@@ -212,12 +221,22 @@ class SccAccount < ApplicationRecord
212
221
  # name should be set after friendly_name because it depends on friendly_name
213
222
  cached_product.name = cached_product.pretty_name
214
223
  cached_product.description = cached_product.pretty_description
224
+ cached_product.subscription_valid = true
215
225
  cached_product.save!
216
226
  upstream_product_ids << up['id']
227
+ # set invalidated record to true, if exists
228
+ invalidated_products = revalidate_subscription_status(invalidated_products, up['id'])
217
229
  end
218
230
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_product_ids.length} products"
219
- # delete products beeing removed upstream
220
- to_delete = scc_products.where.not(scc_id: upstream_product_ids)
231
+
232
+ # all scc products that are kept but not available upstream need to be marked invalid
233
+ # subscription_valid can be set to nil
234
+ to_invalidate = invalidated_products.select { |ip| ip.product_id.present? && !ip.subscription_valid }
235
+ ::Foreman::Logging.logger('foreman_scc_manager').debug "Invalidating #{to_invalidate.count} expired products"
236
+ invalidate_subscription_status(to_invalidate, true)
237
+
238
+ # delete products being removed upstream and that are not subscribed to
239
+ to_delete = scc_products.where.not(scc_id: upstream_product_ids).where(product_id: nil)
221
240
  ::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old products"
222
241
  to_delete.destroy_all
223
242
  # rewire product to product relationships
@@ -230,4 +249,32 @@ class SccAccount < ApplicationRecord
230
249
  end
231
250
  end
232
251
  end
252
+
253
+ # validate the subscription status of a product/repo
254
+ # no saving to database
255
+ # params: elements: scc repos or products, Array or ActiveRecord_(*)
256
+ # scc_id: scc_id of the element that should be revalidated
257
+ # return: elements where for the element with scc_id subscription_valid is true
258
+ def revalidate_subscription_status(elements, scc_id)
259
+ return nil if elements.nil?
260
+
261
+ revalidate = elements.find { |e| e.scc_id == scc_id }
262
+ revalidate.subscription_valid = true unless revalidate.nil?
263
+ # return modified list
264
+ elements
265
+ end
266
+
267
+ # set all products/repos invalid
268
+ # params: items_to_invalidate: ActiveRecord_(*)
269
+ # save_record: store in database or not (default)
270
+ # return: ActiveRecord elements with invalidated subscription status
271
+ def invalidate_subscription_status(items_to_invalidate, save_record = false)
272
+ if items_to_invalidate.present?
273
+ items_to_invalidate.each do |inv|
274
+ inv.subscription_valid = false
275
+ inv.save! if save_record
276
+ end
277
+ end
278
+ items_to_invalidate
279
+ end
233
280
  end
@@ -4,6 +4,7 @@ class SccRepository < ApplicationRecord
4
4
  self.include_root_in_json = false
5
5
 
6
6
  belongs_to :scc_account
7
+ belongs_to :katello_root_repository, class_name: 'Katello::RootRepository'
7
8
  has_one :organization, through: :scc_account
8
9
  has_and_belongs_to_many :scc_products
9
10
 
@@ -12,7 +13,7 @@ class SccRepository < ApplicationRecord
12
13
  end
13
14
 
14
15
  def uniq_name(scc_product)
15
- scc_product.uniq_name + ' ' + description
16
+ scc_product.scc_id.to_s + ' ' + description
16
17
  end
17
18
 
18
19
  def pretty_name
@@ -21,13 +22,10 @@ class SccRepository < ApplicationRecord
21
22
 
22
23
  def token_changed_callback
23
24
  User.current ||= User.anonymous_admin
24
- scc_products.where.not(product: nil).find_each do |sp|
25
- reponame = uniq_name(sp)
26
- repository = sp.product.root_repositories.find_by(name: reponame)
27
- unless repository.nil? || repository.url == full_url
28
- ::Foreman::Logging.logger('foreman_scc_manager').info "Update URL-token for repository '#{reponame}'."
29
- ForemanTasks.async_task(::Actions::Katello::Repository::Update, repository, url: full_url)
30
- end
31
- end
25
+ repo = self.katello_root_repository
26
+ return if repo.nil? || repo.url == full_url
27
+
28
+ ::Foreman::Logging.logger('foreman_scc_manager').info "Update URL-token for repository '#{repo.name}'."
29
+ ForemanTasks.async_task(::Actions::Katello::Repository::Update, repo, url: full_url)
32
30
  end
33
31
  end
@@ -12,6 +12,11 @@
12
12
  <%= check_box_tag("scc_account[scc_subscribe_product_ids][]", scc_product.id, false) %>
13
13
  <%= scc_product.pretty_name %>
14
14
  <% end %>
15
+ <% unless scc_product.subscription_valid? %>
16
+ <span style="color:red">
17
+ <%= _('(WARNING: Please check your SUSE subscription)') %>
18
+ </span>
19
+ <% end %>
15
20
  </span>
16
21
  <% if scc_product.scc_extensions.any? %>
17
22
  <ul style='padding-left: 20px;'>
@@ -0,0 +1,6 @@
1
+ class AddSubscriptionValidToSccProductsAndRepos < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :scc_products, :subscription_valid, :boolean, null: true
4
+ add_column :scc_repositories, :subscription_valid, :boolean, null: true
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class AddRootRepositoryIdToSccRepository < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :scc_repositories, :katello_root_repository_id, :integer, index: true, null: true
4
+ add_foreign_key :scc_repositories, :katello_root_repositories, column: :katello_root_repository_id, on_delete: :nullify
5
+ end
6
+ end
@@ -0,0 +1,28 @@
1
+ class ConnectKatelloRootRepositoryToSccRepository < ActiveRecord::Migration[5.2]
2
+ # add SccRepository class, because original one triggers the token_changed_callback
3
+ # which tried to update Katello root repositories
4
+ class SccRepository < ApplicationRecord
5
+ belongs_to :katello_root_repository, class_name: 'Katello::RootRepository'
6
+ end
7
+
8
+ class SccProduct < ApplicationRecord
9
+ belongs_to :product, class_name: 'Katello::Product'
10
+ has_and_belongs_to_many :scc_repositories
11
+ end
12
+
13
+ def up
14
+ SccProduct.where.not(product_id: nil).each do |scc_p|
15
+ # extract all katello root repository ids from subscribed products
16
+ katello_root_repositories = scc_p.product.root_repositories.map { |r| [r.label, r.id] }.to_h
17
+ # match scc repository and katello repository names
18
+ # katello repository name can be
19
+ # 1) equal to scc repo name
20
+ # 2) equal to scc product id + scc product name + scc repo name
21
+ scc_p.scc_repositories.each do |scc_r|
22
+ katello_root_repositories.each do |katello_label, katello_id|
23
+ scc_r.update!(katello_root_repository_id: katello_id) if katello_label.end_with?(::Katello::Util::Model.labelize(scc_r.name))
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,19 @@
1
+ class AddPermissions < ActiveRecord::Migration[6.0]
2
+ PERMISSIONS = [
3
+ { 'name' => 'view_scc_products', 'resource_type' => 'SccProduct' },
4
+ { 'name' => 'subscribe_scc_products', 'resource_type' => 'SccProduct' },
5
+ { 'name' => 'test_connection_scc_accounts', 'resource_type' => 'SccAccount' }
6
+ ].freeze
7
+
8
+ def up
9
+ PERMISSIONS.each do |p|
10
+ Permission.find_or_create_by(:name => p['name'], :resource_type => p['resource_type'])
11
+ end
12
+ end
13
+
14
+ def down
15
+ PERMISSIONS.each do |p|
16
+ Permission.where(:name => p['name']).destroy_all
17
+ end
18
+ end
19
+ end
@@ -22,8 +22,10 @@ module ForemanSccManager
22
22
 
23
23
  initializer 'foreman_scc_manager.register_plugin', :before => :finisher_hook do |_app|
24
24
  Foreman::Plugin.register :foreman_scc_manager do
25
- requires_foreman '>= 1.22'
26
- requires_foreman_plugin 'katello', '>= 3.12.0'
25
+ requires_foreman '>= 2.1'
26
+ requires_foreman_plugin 'katello', '>= 3.16.0'
27
+
28
+ precompile_assets 'foreman_scc_manager/scc_accounts.js'
27
29
 
28
30
  apipie_documented_controllers ["#{ForemanSccManager::Engine.root}/app/controllers/api/v2/*.rb"]
29
31