foreman_scc_manager 1.8.1 → 1.8.6

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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -0
  3. data/app/controllers/api/v2/scc_accounts_controller.rb +9 -7
  4. data/app/controllers/scc_accounts_controller.rb +30 -4
  5. data/app/lib/actions/scc_manager/subscribe_product.rb +9 -8
  6. data/app/lib/actions/scc_manager/sync_products.rb +8 -7
  7. data/app/lib/actions/scc_manager/sync_repositories.rb +8 -7
  8. data/app/lib/scc_manager.rb +2 -2
  9. data/app/models/scc_account.rb +15 -8
  10. data/app/models/scc_product.rb +20 -2
  11. data/app/models/scc_repository.rb +4 -0
  12. data/app/views/scc_accounts/_form.html.erb +6 -0
  13. data/app/views/scc_accounts/index.html.erb +4 -3
  14. data/app/views/scc_accounts/show.html.erb +8 -4
  15. data/db/migrate/20200520281300_fix_scc_permissions.rb +22 -0
  16. data/db/migrate/20201119084201_add_gpg_key_to_scc_account.rb +6 -0
  17. data/lib/foreman_scc_manager/engine.rb +36 -25
  18. data/lib/foreman_scc_manager/version.rb +1 -1
  19. data/lib/tasks/test.rake +1 -1
  20. data/locale/foreman_scc_manager.pot +8 -0
  21. data/test/controllers/api/v2/scc_accounts_test.rb +9 -3
  22. data/test/controllers/scc_accounts_controller_test.rb +104 -0
  23. data/test/controllers/scc_accounts_controller_test2.rb +51 -0
  24. data/test/fixtures/models/scc_extendings.yml +6 -0
  25. data/test/fixtures/models/scc_products.yml +26 -2
  26. data/test/fixtures/models/scc_repositories.yml +29 -0
  27. data/test/models/scc_account_test.rb +64 -0
  28. data/test/models/scc_product_test.rb +69 -1
  29. data/test/support/fixtures_support.rb +3 -2
  30. data/test/test_controller_helper.rb +15 -0
  31. data/test/test_plugin_helper.rb +9 -0
  32. metadata +26 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09a32f8e4e63e7db95e16152e955a5b3e361529312345b10499fcf0503113c93'
4
- data.tar.gz: dceb4ab2c290b98e1fd76525880c1a6a37555152c900e23b80bf15cf9ae7d773
3
+ metadata.gz: 7a0b1fc3df2a088cefb4344e848995955fb81a5478cf4500268c68f32ccf0bec
4
+ data.tar.gz: ae3c19f91491ba06228c59f6314e28d5c8525d8936e89c5a82af092a71dd4e85
5
5
  SHA512:
6
- metadata.gz: 8f7c83c275080208924404819315b1f0c261b80a606204b906d9bf38d128aadc8286e222d57faa940c97d1799d6f2a9ad71dd98cbabd53bde6099990799ec6f1
7
- data.tar.gz: '092749ae41aed39acabdd28f02532ffd2d45581b073ac4fc57a9f7b4515f27a6c4f8b48b1b15ffaa62bd955ba296464b8f678b9ea63f2fe1e709249aaac806e5'
6
+ metadata.gz: 57f473572bfc7342b44765343b168e94bb55ba479bb17d7a9236703bcb5cb7f2cad615b16d76934790a739037eb5b724e70ff637c17e7d95aaaa6dc993eb3bd2
7
+ data.tar.gz: 6569d327e0ccb6c251a823ae3af6a3bd1a40d44edc9878fd4b538303ec242a8f594dffd0e8fb951ae371c8b22ae13f16a0120ac78a6f9cb4a5bf2dabd33781fb
data/README.md CHANGED
@@ -13,6 +13,8 @@ for how to install Foreman plugins
13
13
 
14
14
  | Foreman Version | Katello Version | Plugin Version |
15
15
  | --------------- | --------------- | -------------- |
16
+ | 2.1 | 3.16 | ~> 1.8.5 |
17
+ | 2.0 | 3.16 | ~> 1.8.4 |
16
18
  | 1.24 | 3.14 | ~> 1.8.0 |
17
19
  | 1.22 | 3.12 | ~> 1.7.0 |
18
20
  | 1.21 | 3.10 | ~> 1.6.0 |
@@ -23,6 +25,9 @@ for how to install Foreman plugins
23
25
  | 1.16 | 3.5 | <= 1.3.0 |
24
26
  | 1.15 | 3.4 | ~> 1.1.0 |
25
27
 
28
+ ## Documentation
29
+ The plugin documentation can be found at https://docs.orcharhino.com/sources/management_ui/the_content_menu/suse_subscriptions.html.
30
+
26
31
  ## Contributing
27
32
 
28
33
  Fork and send a Pull Request. Thanks!
@@ -18,7 +18,7 @@ module Api
18
18
  def index
19
19
  scope = resource_scope
20
20
  scope = scope.where(:organization => params[:organization_id]) if params[:organization_id].present?
21
- @scc_accounts = scope.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
21
+ @scc_accounts = scope.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page], :per_page => params[:per_page])
22
22
  end
23
23
 
24
24
  api :GET, '/scc_accounts/:id/', N_('Show scc_account')
@@ -34,7 +34,8 @@ module Api
34
34
  param :password, String, :required => true, :desc => N_('Password of scc_account')
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
- param :sync_date, String, :desc => N_('Last Sync time of scc_account')
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
39
  end
39
40
  end
40
41
 
@@ -79,9 +80,9 @@ module Api
79
80
  end
80
81
  respond_to do |format|
81
82
  if @scc_account.test_connection
82
- format.json { render json: 'Success'.to_json, status: :ok }
83
+ format.json { render json: { 'success' => true }.to_json, status: :ok }
83
84
  else
84
- format.json { render json: 'Failed'.to_json, status: :not_found }
85
+ format.json { render json: { 'success' => false, 'error' => 'Test failed. Check your credentials.' }.to_json, status: :not_found }
85
86
  end
86
87
  end
87
88
  end
@@ -102,7 +103,7 @@ module Api
102
103
 
103
104
  api :PUT, '/scc_accounts/:id/bulk_subscribe/', N_('Bulk subscription of scc_products for scc_account')
104
105
  param :id, :identifier_dottable, :required => true
105
- param :scc_subscribe_product_ids, Array
106
+ param :scc_subscribe_product_ids, Array, :required => true
106
107
  def bulk_subscribe
107
108
  scc_products_to_subscribe = @scc_account.scc_products.where(:id => params[:scc_subscribe_product_ids])
108
109
  respond_to do |format|
@@ -112,7 +113,7 @@ module Api
112
113
  scc_products_to_subscribe)
113
114
  format.json { render json: subscribe_task.to_json, status: :ok }
114
115
  else
115
- format.json { render json: 'No Product selected'.to_json, status: :expectation_failed }
116
+ format.json { render json: { error: 'No Product selected' }, status: :expectation_failed }
116
117
  end
117
118
  end
118
119
  rescue ::Foreman::Exception => e
@@ -132,7 +133,8 @@ module Api
132
133
  :base_url,
133
134
  :interval,
134
135
  :sync_date,
135
- :organization_id
136
+ :organization_id,
137
+ :katello_gpg_key_id
136
138
  )
