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.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/app/controllers/api/v2/scc_accounts_controller.rb +9 -7
- data/app/controllers/scc_accounts_controller.rb +30 -4
- data/app/lib/actions/scc_manager/subscribe_product.rb +9 -8
- data/app/lib/actions/scc_manager/sync_products.rb +8 -7
- data/app/lib/actions/scc_manager/sync_repositories.rb +8 -7
- data/app/lib/scc_manager.rb +2 -2
- data/app/models/scc_account.rb +15 -8
- data/app/models/scc_product.rb +20 -2
- data/app/models/scc_repository.rb +4 -0
- data/app/views/scc_accounts/_form.html.erb +6 -0
- data/app/views/scc_accounts/index.html.erb +4 -3
- data/app/views/scc_accounts/show.html.erb +8 -4
- data/db/migrate/20200520281300_fix_scc_permissions.rb +22 -0
- data/db/migrate/20201119084201_add_gpg_key_to_scc_account.rb +6 -0
- data/lib/foreman_scc_manager/engine.rb +36 -25
- data/lib/foreman_scc_manager/version.rb +1 -1
- data/lib/tasks/test.rake +1 -1
- data/locale/foreman_scc_manager.pot +8 -0
- data/test/controllers/api/v2/scc_accounts_test.rb +9 -3
- data/test/controllers/scc_accounts_controller_test.rb +104 -0
- data/test/controllers/scc_accounts_controller_test2.rb +51 -0
- data/test/fixtures/models/scc_extendings.yml +6 -0
- data/test/fixtures/models/scc_products.yml +26 -2
- data/test/fixtures/models/scc_repositories.yml +29 -0
- data/test/models/scc_account_test.rb +64 -0
- data/test/models/scc_product_test.rb +69 -1
- data/test/support/fixtures_support.rb +3 -2
- data/test/test_controller_helper.rb +15 -0
- data/test/test_plugin_helper.rb +9 -0
- metadata +26 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a0b1fc3df2a088cefb4344e848995955fb81a5478cf4500268c68f32ccf0bec
|
4
|
+
data.tar.gz: ae3c19f91491ba06228c59f6314e28d5c8525d8936e89c5a82af092a71dd4e85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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_('
|
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: '
|
83
|
+
format.json { render json: { 'success' => true }.to_json, status: :ok }
|
83
84
|
else
|
84
|
-
format.json { render json: '
|
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'
|
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.
|
9
|
-
.
|
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
|
-
:
|
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
|
12
|
-
product_description
|
13
|
-
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
|
-
|
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 =>
|
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:
|
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:
|
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
|
data/app/lib/scc_manager.rb
CHANGED
@@ -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]
|
12
|
-
uri.password = proxy_config[:password].
|
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
|
data/app/models/scc_account.rb
CHANGED
@@ -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
|
data/app/models/scc_product.rb
CHANGED
@@ -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 =
|
33
|
-
new_product.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.
|
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
|
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
|
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
|
@@ -29,37 +29,48 @@ module ForemanSccManager
|
|
29
29
|
|
30
30
|
# Add permissions
|
31
31
|
security_block :foreman_scc_manager do
|
32
|
-
permission :
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
permission :
|
53
|
-
|
54
|
-
|
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[
|
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 },
|
data/lib/tasks/test.rake
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|
-
|
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:
|
5
|
-
scc_products:
|
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
|
data/test/test_plugin_helper.rb
CHANGED
@@ -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.
|
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-
|
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
|
-
|
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/
|
212
|
-
- test/
|
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/
|
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/
|
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
|