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