137
139
  end
138
140
 
@@ -1,12 +1,19 @@
1
1
  class SccAccountsController < ApplicationController
2
+ helper_method :scc_filtered_products
2
3
  before_action :find_organization
3
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]
4
6
  include Foreman::Controller::AutoCompleteSearch
5
7
 
6
8
  # GET /scc_accounts
7
9
  def index
8
- @scc_accounts = resource_base.search_for(params[:search], order: params[:order])
9
- .paginate(page: params[:page])
10
+ @scc_accounts = resource_base.where(organization: @organization)
11
+ .search_for(params[:search], order: params[:order])
12
+ .paginate(:page => params[:page], :per_page => params[:per_page])
13
+ # overwrite the product list with filtered products that do not include products with empty repositories
14
+ @scc_accounts.each do |scc_account|
15
+ scc_account.scc_products_with_repos_count = scc_account.scc_products.only_products_with_repos.count
16
+ end
10
17
  end
11
18
 
12
19
  # GET /scc_accounts/new
@@ -92,6 +99,11 @@ class SccAccountsController < ApplicationController
92
99
 
93
100
  private
94
101
 
102
+ def find_available_gpg_keys
103
+ @scc_account ? org = @scc_account.organization : org = @organization
104
+ @selectable_gpg_keys = ::Katello::GpgKey.where(organization: org).collect { |p| [p.name, p.id] }.unshift ['None', nil]
105
+ end
106
+
95
107
  def find_organization
96
108
  @organization = Organization.current
97
109
  redirect_to '/select_organization?toState=' + request.path unless @organization
@@ -108,7 +120,8 @@ class SccAccountsController < ApplicationController
108
120
  :base_url,
109
121
  :interval,
110
122
  :sync_date,
111
- :organization_id
123
+ :organization_id,
124
+ :katello_gpg_key_id
112
125
  )
113
126
  end
114
127
 
@@ -121,9 +134,22 @@ class SccAccountsController < ApplicationController
121
134
  when 'sync', 'test_connection'
122
135
  :sync
123
136
  when 'bulk_subscribe'
124
- :bulk_subscribe
137
+ :use
125
138
  else
126
139
  super
127
140
  end
128
141
  end
142
+
143
+ # Function filters a product list and removes all products without valid repositories
144
+ # The .order call is necessary to apply the ordering to repository that have already been loaded from the database.
145
+ # Input parameters:
146
+ # product_list: list of SccProduct
147
+ # product_type: return only base products if type is set (default), else all
148
+ def scc_filtered_products(product_list, product_type = 'base')
149
+ if product_type == 'base'
150
+ product_list.only_products_with_repos.where(product_type: 'base').order(:friendly_name)
151
+ else
152
+ product_list.only_products_with_repos.order(:friendly_name)
153
+ end
154
+ end
129
155
  end
@@ -8,15 +8,16 @@ module Actions
8
8
  .info("Initiating subscription for SccProduct '#{scc_product.friendly_name}'.")
9
9
  sequence do
10
10
  product_create_action = plan_action(CreateProduct,
11
- product_name: scc_product.uniq_name,
12
- product_description: scc_product.description,
13
- organization_id: scc_product.organization.id)
11
+ :product_name => scc_product.pretty_name,
12
+ :product_description => scc_product.pretty_description,
13
+ :organization_id => scc_product.organization.id,
14
+ :gpg_key => scc_product.scc_account.katello_gpg_key_id)
14
15
  scc_product.scc_repositories.each do |repo|
15
- uniq_name = scc_product.uniq_name + ' ' + repo.description
16
16
  arch = scc_product.arch || 'noarch'
17
17
  plan_action(CreateRepository,
18
18
  :product_id => product_create_action.output[:product_id],
19
- :uniq_name => uniq_name,
19
+ :uniq_name => repo.uniq_name(scc_product),
20
+ :pretty_repo_name => repo.pretty_name,
20
21
  :url => repo.full_url,
21
22
  :arch => arch)
22
23
  end
@@ -43,6 +44,7 @@ module Actions
43
44
  def create_sub_plans
44
45
  product = ::Katello::Product.new
45
46
  product.name = input[:product_name]
47
+ product.gpg_key = ::Katello::GpgKey.find_by(id: input[:gpg_key], organization: input[:organization_id])
46
48
  product.description = input[:product_description]
47
49
  trigger(::Actions::Katello::Product::Create,
48
50
  product,
@@ -58,12 +60,11 @@ module Actions
58
60
 
59
61
  def create_sub_plans
60
62
  product = ::Katello::Product.find(input[:product_id])
61
- uniq_name = input[:uniq_name]
62
- label = ::Katello::Util::Model.labelize(uniq_name)
63
+ label = ::Katello::Util::Model.labelize(input[:uniq_name])
63
64
  unprotected = true
64
65
  gpg_key = product.gpg_key
65
66
  repo_param = { :label => label,
66
- :name => uniq_name,
67
+ :name => input[:pretty_repo_name],
67
68
  :url => input[:url],
68
69
  :content_type => 'yum',
69
70
  :unprotected => unprotected,
@@ -1,12 +1,15 @@
1
1
  module Actions
2
2
  module SccManager
3
3
  class SyncProducts < Actions::EntryAction
4
+ include EncryptValue
5
+
4
6
  def plan(scc_account)
5
7
  action_subject(scc_account)
8
+ password = encrypt_field(scc_account.password)
6
9
  plan_self(id: scc_account.id,
7
10
  base_url: scc_account.base_url,
8
11
  login: scc_account.login,
9
- password: scc_account.password)
12
+ password: password)
10
13
  end
11
14
 
12
15
  def run
@@ -15,9 +18,11 @@ module Actions
15
18
  products = ::SccManager.get_scc_data(input.fetch(:base_url),
16
19
  '/connect/organizations/products',
17
20
  input.fetch(:login),
18
- input.fetch(:password))
21
+ decrypt_field(input.fetch(:password)))
19
22
  output[:data] = ::SccManager.sanitize_products(products).values
20
- rescue StandardError
23
+ rescue StandardError => e
24
+ ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Products: #{e}"
25
+ output[:error] = e.to_s
21
26
  output[:status] = 'FAILURE'
22
27
  end
23
28
  end
@@ -34,10 +39,6 @@ module Actions
34
39
  _('Sync SUSE subscriptions (Products)')
35
40
  end
36
41
 
37
- def humanized_input
38
- input.dup.update(password: '***')
39
- end
40
-
41
42
  def humanized_output
42
43
  output.dup.update(data: 'Trimmed')
43
44
  end
@@ -1,11 +1,14 @@
1
1
  module Actions
2
2
  module SccManager
3
3
  class SyncRepositories < Actions::EntryAction
4
+ include EncryptValue
5
+
4
6
  def plan(scc_account)
5
7
  action_subject(scc_account)
8
+ password = encrypt_field(scc_account.password)
6
9
  plan_self(base_url: scc_account.base_url,
7
10
  login: scc_account.login,
8
- password: scc_account.password)
11
+ password: password)
9
12
  end
10
13
 
11
14
  def run
@@ -14,9 +17,11 @@ module Actions
14
17
  output[:data] = ::SccManager.get_scc_data(input[:base_url],
15
18
  '/connect/organizations/repositories',
16
19
  input[:login],
17
- input[:password])
20
+ decrypt_field(input[:password]))
18
21
  output[:status] = 'SUCCESS'
