foreman_scc_manager 1.8.1 → 1.8.6

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