19
- rescue StandardError
22
+ rescue StandardError => e
23
+ ::Foreman::Logging.logger('foreman_scc_manager').error "Error while syncronizing SCC-Repositories: #{e}"
24
+ output[:error] = e.to_s
20
25
  output[:status] = 'FAILURE'
21
26
  end
22
27
  end
@@ -33,10 +38,6 @@ module Actions
33
38
  _('Sync SUSE subscriptions (Repositories)')
34
39
  end
35
40
 
36
- def humanized_input
37
- input.dup.update(password: '***')
38
- end
39
-
40
41
  def humanized_output
41
42
  output.dup.update(data: "Trimmed (got #{output[:data]&.length} repositories")
42
43
  end
@@ -8,8 +8,8 @@ module SccManager
8
8
  uri.scheme = URI.parse(proxy_config[:host]).scheme
9
9
  uri.host = URI.parse(proxy_config[:host]).host
10
10
  uri.port = proxy_config[:port].try(:to_s)
11
- uri.user = proxy_config[:user].try(:to_s)
12
- uri.password = proxy_config[:password].try(:to_s)
11
+ uri.user = proxy_config[:user]
12
+ uri.password = proxy_config[:password] if uri.user.present?
13
13
 
14
14
  RestClient.proxy = uri.to_s
15
15
  end
@@ -2,6 +2,9 @@ class SccAccount < ApplicationRecord
2
2
  include Authorizable
3
3
  include Encryptable
4
4
  include ForemanTasks::Concerns::ActionSubject
5
+
6
+ attr_accessor :scc_products_with_repos_count
7
+
5
8
  encrypts :password
6
9
 
7
10
  NEVER = 'never'.freeze
@@ -166,7 +169,8 @@ class SccAccount < ApplicationRecord
166
169
  def test_connection
167
170
  get_scc_data('/connect/organizations/subscriptions')
168
171
  true
169
- rescue StandardError
172
+ rescue StandardError => e
173
+ ::Foreman::Logging.logger('foreman_scc_manager').warn "Error occurred while testing SCC-Connection to Account #{self}: #{e}"
170
174
  false
171
175
  end
172
176
 
@@ -175,20 +179,21 @@ class SccAccount < ApplicationRecord
175
179
  # import repositories
176
180
  upstream_repositories.each do |ur|
177
181
  cached_repository = scc_repositories.find_or_initialize_by(scc_id: ur['id'])
178
- cached_repository.name = ur['name']
179
182
  cached_repository.distro_target = ur['distro_target']
180
183
  cached_repository.description = ur['description']
181
184
  cached_repository.url, cached_repository.token = ur['url'].split('?')
182
185
  cached_repository.enabled = ur['enabled']
183
186
  cached_repository.autorefresh = ur['autorefresh']
184
187
  cached_repository.installer_updates = ur['installer_updates']
188
+ # should be called after all attributes are set in case of dependencies (currently: description)
189
+ cached_repository.name = cached_repository.pretty_name
185
190
  cached_repository.save!
186
191
  upstream_repo_ids << ur['id']
187
192
  end
188
- logger.debug "Found #{upstream_repo_ids.length} repositories"
193
+ ::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_repo_ids.length} repositories"
189
194
  # delete repositories beeing removed upstream
190
195
  to_delete = scc_repositories.where.not(scc_id: upstream_repo_ids)
191
- logger.debug "Deleting #{to_delete.count} old repositories"
196
+ ::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old repositories"
192
197
  to_delete.destroy_all
193
198
  end
194
199
 
@@ -197,7 +202,6 @@ class SccAccount < ApplicationRecord
197
202
  # import products
198
203
  upstream_products.each do |up|
199
204
  cached_product = scc_products.find_or_initialize_by(scc_id: up['id'])
200
- cached_product.name = up['name']
201
205
  cached_product.version = up['version']
202
206
  cached_product.arch = up['arch']
203
207
  cached_product.description = up['description']
@@ -205,13 +209,16 @@ class SccAccount < ApplicationRecord
205
209
  cached_product.product_type = up['product_type']
206
210
  cached_product.scc_repositories =
207
211
  scc_repositories.where(scc_id: up['repositories'].map { |repo| repo['id'] })
212
+ # name should be set after friendly_name because it depends on friendly_name
213
+ cached_product.name = cached_product.pretty_name
214
+ cached_product.description = cached_product.pretty_description
208
215
  cached_product.save!
209
216
  upstream_product_ids << up['id']
210
217
  end
211
- logger.debug "Found #{upstream_product_ids.length} products"
218
+ ::Foreman::Logging.logger('foreman_scc_manager').debug "Found #{upstream_product_ids.length} products"
212
219
  # delete products beeing removed upstream
213
220
  to_delete = scc_products.where.not(scc_id: upstream_product_ids)
214
- logger.debug "Deleting #{to_delete.count} old products"
221
+ ::Foreman::Logging.logger('foreman_scc_manager').debug "Deleting #{to_delete.count} old products"
215
222
  to_delete.destroy_all
216
223
  # rewire product to product relationships
217
224
  upstream_products.each do |up|
@@ -219,7 +226,7 @@ class SccAccount < ApplicationRecord
219
226
  begin
220
227
  scc_products.find_by!(scc_id: up['id']).update!(scc_extensions: extensions)
221
228
  rescue ActiveRecord::RecordNotFound
222
- logger.info "Failed to find parent scc_product '#{up['name']}'."
229
+ ::Foreman::Logging.logger('foreman_scc_manager').info "Failed to find parent scc_product '#{up['name']}'."
223
230
  end
224
231
  end
225
232
  end
@@ -2,6 +2,8 @@ class SccProduct < ApplicationRecord
2
2
  include Authorizable
3
3
  include ForemanTasks::Concerns::ActionSubject
4
4
 
5
+ scope :only_products_with_repos, -> { joins(:scc_repositories).distinct }
6
+
5
7
  self.include_root_in_json = false
6
8
 
7
9
  belongs_to :scc_account
@@ -25,12 +27,28 @@ class SccProduct < ApplicationRecord
25
27
  "#{scc_id} " + friendly_name
26
28
  end
27
29
 
30
+ def pretty_name
31
+ friendly_name + " (id: #{scc_id})"
32
+ end
33
+
34
+ # Remove HTML tags (currently assumed that there are only paragraph tags)
35
+ # Remove second HTML paragraph if available
36
+ def pretty_description
37
+ new_description = Nokogiri::XML(description).xpath('//p')
38
+ # No tags to remove
39
+ if new_description.count == 0
40
+ description
41
+ else
42
+ new_description.first.children.first.text.strip
43
+ end
44
+ end
45
+
28
46
  def subscribe
29
47
  raise 'Product already subscribed!' if product
30
48
 
31
49
  new_product = Katello::Product.new
32
- new_product.name = uniq_name
33
- new_product.description = description
50
+ new_product.name = pretty_name
51
+ new_product.description = pretty_description
34
52
  ForemanTasks.sync_task(::Actions::Katello::Product::Create, new_product, scc_account.organization)
35
53
  new_product.reload
36
54
  scc_repositories.each do |repo|
@@ -15,6 +15,10 @@ class SccRepository < ApplicationRecord
15
15
  scc_product.uniq_name + ' ' + description
16
16
  end
17
17
 
18
+ def pretty_name
19
+ description
20
+ end
21
+
18
22
  def token_changed_callback
19
23
  User.current ||= User.anonymous_admin
20
24
  scc_products.where.not(product: nil).find_each do |sp|
@@ -1,3 +1,4 @@
1
+ <!-- see foreman/app/helper/form_helper.rb -->
1
2
  <% javascript 'foreman_scc_manager/scc_accounts' %>
2
3
 
3
4
  <%= form_for(@scc_account) do |f| %>
@@ -18,6 +19,11 @@
18
19
  <%= field f, :sync_date, label: _('Sync Date') do
19
20
  f.datetime_field :sync_date, placeholder: Time.now
20
21
  end %>
22
+ <%= selectable_f f, :katello_gpg_key_id, @selectable_gpg_keys, {},
23
+ { :include_blank => _("None"),
24
+ :label => _('Use GPG key for SUSE products'),
25
+ :selected => @scc_account.katello_gpg_key_id,
26
+ :help_block => _("Use this setting if you want to automatically add a GPG key to your SUSE products upon subscription. You can change this setting in the 'Content' > 'Products' menu, later.") } %>
21
27
  <div class='clearfix'>
22
28
  <div class='form-group'>
23
29
  <div class='col-md-2'></div>
@@ -17,15 +17,16 @@
17
17
  <td class="display-two-pane ellipsis">
18
18
  <%= link_to_if_authorized(scc_account.name, hash_for_edit_scc_account_path(:id => scc_account).merge(:auth_object => scc_account, :authorizer => authorizer)) %>
19
19
  </td>
20
- <td><%= scc_account.scc_products.count.to_s %></td>
20
+ <td><%= scc_account.scc_products_with_repos_count.to_s %></td>
21
21
  <td><%= link_to_if(scc_account.sync_task, scc_account.sync_status, scc_account.sync_task) %></td>
22
22
  <td>
23
23
  <%= action_buttons(
24
- display_link_if_authorized(_("Select products"), hash_for_scc_account_path(:id => scc_account).merge(:auth_object => scc_account, :authorizer => authorizer)),
24
+ display_link_if_authorized(_("Select products"), hash_for_scc_account_path(:id => scc_account).merge(:auth_object => scc_account, :authorizer => authorizer, :permission => 'view_scc_accounts')),
25
25
  display_link_if_authorized(_("Sync"), hash_for_sync_scc_account_path(:id => scc_account).merge(:auth_object => scc_account, :authorizer => authorizer),
26
26
  :method => :put),
27
- display_delete_if_authorized(hash_for_scc_account_path(:id => scc_account).merge(:auth_object => scc_account, :authorizer => authorizer),
27
+ display_delete_if_authorized(hash_for_scc_account_path(:id => scc_account).merge(:auth_object => scc_account, :authorizer => authorizer, :permission => 'delete_scc_accounts'),
28
28
  :data => { :confirm => _("Delete %s?") % scc_account.to_s })
29
+
29
30
  ) %>
30
31
  </td>
31
32
  </tr>
@@ -1,3 +1,5 @@
1
+ <% title (_("Product Selection for Account %s") % @scc_account) %>
2
+
1
3
  <% javascript 'foreman_scc_manager/scc_accounts' %>
2
4
  <%= form_for([:bulk_subscribe, @scc_account], method: :put) do |f| %>
3
5
  <% def render_list_node(f, scc_product, parent_id = "") %>
@@ -5,14 +7,15 @@
5
7
  <span class="scc_product_checkbox" id="<%= "scc_product_span_#{parent_id + "_" + scc_product.id.to_s}" %>" <%= "data-parent=scc_product_span_#{parent_id}" if parent_id != "" %>>
6
8
  <% if scc_product.product %>
7
9
  <%= check_box_tag("scc_account[scc_unsubscribe_product_ids][]", scc_product.id, true, disabled: true) %>
10
+ <%= link_to(scc_product.pretty_name, "/products/#{scc_product.product_id}") %>
8
11
  <% else %>
9
12
  <%= check_box_tag("scc_account[scc_subscribe_product_ids][]", scc_product.id, false) %>
13
+ <%= scc_product.pretty_name %>
10
14
  <% end %>
11
15
  </span>
12
- <%= scc_product.friendly_name %>
13
16
  <% if scc_product.scc_extensions.any? %>
14
- <ul>
15
- <% scc_product.scc_extensions.order(:friendly_name).each do |scc_extension| %>
17
+ <ul style='padding-left: 20px;'>
18
+ <% scc_filtered_products(scc_product.scc_extensions, 'extension').each do |scc_extension| %>
16
19
  <% render_list_node(f, scc_extension, parent_id + "_" + scc_product.id.to_s) %>
17
20
  <% end %>
18
21
  </ul>
@@ -29,7 +32,7 @@
29
32
  <div class="tab-pane active" id="primary">
30
33
  <ul>
31
34
  <% if @scc_account.synced %>
32
- <% @scc_account.scc_products.where(product_type: 'base').order(:friendly_name).each do |scc_product| %>
35
+ <% scc_filtered_products(@scc_account.scc_products).each do |scc_product| %>
33
36
  <% render_list_node(f, scc_product) %>
34
37
  <% end %>
35
38
  <% else %>
@@ -41,3 +44,4 @@
41
44
  <%= submit_or_cancel f, false, {disabled: submit_disabled || false} %>
42
45
  </div>
43
46
  <% end %>
47
+
@@ -0,0 +1,22 @@
1
+ class FixSccPermissions < ActiveRecord::Migration[5.2]
2
+ PERMISSION_NAMES = {
3
+ :view_scc => :view_scc_accounts,
4
+ :use_scc => :use_scc_accounts,
5
+ :new_scc => :new_scc_accounts,
6
+ :edit_scc => :edit_scc_accounts,
7
+ :delete_scc => :delete_scc_accounts,
8
+ :sync_scc => :sync_scc_accounts
9
+ }.freeze
10
+
11
+ def up
12
+ PERMISSION_NAMES.each do |old_n, new_n|
13
+ Permission.find_by(name: old_n)&.update(name: new_n, resource_type: 'SccAccount')
14
+ end
15
+ end
16
+
17
+ def down
18
+ PERMISSION_NAMES.each do |old_n, new_n|
19
+ Permission.find_by(name: new_n)&.update(name: old_n, resource_type: nil)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ class AddGpgKeyToSccAccount < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :scc_accounts, :katello_gpg_key_id, :integer, null: true
4
+ add_foreign_key :scc_accounts, :katello_gpg_keys, column: :katello_gpg_key_id, on_delete: :nullify
5
+ end
6
+ end
@@ -29,37 +29,48 @@ module ForemanSccManager
29
29
 
30
30
  # Add permissions
31
31
  security_block :foreman_scc_manager do
32
- permission :view_scc, {
33
- :'foreman_scc_manager/scc_accounts' => [:show, :index],
34
- :'api/v2/scc_accounts' => [:show, :index]
35
- }
36
- permission :use_scc, {
37
- :'foreman_scc_manager/scc_accounts' => [:bulk_subscribe],
38
- :'api/v2/scc_accounts' => [:bulk_subscribe]
39
- }
40
- permission :new_scc, {
41
- :'foreman_scc_manager/scc_accounts' => [:new, :create],
42
- :'api/v2/scc_accounts' => [:create]
43
- }
44
- permission :edit_scc, {
45
- :'foreman_scc_manager/scc_accounts' => [:edit, :update],
46
- :'api/v2/scc_accounts' => [:update]
47
- }
48
- permission :delete_scc, {
49
- :'foreman_scc_manager/scc_accounts' => [:destroy],
50
- :'api/v2/scc_accounts' => [:destroy]
51
- }
52
- permission :sync_scc, {
53
- :'foreman_scc_manager/scc_accounts' => [:sync],
54
- :'api/v2/scc_accounts' => [:sync]
55
- }
32
+ permission :view_scc_accounts,
33
+ { :scc_accounts => [:show, :index],
34
+ :'api/v2/scc_accounts' => [:show, :index] },
35
+ :resource_type => 'SccAccount'
36
+
37
+ permission :use_scc_accounts,
38
+ { :scc_accounts => [:bulk_subscribe],
39
+ :'api/v2/scc_accounts' => [:bulk_subscribe] },
40
+ :resource_type => 'SccAccount'
41
+
42
+ permission :new_scc_accounts,
43
+ { :scc_accounts => [:new, :create],
44
+ :'api/v2/scc_accounts' => [:create] },
45
+ :resource_type => 'SccAccount'
46
+
47
+ permission :edit_scc_accounts,
48
+ { :scc_accounts => [:edit, :update],
49
+ :'api/v2/scc_accounts' => [:update] },
50
+ :resource_type => 'SccAccount'
51
+
52
+ permission :delete_scc_accounts,
53
+ { :scc_accounts => [:destroy],
54
+ :'api/v2/scc_accounts' => [:destroy] },
55
+ :resource_type => 'SccAccount'
56
+
57
+ permission :sync_scc_accounts,
58
+ { :scc_accounts => [:sync],
59
+ :'api/v2/scc_accounts' => [:sync] },
60
+ :resource_type => 'SccAccount'
56
61
  end
57
62
 
58
63
  # Add a new role called 'SccManager' if it doesn't exist
59
64
  role 'SccManager',
60
- %i[view_scc use_scc new_scc edit_scc delete_scc sync_scc],
65
+ %i[view_scc_accounts use_scc_accounts new_scc_accounts edit_scc_accounts delete_scc_accounts sync_scc_accounts],
61
66
  'Role granting permissons to manage SUSE Subscriptions'
62
67
 
68
+ role 'SccViewer',
69
+ %i[view_scc_accounts use_scc_accounts sync_scc_accounts create_products view_products],
70
+ 'Role granting permissons to view and use SUSE Subscriptions'
71
+
72
+ add_all_permissions_to_default_roles
73
+
63
74
  # add menu entry
64
75
  menu :top_menu, :scc_manager,
65
76
  url_hash: { controller: :scc_accounts, action: :index },
@@ -1,3 +1,3 @@
1
1
  module ForemanSccManager
2
- VERSION = '1.8.1'.freeze
2
+ VERSION = '1.8.6'.freeze
3
3
  end
@@ -14,7 +14,7 @@ end
14
14
 
15
15
  namespace :jenkins do
16
16
  desc 'Test ForemanSccManager with XML output for jenkins'
17
- task 'foreman_scc_manager' do
17
+ task 'foreman_scc_manager' => :environment do
18
18
  Rake::Task['jenkins:setup:minitest'].invoke
19
19
  Rake::Task['rake:test:foreman_scc_manager'].invoke
20
20
  end
@@ -192,6 +192,14 @@ msgid ""
192
192
  " of any imported products."
193
193
  msgstr ""
194
194
 
195
+ #: ../app/views/scc_accounts/_form.html.erb:22
196
+ msgid "Use GPG key for SUSE products"
197
+ msgstr ""
198
+
199
+ #: ../app/views/scc_accounts/_form.html.erb:22
200
+ msgid "Use this setting if you want to automatically add a GPG key to your SUSE products upon subscription. You can change this setting in the 'Content' > 'Products' menu, later."
201
+ msgstr ""
202
+
195
203
  #: ../app/views/scc_accounts/_form.html.erb:18
196
204
  msgid "Sync Date"
197
205
  msgstr ""
@@ -236,7 +236,9 @@ class Api::V2::SccAccountsControllerTest < ActionController::TestCase
236
236
  assert account
237
237
  post :test_connection, params: { :scc_account => { :login => account.login, :password => account.password, :base_url => account.base_url } }
238
238
  assert_response :not_found
239
- assert_match response.body, '"Failed"'
239
+ body = ActiveSupport::JSON.decode(@response.body)
240
+ assert body.key? 'error'
241
+ assert_equal body['success'], false
240
242
  end
241
243
 
242
244
  test 'existing account SCC server connection-test' do
@@ -260,7 +262,9 @@ class Api::V2::SccAccountsControllerTest < ActionController::TestCase
260
262
  assert account
261
263
  post :test_connection, params: { :id => account.id }
262
264
  assert_response :not_found
263
- assert_match response.body, '"Failed"'
265
+ body = ActiveSupport::JSON.decode(@response.body)
266
+ assert body.key? 'error'
267
+ assert_equal body['success'], false
264
268
  end
265
269
 
266
270
  test 'SCC server sync products' do
@@ -289,7 +293,9 @@ class Api::V2::SccAccountsControllerTest < ActionController::TestCase
289
293
  account.scc_products = [product1, product2]
290
294
  put :bulk_subscribe, params: { :id => account.id, :scc_subscribe_product_ids => [] }
291
295
  assert_response :expectation_failed
292
- assert_match response.body, '"No Product selected"'
296
+ body = ActiveSupport::JSON.decode(@response.body)
297
+ assert body.key? 'error'
298
+ assert_match body['error'], 'No Product selected'
293
299
  end
294
300
 
295
301
  test 'should delete scc_account' do
@@ -0,0 +1,104 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class SccAccountsControllerTest < ActionController::TestCase
4
+ def setup
5
+ @scc_account = scc_accounts(:one)
6
+ end
7
+
8
+ def stub_custom_request(url, host = 'scc.example.com', auth = 'Basic b25ldXNlcjpvbmVwYXNz')
9
+ stub_request(:get, url)
10
+ .with(
11
+ headers: {
12
+ 'Accept' => 'application/vnd.scc.suse.com.v4+json',
13
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
14
+ 'Authorization' => auth,
15
+ 'Host' => host,
16
+ 'User-Agent' => "rest-client/2.1.0 (linux-gnu x86_64) ruby/#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
17
+ }
18
+ )
19
+ .to_return(status: 200, body: '', headers: {})
20
+ end
21
+
22
+ test 'should get new' do
23
+ get :new, session: set_session_user
24
+ assert_response :success
25
+ assert_select 'title', 'Add SUSE Customer Center Account'
26
+ end
27
+
28
+ test 'should get edit' do
29
+ get :edit, params: { :id => @scc_account.id }, session: set_session_user
30
+ assert_response :success
31
+ assert_select 'title', "Edit #{@scc_account.name}"
32
+ end
33
+
34
+ test 'should get index' do
35
+ get :index, session: set_session_user
36
+ assert_response :success
37
+ assert_not_nil assigns(:scc_accounts)
38
+ body = @response.body
39
+ assert_not_empty body
40
+ assert_select 'title', 'SUSE subscriptions'
41
+ end
42
+
43
+ test 'should show scc_account' do
44
+ get :show, params: { :id => @scc_account.id }, session: set_session_user
45
+
46
+ assert_not_nil assigns(:scc_account)
47
+ assert_response :success
48
+ assert_select 'title', "Product Selection for Account #{@scc_account.name}"
49
+ end
50
+
51
+ test 'should 404 for unknown scc_account' do
52
+ get :show, params: { :id => 'does-not-exist' }, session: set_session_user
53
+
54
+ assert_response :not_found
55
+ end
56
+
57
+ test 'should create scc_account' do
58
+ account = scc_accounts(:two)
59
+ organization = get_organization
60
+ assert organization
61
+ assert account
62
+ assert_difference('SccAccount.count') do
63
+ post :create, params:
64
+ { :scc_account => { :name => account.name, :login => account.login, :password => account.password, :organization_id => organization.id } },
65
+ session: set_session_user
66
+ end
67
+ end
68
+
69
+ test 'should update scc_account' do
70
+ account = scc_accounts(:two)
71
+ put :update, params: { id: account.id, :scc_account => { :sync_date => Time.now, :interval => 'weekly' } }, session: set_session_user
72
+
73
+ assert_equal 'weekly', assigns(:scc_account).interval
74
+ end
75
+
76
+ test 'SCC server sync products' do
77
+ stub_custom_request('https://scc.example.com/connect/organizations/products')
78
+ stub_custom_request('https://scc.example.com/connect/organizations/repositories')
79
+
80
+ account = scc_accounts(:one)
81
+ assert account
82
+ put :sync, params: { :id => account.id }, session: set_session_user
83
+ assert_redirected_to '/scc_accounts'
84
+ end
85
+
86
+ test 'SCC server bulk subscribe products' do
87
+ stub_custom_request('https://scc.example.com/connect/organizations/repositories')
88
+
89
+ account = scc_accounts(:one)
90
+ product1 = scc_products(:one)
91
+ product2 = scc_products(:two)
92
+ account.scc_products = [product1, product2]
93
+ put :bulk_subscribe, params: { :id => account.id, :scc_account => { :scc_subscribe_product_ids => [product1.id, product2.id] } }, session: set_session_user
94
+
95
+ assert_redirected_to '/scc_accounts'
96
+ end
97
+
98
+ test 'should delete scc_account' do
99
+ account = scc_accounts(:two)
100
+ assert_difference 'SccAccount.count', -1 do
101
+ delete :destroy, params: { :id => account.id }, session: set_session_user
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class SccAccountsControllerTest2 < ActionDispatch::IntegrationTest
4
+ setup do
5
+ @scc_account = scc_accounts(:one)
6
+ end
7
+
8
+ test 'should get index' do
9
+ get scc_accounts_url, session: set_session_user
10
+ # post path, params: { :id => "#{taxonomies(:empty_organization).id}-#{taxonomies(:empty_organization).name}" }
11
+ # post path, params: {:toState => scc_accounts_url, :bastion_page => "select_organization"}
12
+ # follow_redirect!
13
+ assert_response :success
14
+ end
15
+
16
+ test 'should get new' do
17
+ get new_scc_account_url
18
+ assert_response :success
19
+ end
20
+
21
+ test 'should create scc_account' do
22
+ assert_difference('SccAccount.count') do
23
+ post scc_accounts_url, params: { scc_account: {} }
24
+ end
25
+
26
+ assert_redirected_to scc_account_url(SccAccount.last)
27
+ end
28
+
29
+ test 'should show scc_account' do
30
+ get scc_account_url(@scc_account)
31
+ assert_response :success
32
+ end
33
+
34
+ test 'should get edit' do
35
+ get edit_scc_account_url(@scc_account)
36
+ assert_response :success
37
+ end
38
+
39
+ test 'should update scc_account' do
40
+ patch scc_account_url(@scc_account), params: { scc_account: {} }
41
+ assert_redirected_to scc_account_url(@scc_account)
42
+ end
43
+
44
+ test 'should destroy scc_account' do
45
+ assert_difference('SccAccount.count', -1) do
46
+ delete scc_account_url(@scc_account)
47
+ end
48
+
49
+ assert_redirected_to scc_accounts_url
50
+ end
51
+ end
@@ -0,0 +1,6 @@
1
+ # create a couple of products as scc_extensions
2
+ <% 1.upto(10) do |i| %>
3
+ p_extending_<%= i %>:
4
+ scc_product_id: 4
5
+ scc_extension_id: <%= 4 + i %>
6
+ <% end %>
@@ -7,7 +7,7 @@ one:
7
7
  version: 1
8
8
  arch: x86_128
9
9
  friendly_name: number one
10
- description: lorem ipsum dolor sit amet
10
+ description: "<p> lorem ipsum dolor sit amet </p>"
11
11
  product_type: base
12
12
 
13
13
  two:
@@ -17,5 +17,29 @@ two:
17
17
  version: 2
18
18
  arch: x86_128
19
19
  friendly_name: number two
20
- description: lorem ipsum dolor sit amet
20
+ description: "<p> lorem ipsum dolor sit amet </p><p> lorem lorem lorem </p>"
21
21
  product_type: extras
22
+
23
+ three:
24
+ scc_account_id: test_account1
25
+ scc_id: 333
26
+ name: three
27
+ version: 3
28
+ arch: x86_128
29
+ friendly_name: number three
30
+ description: lorem ipsum dolor sit amet
31
+ product_type: base
32
+
33
+ # create a couple of products as scc_extensions
34
+ <% 1.upto(10) do |i| %>
35
+ p_extension_<%= i %>:
36
+ scc_account_id: test_account1
37
+ scc_id: <%= i %>
38
+ name: p_ext_<%= i%>
39
+ version: 3
40
+ arch: x86_128
41
+ friendly_name: number <%= i%>
42
+ description: lorem ipsum dolor sit amet
43
+ product_type: extension
44
+ <% end %>
45
+
@@ -0,0 +1,29 @@
1
+ # repositories for testing the empty repository filtering
2
+ <% 1.upto(8) do |i| %>
3
+ repo_<%= i %>:
4
+ id: <%= i %>
5
+ scc_account_id: 1
6
+ scc_id: <%= 63 + i %>
7
+ name: SLE10-Debuginfo-Updates_<%= i %>
8
+ distro_target: sles_<%= i %>
9
+ description: SLE10-Debuginfo-Updates for sles-10-ppc_<%= i %>
10
+ url: https://updates.suse.com/repo/example_<%= i %>
11
+ token: token_<%= i %>
12
+ autorefresh: true
13
+ installer_updates: false
14
+ <% end %>
15
+
16
+ repo_9:
17
+ id: 9
18
+ scc_account_id: 1
19
+ scc_id: 63
20
+ name: SLE10-Debuginfo-Updates_9
21
+ distro_target: sles_9
22
+ description: SLE10-Debuginfo-Updates for sles-10-ppc_9
23
+ url: https://updates.suse.com/repo/example_9
24
+ token: token_9
25
+ autorefresh: true
26
+ installer_updates: false
27
+
28
+
29
+
@@ -71,4 +71,68 @@ class SccAccountSearchTest < ActiveSupport::TestCase
71
71
  end
72
72
  end
73
73
 
74
+ class SccAccountUpdateProductsTest < ActiveSupport::TestCase
75
+ def setup
76
+ @account = scc_accounts(:one)
77
+ one = scc_products(:one)
78
+ @account.scc_products = SccProduct.where(name: 'one')
79
+ # generate test data, beware that hash names are not equal to SccProduct instance names
80
+ @product_data = { 'name' => one.name,
81
+ 'id' => one.scc_id,
82
+ 'version' => one.version,
83
+ 'arch' => one.arch,
84
+ 'repositories' => one.scc_repositories,
85
+ 'extensions' => one.scc_extensions,
86
+ 'product_type' => one.product_type,
87
+ 'description' => '<p> new unpretty description </p>',
88
+ 'friendly_name' => 'updated name' }
89
+ @product_array = []
90
+ @product_array.push @product_data
91
+
92
+ @test_product = SccProduct.new
93
+ @test_product.scc_id = @product_data['id']
94
+ @test_product.friendly_name = @product_data['friendly_name']
95
+ @test_product.description = @product_data['description']
96
+ end
97
+
98
+ test 'update scc product' do
99
+ @account.update_scc_products(@product_array)
100
+ @updated_product = @account.scc_products.where(friendly_name: 'updated name').first
101
+ assert_equal @test_product.pretty_name, @updated_product.name
102
+ assert_equal @test_product.pretty_name, @updated_product.pretty_name
103
+ assert_equal @test_product.pretty_description, @updated_product.description
104
+ assert_equal @test_product.pretty_description, @updated_product.pretty_description
105
+ end
106
+ end
107
+
108
+ class SccAccountUpdateReposTest < ActiveSupport::TestCase
109
+ def setup
110
+ @account = scc_accounts(:one)
111
+ test_repo = scc_repositories(:repo_9)
112
+ @account.scc_repositories = SccProduct.where(name: 'repo_9')
113
+ # generate test data
114
+ @repo_data = { 'name' => test_repo.name,
115
+ 'id' => test_repo.scc_id,
116
+ 'distro_target' => test_repo.distro_target,
117
+ 'url' => test_repo.url,
118
+ 'enabled' => test_repo.enabled,
119
+ 'autorefresh' => test_repo.autorefresh,
120
+ 'installer_updates' => test_repo.installer_updates,
121
+ 'description' => '<p> new unpretty repo description </p>' }
122
+ @repo_array = []
123
+ @repo_array.push @repo_data
124
+
125
+ @test_repo = SccRepository.new
126
+ @test_repo.description = @repo_data['description']
127
+ @test_repo.name = @repo_data['name']
128
+ end
129
+
130
+ test 'update scc repository' do
131
+ @account.update_scc_repositories(@repo_array)
132
+ @updated_repo = @account.scc_repositories.where(name: @test_repo.pretty_name).first
133
+ assert_equal @test_repo.pretty_name, @updated_repo.name
134
+ assert_equal @test_repo.pretty_name, @updated_repo.pretty_name
135
+ end
136
+ end
137
+
74
138
  # FIXME: test cascaded delete
@@ -3,6 +3,8 @@ require 'test_plugin_helper'
3
3
  class SccProductCreateTest < ActiveSupport::TestCase
4
4
  def setup
5
5
  @product = scc_products(:one)
6
+ @product_with_ugly_description = scc_products(:two)
7
+ @product_with_normal_description = scc_products(:three)
6
8
  end
7
9
 
8
10
  test 'create' do
@@ -13,11 +15,26 @@ class SccProductCreateTest < ActiveSupport::TestCase
13
15
  test 'uniq_name' do
14
16
  assert_equal @product.uniq_name, '111 number one'
15
17
  end
18
+
19
+ test 'pretty_name' do
20
+ assert_equal @product.pretty_name, 'number one (id: 111)'
21
+ end
22
+
23
+ test 'pretty_description' do
24
+ assert_equal @product_with_normal_description.description,
25
+ @product_with_normal_description.pretty_description
26
+ assert_equal @product.pretty_description, 'lorem ipsum dolor sit amet'
27
+ assert_equal @product_with_ugly_description.pretty_description, 'lorem ipsum dolor sit amet'
28
+ end
16
29
  end
17
30
 
18
31
  class SccProductSearchTest < ActiveSupport::TestCase
19
32
  test 'default ordered by name' do
20
- assert_equal SccProduct.all.pluck(:name), ['one', 'two'].sort
33
+ product_names = ['one', 'two', 'three',
34
+ 'p_ext_1', 'p_ext_10', 'p_ext_2', 'p_ext_3',
35
+ 'p_ext_4', 'p_ext_5', 'p_ext_6', 'p_ext_7',
36
+ 'p_ext_8', 'p_ext_9']
37
+ assert_equal SccProduct.all.pluck(:name), product_names.sort
21
38
  end
22
39
 
23
40
  test 'search name' do
@@ -30,3 +47,54 @@ class SccProductSearchTest < ActiveSupport::TestCase
30
47
  assert_empty empty
31
48
  end
32
49
  end
50
+
51
+ # These produt extension tests are pre-tests for the class ProductEmptyRepoAvailableTests.
52
+ # They do not test any direct functionality of the plugin.
53
+ class SccProductExtensionsTest < ActiveSupport::TestCase
54
+ def setup
55
+ @product_with_extensions = scc_products(:one)
56
+ @product_with_extensions.scc_extensions = scc_products.select { |p| p.product_type == 'extension' }
57
+ @product_with_wrong_extensions = scc_products(:two)
58
+ @product_with_wrong_extensions.scc_extensions = [scc_products(:three)]
59
+ @product_without_extensions = scc_products(:three)
60
+ end
61
+
62
+ test 'check product extensions available' do
63
+ assert_equal @product_with_extensions.scc_extensions.count, 10
64
+ assert_not_empty @product_with_extensions.scc_extensions
65
+ assert_empty @product_without_extensions.scc_extensions
66
+ end
67
+
68
+ test 'product extension of correct type' do
69
+ assert_empty(@product_with_extensions.scc_extensions.reject { |p| p.product_type == 'extension' })
70
+ assert_not_empty(@product_with_wrong_extensions.scc_extensions.reject { |p| p.product_type == 'extension' })
71
+ end
72
+ end
73
+
74
+ class SccProductEmptyRepoAvailableTest < ActiveSupport::TestCase
75
+ def setup
76
+ @product_with_repos = scc_products(:one)
77
+ @product_with_repos.scc_extensions = scc_products.select { |p| p.product_type == 'extension' }
78
+ @product_with_repos.scc_repositories = scc_repositories[0..2]
79
+ @product_with_repos.scc_extensions[1].scc_repositories = scc_repositories[3..4]
80
+ @product_with_repos.scc_extensions[2].scc_repositories = scc_repositories[5..7]
81
+ end
82
+
83
+ test 'products with empty repositories' do
84
+ products_with_repos = SccProduct.only_products_with_repos
85
+ assert_equal SccProduct.all.count { |prod| !prod.scc_repositories.empty? }, 3
86
+ assert_equal products_with_repos.count, 3
87
+ end
88
+ end
89
+
90
+ class SccProductNoRepoTest < ActiveSupport::TestCase
91
+ def setup
92
+ @product_with_repos = scc_products(:one)
93
+ @product_with_repos.scc_extensions = scc_products.select { |p| p.product_type == 'extension' }
94
+ end
95
+
96
+ test 'products without any repositories' do
97
+ products_with_repos = SccProduct.only_products_with_repos
98
+ assert_empty products_with_repos
99
+ end
100
+ end
@@ -1,8 +1,9 @@
1
1
  module ForemanSccManager
2
2
  module FixturesSupport
3
3
  FIXTURE_CLASSES = {
4
- scc_accounts: ForemanSccManager::SccAccount,
5
- scc_products: ForemanSccManager::SccProduct
4
+ scc_accounts: ::SccAccount,
5
+ scc_products: ::SccProduct,
6
+ scc_repositories: ::SccRepository
6
7
  }.freeze
7
8
 
8
9
  def self.set_fixture_classes(test_class)
@@ -0,0 +1,15 @@
1
+ # This calls the main test_helper in Foreman-core
2
+ require 'test_helper'
3
+ # require "#{Katello::Engine.root}/test/katello_test_helper"
4
+
5
+ require 'foreman_tasks/test_helpers'
6
+
7
+ module SignInHelper
8
+ def sign_in_as(user)
9
+ post sign_in_url(username: user.login, password: user.password)
10
+ end
11
+ end
12
+
13
+ class ActionDispatch::IntegrationTest
14
+ include SignInHelper
15
+ end
@@ -22,6 +22,7 @@ module FixtureTestCase
22
22
  Dir.mkdir(self.fixture_path)
23
23
  FileUtils.cp(Dir.glob("#{ForemanSccManager::Engine.root}/test/fixtures/models/*"), self.fixture_path)
24
24
  FileUtils.cp(Dir.glob("#{ForemanSccManager::Engine.root}/test/fixtures/files/*"), self.fixture_path)
25
+ FileUtils.cp(Dir.glob("#{ForemanSccManager::Engine.root}/test/fixtures/controllers/*"), self.fixture_path)
25
26
  FileUtils.cp(Dir.glob("#{Rails.root}/test/fixtures/*"), self.fixture_path)
26
27
  fixtures(:all)
27
28
  FIXTURES = load_fixtures(ActiveRecord::Base)
@@ -56,3 +57,11 @@ class ActiveSupport::TestCase
56
57
  organization
57
58
  end
58
59
  end
60
+
61
+ class ActionController::TestCase
62
+ def set_session_user(user = :admin, org = :empty_organization)
63
+ user = user.is_a?(User) ? user : users(user)
64
+ org = org.is_a?(Organization) ? org : taxonomies(org)
65
+ { :user => user.id, :expires_at => 5.minutes.from_now, :organization_id => org.id }
66
+ end
67
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_scc_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 1.8.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - ATIX AG
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-16 00:00:00.000000000 Z
11
+ date: 2020-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdoc
@@ -84,14 +84,14 @@ dependencies:
84
84
  name: rails
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '5.1'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '5.1'
97
97
  description: Foreman plugin to sync SUSE Customer Center products and repositories
@@ -153,6 +153,8 @@ files:
153
153
  - db/migrate/20170505063726_add_sync_status_to_scc_account.rb
154
154
  - db/migrate/20180321000000_change_sync_status_to_sync_task.rb
155
155
  - db/migrate/20190417202427_add_recurring_sync.foreman_scc_manager.rb
156
+ - db/migrate/20200520281300_fix_scc_permissions.rb
157
+ - db/migrate/20201119084201_add_gpg_key_to_scc_account.rb
156
158
  - lib/foreman_scc_manager.rb
157
159
  - lib/foreman_scc_manager/engine.rb
158
160
  - lib/foreman_scc_manager/version.rb
@@ -168,6 +170,8 @@ files:
168
170
  - locale/gemspec.rb
169
171
  - test/controllers/api/v2/scc_accounts_test.rb
170
172
  - test/controllers/api/v2/scc_products_test.rb
173
+ - test/controllers/scc_accounts_controller_test.rb
174
+ - test/controllers/scc_accounts_controller_test2.rb
171
175
  - test/factories/foreman_scc_manager_factories.rb
172
176
  - test/features/sync_test.rb
173
177
  - test/fixtures/files/data_products_page1.json
@@ -175,10 +179,13 @@ files:
175
179
  - test/fixtures/files/data_repositories.json
176
180
  - test/fixtures/files/data_subscriptions.json
177
181
  - test/fixtures/models/scc_accounts.yml
182
+ - test/fixtures/models/scc_extendings.yml
178
183
  - test/fixtures/models/scc_products.yml
184
+ - test/fixtures/models/scc_repositories.yml
179
185
  - test/models/scc_account_test.rb
180
186
  - test/models/scc_product_test.rb
181
187
  - test/support/fixtures_support.rb
188
+ - test/test_controller_helper.rb
182
189
  - test/test_plugin_helper.rb
183
190
  - test/unit/foreman_scc_manager_test.rb
184
191
  homepage: https://www.orcharhino.com/
@@ -200,24 +207,28 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
207
  - !ruby/object:Gem::Version
201
208
  version: '0'
202
209
  requirements: []
203
- rubyforge_project:
204
- rubygems_version: 2.7.9
210
+ rubygems_version: 3.1.2
205
211
  signing_key:
206
212
  specification_version: 4
207
213
  summary: Suse Customer Center plugin for Foreman
208
214
  test_files:
215
+ - test/unit/foreman_scc_manager_test.rb
216
+ - test/test_controller_helper.rb
217
+ - test/features/sync_test.rb
218
+ - test/models/scc_product_test.rb
219
+ - test/models/scc_account_test.rb
220
+ - test/factories/foreman_scc_manager_factories.rb
209
221
  - test/controllers/api/v2/scc_accounts_test.rb
210
222
  - test/controllers/api/v2/scc_products_test.rb
211
- - test/test_plugin_helper.rb
212
- - test/features/sync_test.rb
223
+ - test/controllers/scc_accounts_controller_test2.rb
224
+ - test/controllers/scc_accounts_controller_test.rb
213
225
  - test/support/fixtures_support.rb
214
- - test/fixtures/models/scc_products.yml
215
226
  - test/fixtures/models/scc_accounts.yml
216
- - test/fixtures/files/data_subscriptions.json
227
+ - test/fixtures/models/scc_repositories.yml
228
+ - test/fixtures/models/scc_products.yml
229
+ - test/fixtures/models/scc_extendings.yml
230
+ - test/fixtures/files/data_products_page2.json
217
231
  - test/fixtures/files/data_products_page1.json
232
+ - test/fixtures/files/data_subscriptions.json
218
233
  - test/fixtures/files/data_repositories.json
219
- - test/fixtures/files/data_products_page2.json
220
- - test/models/scc_product_test.rb
221
- - test/models/scc_account_test.rb
222
- - test/unit/foreman_scc_manager_test.rb
223
- - test/factories/foreman_scc_manager_factories.rb
234
+ - test/test_plugin_helper.rb