katello 4.5.0.rc1 → 4.5.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of katello might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/javascripts/katello/hosts/activation_key_edit.js +9 -2
- data/app/controllers/katello/api/registry/registry_proxies_controller.rb +3 -0
- data/app/controllers/katello/api/v2/alternate_content_sources_bulk_actions_controller.rb +44 -0
- data/app/controllers/katello/api/v2/alternate_content_sources_controller.rb +29 -6
- data/app/controllers/katello/api/v2/content_view_components_controller.rb +1 -1
- data/app/controllers/katello/api/v2/content_view_repositories_controller.rb +1 -1
- data/app/controllers/katello/api/v2/repositories_controller.rb +2 -8
- data/app/lib/actions/katello/alternate_content_source/refresh.rb +27 -0
- data/app/lib/actions/katello/cdn_configuration/update.rb +1 -1
- data/app/lib/actions/katello/content_view/publish.rb +1 -1
- data/app/lib/actions/katello/organization/manifest_refresh.rb +1 -1
- data/app/lib/actions/pulp3/alternate_content_source/delete.rb +2 -2
- data/app/lib/actions/pulp3/alternate_content_source/delete_remote.rb +2 -2
- data/app/lib/actions/pulp3/alternate_content_source/refresh.rb +23 -0
- data/app/lib/actions/pulp3/alternate_content_source/update.rb +2 -2
- data/app/lib/actions/pulp3/alternate_content_source/update_remote.rb +2 -2
- data/app/lib/actions/pulp3/orchestration/alternate_content_source/create.rb +0 -2
- data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh.rb +15 -0
- data/app/lib/actions/pulp3/orchestration/alternate_content_source/update.rb +0 -2
- data/app/lib/actions/pulp3/repository/refresh_distribution.rb +1 -4
- data/app/lib/actions/pulp3/repository/save_artifact.rb +1 -1
- data/app/lib/actions/pulp3/repository/save_distribution_references.rb +0 -2
- data/app/models/katello/alternate_content_source.rb +5 -0
- data/app/services/katello/pulp3/alternate_content_source.rb +6 -0
- data/app/services/katello/pulp3/content_view_version/metadata_map.rb +1 -1
- data/app/services/katello/pulp3/repository.rb +29 -1
- data/app/views/katello/api/v2/alternate_content_sources/base.json.rabl +10 -1
- data/app/views/katello/api/v2/content_facet/show.json.rabl +12 -0
- data/app/views/katello/api/v2/repository_sets/show.json.rabl +4 -0
- data/config/routes/api/v2.rb +16 -4
- data/db/migrate/20220303160220_remove_duplicate_errata.rb +1 -1
- data/db/migrate/20220428203334_add_last_refreshed_to_katello_alternate_content_sources.rb +5 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.controller.js +1 -1
- data/lib/katello/permission_creator.rb +4 -2
- data/lib/katello/tasks/refresh_alternate_content_sources.rake +10 -0
- data/lib/katello/version.rb +1 -1
- data/webpack/components/Bookmark/index.js +22 -14
- data/webpack/components/Search/Search.js +4 -0
- data/webpack/components/Table/MainTable.scss +5 -1
- data/webpack/components/Table/TableWrapper.js +5 -1
- data/webpack/components/TypeAhead/TypeAhead.js +4 -0
- data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +2 -0
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +2 -8
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +41 -11
- data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsActions.js +2 -2
- data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +32 -13
- data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsCard.test.js +8 -0
- data/webpack/components/extensions/HostDetails/DetailsTabCards/RecentCommunicationCardExtensions.js +37 -0
- data/webpack/components/extensions/HostDetails/HostDetailsActions.js +11 -0
- data/webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js +4 -0
- data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +2 -0
- data/webpack/components/extensions/HostDetails/Tabs/ContentTab/index.js +6 -1
- data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +120 -51
- data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +71 -37
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +4 -3
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +117 -40
- data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +25 -3
- data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionHooks.js +85 -0
- data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +87 -33
- data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +14 -7
- data/webpack/components/extensions/HostDetails/Tabs/TracesTab/HostTracesActions.js +2 -1
- data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +104 -0
- data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +92 -51
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +13 -23
- data/webpack/components/extensions/HostDetails/Tabs/{ModuleStreamsTab/__tests__/modules.fixtures.json → __tests__/moduleStreams.fixtures.json} +0 -0
- data/webpack/components/extensions/HostDetails/Tabs/{ModuleStreamsTab/__tests__ → __tests__}/moduleStreamsTab.test.js +13 -6
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/packageInstallModal.test.js +21 -15
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +8 -0
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySets.fixtures.json +4 -1
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +26 -0
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +7 -4
- data/webpack/components/extensions/HostDetails/hostDetailsHelpers.js +18 -0
- data/webpack/global_index.js +2 -2
- data/webpack/redux/actions/RedHatRepositories/helpers.js +5 -1
- data/webpack/scenes/AlternateContentSources/ACSActions.js +13 -1
- data/webpack/scenes/AlternateContentSources/ACSConstants.js +14 -0
- data/webpack/scenes/AlternateContentSources/ACSSelectors.js +10 -1
- data/webpack/scenes/AlternateContentSources/Create/ACSCreateContext.js +4 -0
- data/webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js +160 -0
- data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js +79 -0
- data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCredentials.js +199 -0
- data/webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js +104 -0
- data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +41 -0
- data/webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js +71 -0
- data/webpack/scenes/AlternateContentSources/Create/Steps/NameACS.js +57 -0
- data/webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js +77 -0
- data/webpack/scenes/AlternateContentSources/Create/__tests__/acsCreate.test.js +149 -0
- data/webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateData.fixtures.json +3 -0
- data/webpack/scenes/AlternateContentSources/Create/__tests__/contentCredentials.fixtures.json +69 -0
- data/webpack/scenes/AlternateContentSources/Create/__tests__/smartProxy.fixtures.json +65 -0
- data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +33 -23
- data/webpack/scenes/ContentCredentials/ContentCredentialSelectors.js +4 -1
- data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +2 -2
- data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +1 -1
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +1 -1
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -2
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +4 -4
- data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +1 -1
- data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +4 -4
- data/webpack/scenes/ContentViews/components/ContentViewIcon.js +1 -1
- data/webpack/scenes/ContentViews/components/ContentViewsCounter.js +1 -1
- data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +1 -1
- data/webpack/scenes/ContentViews/expansions/DetailsExpansion.js +2 -2
- data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +2 -2
- data/webpack/scenes/ContentViews/expansions/__tests__/contentViewComponentsModal.test.js +1 -1
- data/webpack/scenes/RedHatRepositories/components/Search.js +4 -4
- data/webpack/scenes/SmartProxy/SmartProxyContentActions.js +9 -2
- data/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +1 -1
- data/webpack/scenes/SmartProxy/SmartProxyContentSelectors.js +10 -1
- data/webpack/scenes/Tasks/helpers.js +30 -3
- metadata +34 -14
- data/db/seeds.d/107-enable_dynflow.rb +0 -8
- data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerEmptyState.js +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5922047abc1b1bd8649e30bbaaf5eaf2e09f09bc9abb5e1b61920c0b84b1b57b
|
4
|
+
data.tar.gz: 8105c45f9d16ca034430e89224f9bb81fa95c02d38ca638268864e34a9d57e2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '069335f24169763ce80081693498c668a115893acb4e9c7b2a1486d54d5394f53b9d21cb6442acd6cba990f07d58e6b75f7ec0d9e32515165226fb833874a311'
|
7
|
+
data.tar.gz: 22cda386e45a6d989daff56fe3897d07a75205282b2aa1e901bf7c333fd38d72869ab3dd808641a5535d8f72063c2961aa575c2420dfa51c2f98a3ab4152b28c
|
@@ -75,8 +75,15 @@ function ktSetParam(name, value) {
|
|
75
75
|
var paramContainer = ktFindParamContainer(name);
|
76
76
|
if(value) {
|
77
77
|
if(! paramContainer) { // we create the param for kt_activation_keys
|
78
|
-
$(
|
79
|
-
|
78
|
+
var addParameterButton = $('#parameters').find('.btn-primary');
|
79
|
+
addParameterButton.click();
|
80
|
+
var directionOfAddedItems = addParameterButton.attr('direction');
|
81
|
+
var paramContainer = $('#parameters').find('.fields');
|
82
|
+
if(directionOfAddedItems === 'append'){
|
83
|
+
paramContainer = paramContainer.last();
|
84
|
+
} else {
|
85
|
+
paramContainer = paramContainer.first();
|
86
|
+
}
|
80
87
|
paramContainer.find("input[name*='name']").val(name);
|
81
88
|
}
|
82
89
|
paramContainer.find("textarea").val(value);
|
@@ -177,6 +177,9 @@ module Katello
|
|
177
177
|
end
|
178
178
|
end
|
179
179
|
response.headers['Content-Type'] = media_type
|
180
|
+
length = manifest_response.try(:body).try(:size)
|
181
|
+
length ||= 0
|
182
|
+
response.header['Content-Length'] = "#{length}"
|
180
183
|
render json: manifest_response
|
181
184
|
end
|
182
185
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Katello
|
2
|
+
class Api::V2::AlternateContentSourcesBulkActionsController < Api::V2::ApiController
|
3
|
+
before_action :find_alternate_content_sources
|
4
|
+
|
5
|
+
api :PUT, '/alternate_content_sources/bulk/destroy', N_('Destroy one or more alternate content sources')
|
6
|
+
param :ids, Array, desc: N_('List of alternate content source IDs'), required: true
|
7
|
+
def destroy_alternate_content_sources
|
8
|
+
deletable_alternate_content_sources = @alternate_content_sources.deletable
|
9
|
+
|
10
|
+
if deletable_alternate_content_sources.empty?
|
11
|
+
msg = _("Unable to delete any alternate content source. You either do not have the permission to"\
|
12
|
+
" delete, or none of the alternate content sources exist.")
|
13
|
+
fail HttpErrors::UnprocessableEntity, msg
|
14
|
+
end
|
15
|
+
task = async_task(::Actions::BulkAction,
|
16
|
+
::Actions::Katello::AlternateContentSource::Destroy,
|
17
|
+
deletable_alternate_content_sources)
|
18
|
+
respond_for_async :resource => task
|
19
|
+
end
|
20
|
+
|
21
|
+
api :POST, '/alternate_content_sources/bulk/refresh', N_('Refresh alternate content sources')
|
22
|
+
param :ids, Array, desc: N_('List of alternate content source IDs'), required: true
|
23
|
+
def refresh_alternate_content_sources
|
24
|
+
refreshable_alternate_content_sources = @alternate_content_sources.editable
|
25
|
+
if refreshable_alternate_content_sources.empty?
|
26
|
+
msg = _("Unable to refresh any alternate content source. You either do not have the permission to"\
|
27
|
+
" refresh, or none of the alternate content sources exist.")
|
28
|
+
fail HttpErrors::UnprocessableEntity, msg
|
29
|
+
else
|
30
|
+
task = async_task(::Actions::BulkAction,
|
31
|
+
::Actions::Katello::AlternateContentSource::Refresh,
|
32
|
+
refreshable_alternate_content_sources)
|
33
|
+
respond_for_async resource: task
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def find_alternate_content_sources
|
40
|
+
params.require(:ids)
|
41
|
+
@alternate_content_sources = AlternateContentSource.readable.where(id: params[:ids])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -2,8 +2,10 @@ module Katello
|
|
2
2
|
class Api::V2::AlternateContentSourcesController < Api::V2::ApiController
|
3
3
|
include Katello::Concerns::FilteredAutoCompleteSearch
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
acs_wrap_params = AlternateContentSource.attribute_names + [:smart_proxy_ids, :smart_proxy_names]
|
6
|
+
wrap_parameters :alternate_content_source, include: acs_wrap_params
|
7
|
+
|
8
|
+
before_action :find_authorized_katello_resource, only: [:show, :update, :destroy, :refresh]
|
7
9
|
|
8
10
|
def_param_group :acs do
|
9
11
|
param :name, String, desc: N_("Name of the alternate content source")
|
@@ -11,6 +13,7 @@ module Katello
|
|
11
13
|
param :base_url, String, desc: N_('Base URL for finding alternate content'), required: false
|
12
14
|
param :subpaths, Array, desc: N_('Path suffixes for finding alternate content'), required: false
|
13
15
|
param :smart_proxy_ids, Array, desc: N_("Ids of smart proxies to associate"), required: false
|
16
|
+
param :smart_proxy_names, Array, desc: N_("Names of smart proxies to associate"), required: false
|
14
17
|
param :content_type, RepositoryTypeManager.defined_repository_types.keys & AlternateContentSource::CONTENT_TYPES, desc: N_("The content type for the Alternate Content Source"), required: false
|
15
18
|
param :alternate_content_source_type, AlternateContentSource::ACS_TYPES, desc: N_("The Alternate Content Source type")
|
16
19
|
param :upstream_username, String, desc: N_("Basic authentication username"), required: false
|
@@ -54,7 +57,8 @@ module Katello
|
|
54
57
|
api :POST, '/alternate_content_sources', N_('Create an ACS')
|
55
58
|
param_group :acs
|
56
59
|
def create
|
57
|
-
|
60
|
+
find_smart_proxies
|
61
|
+
@alternate_content_source = ::Katello::AlternateContentSource.new(acs_params.except(:smart_proxy_ids, :smart_proxy_names))
|
58
62
|
sync_task(::Actions::Katello::AlternateContentSource::Create, @alternate_content_source, @smart_proxies)
|
59
63
|
@alternate_content_source.reload
|
60
64
|
respond_for_create(resource: @alternate_content_source)
|
@@ -67,8 +71,12 @@ module Katello
|
|
67
71
|
# If a user doesn't include smart proxies in the update call, don't accidentally remove all of them.
|
68
72
|
if params[:smart_proxy_ids].nil?
|
69
73
|
@smart_proxies = @alternate_content_source.smart_proxies
|
74
|
+
elsif params[:smart_proxy_ids].empty?
|
75
|
+
@smart_proxies = []
|
76
|
+
else
|
77
|
+
find_smart_proxies
|
70
78
|
end
|
71
|
-
sync_task(::Actions::Katello::AlternateContentSource::Update, @alternate_content_source, @smart_proxies, acs_params)
|
79
|
+
sync_task(::Actions::Katello::AlternateContentSource::Update, @alternate_content_source, @smart_proxies, acs_params.except(:smart_proxy_ids))
|
72
80
|
respond_for_show(:resource => @alternate_content_source)
|
73
81
|
end
|
74
82
|
|
@@ -79,10 +87,17 @@ module Katello
|
|
79
87
|
respond_for_destroy
|
80
88
|
end
|
81
89
|
|
90
|
+
api :POST, '/alternate_content_sources/:id/refresh', N_('Refresh an alternate content source')
|
91
|
+
param :id, :number, :required => true, :desc => N_("Alternate content source ID")
|
92
|
+
def refresh
|
93
|
+
task = async_task(::Actions::Katello::AlternateContentSource::Refresh, @alternate_content_source)
|
94
|
+
respond_for_async :resource => task
|
95
|
+
end
|
96
|
+
|
82
97
|
protected
|
83
98
|
|
84
99
|
def acs_params
|
85
|
-
keys = [:name, :label, :base_url, {subpaths: []}, {smart_proxy_ids: []}, :content_type, :alternate_content_source_type,
|
100
|
+
keys = [:name, :label, :base_url, {subpaths: []}, {smart_proxy_ids: []}, {smart_proxy_names: []}, :content_type, :alternate_content_source_type,
|
86
101
|
:upstream_username, :upstream_password, :ssl_ca_cert_id, :ssl_client_cert_id, :ssl_client_key_id,
|
87
102
|
:http_proxy_id, :verify_ssl]
|
88
103
|
params.require(:alternate_content_source).permit(*keys).to_h.with_indifferent_access
|
@@ -91,7 +106,15 @@ module Katello
|
|
91
106
|
def find_smart_proxies
|
92
107
|
if params[:smart_proxy_ids]
|
93
108
|
@smart_proxies = ::SmartProxy.where(id: params[:smart_proxy_ids])
|
94
|
-
|
109
|
+
elsif params[:smart_proxy_names]
|
110
|
+
@smart_proxies = ::SmartProxy.where(name: params[:smart_proxy_names])
|
111
|
+
end
|
112
|
+
if params[:smart_proxy_ids] && @smart_proxies.length < params[:smart_proxy_ids].length
|
113
|
+
missing_smart_proxies = params[:smart_proxy_ids] - @smart_proxies.pluck(:id)
|
114
|
+
fail HttpErrors::NotFound, _("Couldn't find smart proxies with id '%s'") % missing_smart_proxies.to_sentence
|
115
|
+
elsif params[:smart_proxy_names] && @smart_proxies.length < params[:smart_proxy_names].length
|
116
|
+
missing_smart_proxies = params[:smart_proxy_names] - @smart_proxies.pluck(:name)
|
117
|
+
fail HttpErrors::NotFound, _("Couldn't find smart proxies with name '%s'") % missing_smart_proxies.to_sentence
|
95
118
|
end
|
96
119
|
end
|
97
120
|
end
|
@@ -57,7 +57,7 @@ module Katello
|
|
57
57
|
else
|
58
58
|
query
|
59
59
|
end
|
60
|
-
custom_sort = ->(sort_query) { sort_query.joins(join_query).order(order_query) }
|
60
|
+
custom_sort = ->(sort_query) { sort_query.joins(join_query).order(Arel.sql(order_query)) }
|
61
61
|
options = { resource_class: Katello::ContentView, custom_sort: custom_sort }
|
62
62
|
collection = scoped_search(query, nil, nil, options)
|
63
63
|
collection[:results] = ComponentViewPresenter.component_presenter(@view, params[:status], views: collection[:results])
|
@@ -28,7 +28,7 @@ module Katello
|
|
28
28
|
query = query.with_type(params[:content_type]) if params[:content_type]
|
29
29
|
# Use custom sort to perform the join and order since we need to order by specific content_view
|
30
30
|
# and the ORDER BY query needs access to the katello_content_view_repositories table
|
31
|
-
custom_sort = ->(sort_query) { sort_query.joins(:root).joins(join_query).order(order_query) }
|
31
|
+
custom_sort = ->(sort_query) { sort_query.joins(:root).joins(join_query).order(Arel.sql(order_query)) }
|
32
32
|
options = { resource_class: Katello::Repository, custom_sort: custom_sort }
|
33
33
|
repos = scoped_search(query, nil, nil, options)
|
34
34
|
|
@@ -420,8 +420,8 @@ module Katello
|
|
420
420
|
param 'id', String, :required => true
|
421
421
|
param 'content_unit_id', String
|
422
422
|
param 'size', String
|
423
|
-
param 'checksum', String
|
424
|
-
param 'name', String, :
|
423
|
+
param 'checksum', String
|
424
|
+
param 'name', String, :desc => N_("Needs to only be set for file repositories or docker tags")
|
425
425
|
param 'digest', String, :desc => N_("Needs to only be set for docker tags")
|
426
426
|
end
|
427
427
|
Katello::RepositoryTypeManager.generic_repository_types.each_pair do |_, repo_type|
|
@@ -439,12 +439,6 @@ module Katello
|
|
439
439
|
end
|
440
440
|
|
441
441
|
uploads = (params[:uploads] || []).map do |upload|
|
442
|
-
if upload[:checksum].nil?
|
443
|
-
fail HttpErrors::BadRequest, _('Checksum is a required parameter.')
|
444
|
-
end
|
445
|
-
if upload[:name].nil?
|
446
|
-
fail HttpErrors::BadRequest, _('Name is a required parameter.')
|
447
|
-
end
|
448
442
|
upload.permit(:id, :content_unit_id, :size, :checksum, :name, :digest).to_h
|
449
443
|
end
|
450
444
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Actions
|
2
|
+
module Katello
|
3
|
+
module AlternateContentSource
|
4
|
+
class Refresh < Actions::EntryAction
|
5
|
+
def plan(acs)
|
6
|
+
action_subject(acs)
|
7
|
+
concurrence do
|
8
|
+
acs.smart_proxies.each do |smart_proxy|
|
9
|
+
plan_action(Pulp3::Orchestration::AlternateContentSource::Refresh,
|
10
|
+
acs, smart_proxy)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
plan_self(acs_id: acs.id)
|
14
|
+
end
|
15
|
+
|
16
|
+
def finalize
|
17
|
+
acs = ::Katello::AlternateContentSource.find_by(id: input[:acs_id])
|
18
|
+
acs.update(last_refreshed: ::DateTime.now)
|
19
|
+
end
|
20
|
+
|
21
|
+
def humanized_name
|
22
|
+
_("Refresh Alternate Content Source")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -21,7 +21,7 @@ module Actions
|
|
21
21
|
full_path = if cdn_configuration.redhat_cdn?
|
22
22
|
root.product.repo_url(root.library_instance.generate_content_path)
|
23
23
|
elsif cdn_configuration.network_sync?
|
24
|
-
resource.repository_url(content_label: root.content.label)
|
24
|
+
resource.repository_url(content_label: root.content.label, arch: root.arch, major: root.major, minor: root.minor)
|
25
25
|
end
|
26
26
|
plan_action(::Actions::Katello::Repository::Update, root, url: full_path)
|
27
27
|
end
|
@@ -41,7 +41,7 @@ module Actions
|
|
41
41
|
:triggered_by => options[:triggered_by]
|
42
42
|
)
|
43
43
|
source_repositories = []
|
44
|
-
content_view.publish_repositories(options[:
|
44
|
+
content_view.publish_repositories(options[:override_components]) do |repositories|
|
45
45
|
source_repositories += [repositories]
|
46
46
|
end
|
47
47
|
|
@@ -9,7 +9,7 @@ module Actions
|
|
9
9
|
def plan(organization)
|
10
10
|
action_subject organization
|
11
11
|
manifest_update = organization.products.redhat.any?
|
12
|
-
path = "
|
12
|
+
path = File.join(::Rails.root, "tmp", "#{rand}.zip")
|
13
13
|
details = organization.owner_details
|
14
14
|
upstream = details['upstreamConsumer'].blank? ? {} : details['upstreamConsumer']
|
15
15
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Actions
|
2
2
|
module Pulp3
|
3
3
|
module AlternateContentSource
|
4
|
-
class Delete < Pulp3::
|
4
|
+
class Delete < Pulp3::AbstractAsyncTask
|
5
5
|
def plan(acs, smart_proxy)
|
6
6
|
plan_self(:acs_id => acs.id, :smart_proxy_id => smart_proxy.id)
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def invoke_external_task
|
10
10
|
acs = ::Katello::AlternateContentSource.find(input[:acs_id])
|
11
11
|
output[:response] = acs.backend_service(smart_proxy).delete_alternate_content_source
|
12
12
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Actions
|
2
2
|
module Pulp3
|
3
3
|
module AlternateContentSource
|
4
|
-
class DeleteRemote < Pulp3::
|
4
|
+
class DeleteRemote < Pulp3::AbstractAsyncTask
|
5
5
|
def plan(acs, smart_proxy)
|
6
6
|
plan_self(:acs_id => acs.id, :smart_proxy_id => smart_proxy.id)
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def invoke_external_task
|
10
10
|
acs = ::Katello::AlternateContentSource.find(input[:acs_id])
|
11
11
|
output[:response] = acs.backend_service(smart_proxy).delete_remote
|
12
12
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Actions
|
2
|
+
module Pulp3
|
3
|
+
module AlternateContentSource
|
4
|
+
class Refresh < Pulp3::AbstractAsyncTask
|
5
|
+
def plan(acs, smart_proxy)
|
6
|
+
plan_self(acs_id: acs.id, smart_proxy_id: smart_proxy.id)
|
7
|
+
end
|
8
|
+
|
9
|
+
def invoke_external_task
|
10
|
+
acs = ::Katello::AlternateContentSource.find(input[:acs_id])
|
11
|
+
output[:response] = acs.backend_service(smart_proxy).refresh
|
12
|
+
end
|
13
|
+
|
14
|
+
def rescue_strategy_for_self
|
15
|
+
# There are various reasons why refreshing fails, but not all of them are
|
16
|
+
# fatal. When failing to refresh, we continue with the task ending up
|
17
|
+
# in the warning state, but don't lock further refreshing
|
18
|
+
Dynflow::Action::Rescue::Skip
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Actions
|
2
2
|
module Pulp3
|
3
3
|
module AlternateContentSource
|
4
|
-
class Update < Pulp3::
|
4
|
+
class Update < Pulp3::AbstractAsyncTask
|
5
5
|
def plan(acs, smart_proxy)
|
6
6
|
plan_self(:acs_id => acs.id, :smart_proxy_id => smart_proxy.id)
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def invoke_external_task
|
10
10
|
acs = ::Katello::AlternateContentSource.find(input[:acs_id])
|
11
11
|
output[:response] = acs.backend_service(smart_proxy).update
|
12
12
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module Actions
|
2
2
|
module Pulp3
|
3
3
|
module AlternateContentSource
|
4
|
-
class UpdateRemote < Pulp3::
|
4
|
+
class UpdateRemote < Pulp3::AbstractAsyncTask
|
5
5
|
def plan(acs, smart_proxy)
|
6
6
|
acs.backend_service(smart_proxy).create_test_remote
|
7
7
|
plan_self(:acs_id => acs.id, :smart_proxy_id => smart_proxy.id)
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def invoke_external_task
|
11
11
|
acs = ::Katello::AlternateContentSource.find(input[:acs_id])
|
12
12
|
output[:response] = acs.backend_service(smart_proxy).update_remote
|
13
13
|
end
|
@@ -7,8 +7,6 @@ module Actions
|
|
7
7
|
sequence do
|
8
8
|
plan_action(Actions::Pulp3::AlternateContentSource::CreateRemote, acs, smart_proxy)
|
9
9
|
plan_action(Actions::Pulp3::AlternateContentSource::Create, acs, smart_proxy)
|
10
|
-
# TODO: Should the hrefs be committed to acs records in a new action? Is it okay to be in the service class methods?
|
11
|
-
# -> i.e. do we need something like SaveVersions?
|
12
10
|
end
|
13
11
|
end
|
14
12
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Actions
|
2
|
+
module Pulp3
|
3
|
+
module Orchestration
|
4
|
+
module AlternateContentSource
|
5
|
+
class Refresh < Pulp3::Abstract
|
6
|
+
def plan(acs, smart_proxy)
|
7
|
+
sequence do
|
8
|
+
plan_action(Actions::Pulp3::AlternateContentSource::Refresh, acs, smart_proxy)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -7,8 +7,6 @@ module Actions
|
|
7
7
|
sequence do
|
8
8
|
plan_action(Actions::Pulp3::AlternateContentSource::UpdateRemote, acs, smart_proxy)
|
9
9
|
plan_action(Actions::Pulp3::AlternateContentSource::Update, acs, smart_proxy)
|
10
|
-
# TODO: Should the hrefs be committed to acs records in a new action? Is it okay to be in the service class methods?
|
11
|
-
# -> i.e. do we need something like SaveVersions?
|
12
10
|
end
|
13
11
|
end
|
14
12
|
end
|
@@ -3,7 +3,6 @@ module Actions
|
|
3
3
|
module Repository
|
4
4
|
class RefreshDistribution < Pulp3::AbstractAsyncTask
|
5
5
|
include Helpers::Presenter
|
6
|
-
middleware.use Actions::Middleware::ExecuteIfContentsChanged
|
7
6
|
|
8
7
|
def plan(repository, smart_proxy, options = {})
|
9
8
|
smart_proxy = SmartProxy.unscoped.find_by(id: smart_proxy) #support bulk actions
|
@@ -16,11 +15,9 @@ module Actions
|
|
16
15
|
:repository_id => repository.id,
|
17
16
|
:smart_proxy_id => smart_proxy.id
|
18
17
|
}
|
19
|
-
refresh_options[:contents_changed] if options.key?(:contents_changed)
|
20
18
|
action = plan_self(refresh_options)
|
21
19
|
|
22
|
-
plan_action(SaveDistributionReferences, repository, smart_proxy,
|
23
|
-
action.output, :contents_changed => options[:contents_changed])
|
20
|
+
plan_action(SaveDistributionReferences, repository, smart_proxy, action.output)
|
24
21
|
end
|
25
22
|
end
|
26
23
|
|
@@ -5,7 +5,7 @@ module Actions
|
|
5
5
|
#This task creates a content unit and may or may not create a new repository version in the process
|
6
6
|
def plan(file, repository, smart_proxy, tasks, unit_type_id, options = {})
|
7
7
|
options[:file_name] = file[:filename]
|
8
|
-
options[:sha256] = file[:sha256] || Digest::SHA256.hexdigest(File.read(file[:path]))
|
8
|
+
options[:sha256] = file[:sha256] || (Digest::SHA256.hexdigest(File.read(file[:path])) if file[:path].present?)
|
9
9
|
plan_self(:repository_id => repository.id, :smart_proxy_id => smart_proxy.id, :tasks => tasks, :unit_type_id => unit_type_id, :options => options)
|
10
10
|
end
|
11
11
|
|
@@ -2,8 +2,6 @@ module Actions
|
|
2
2
|
module Pulp3
|
3
3
|
module Repository
|
4
4
|
class SaveDistributionReferences < Pulp3::Abstract
|
5
|
-
middleware.use Actions::Middleware::ExecuteIfContentsChanged
|
6
|
-
|
7
5
|
def plan(repository, smart_proxy, tasks, options = {})
|
8
6
|
plan_self(repository_id: repository.id, smart_proxy_id: smart_proxy.id, tasks: tasks, contents_changed: options[:contents_changed])
|
9
7
|
end
|
@@ -62,5 +62,10 @@ module Katello
|
|
62
62
|
conditions = sanitize_sql_for_conditions(["? #{operator} ANY (subpaths)", value_to_sql(operator, value)])
|
63
63
|
{ conditions: conditions }
|
64
64
|
end
|
65
|
+
|
66
|
+
def latest_dynflow_refresh_task
|
67
|
+
@latest_dynflow_refresh_task ||= ForemanTasks::Task::DynflowTask.where(:label => Actions::Katello::AlternateContentSource::Refresh.name).
|
68
|
+
for_resource(self).order(:started_at).last
|
69
|
+
end
|
65
70
|
end
|
66
71
|
end
|
@@ -101,6 +101,12 @@ module Katello
|
|
101
101
|
ignore_404_exception { api.alternate_content_source_api.delete(href) } if href
|
102
102
|
end
|
103
103
|
|
104
|
+
def refresh
|
105
|
+
href = smart_proxy_acs.alternate_content_source_href
|
106
|
+
# https://github.com/pulp/pulp_rpm/issues/2504
|
107
|
+
api.alternate_content_source_api.refresh(href, 'placeholder')
|
108
|
+
end
|
109
|
+
|
104
110
|
private
|
105
111
|
|
106
112
|
def insert_pulp_manifest!(subpaths)
|
@@ -24,12 +24,12 @@ module Katello
|
|
24
24
|
|
25
25
|
def initialize(metadata:)
|
26
26
|
@toc = metadata[:toc]
|
27
|
+
@gpg_keys = parse_gpg_keys(metadata[:gpg_keys]) if metadata[:gpg_keys]
|
27
28
|
@products = parse_products(metadata[:products]) if metadata[:products]
|
28
29
|
@repositories = parse_repositories(metadata[:repositories]) if metadata[:repositories]
|
29
30
|
@content_view = parse_content_view(metadata[:content_view]) if metadata[:content_view]
|
30
31
|
@content_view_version = parse_content_view_version(metadata[:content_view_version]) if metadata[:content_view_version]
|
31
32
|
@from_content_view_version = parse_content_view_version(metadata[:from_content_view_version]) if metadata[:from_content_view_version]
|
32
|
-
@gpg_keys = parse_gpg_keys(metadata[:gpg_keys]) if metadata[:gpg_keys]
|
33
33
|
end
|
34
34
|
|
35
35
|
private
|
@@ -231,11 +231,17 @@ module Katello
|
|
231
231
|
return update_distribution
|
232
232
|
end
|
233
233
|
|
234
|
-
if dist_ref
|
234
|
+
if dist && dist_ref
|
235
|
+
# If the saved distribution reference is wrong, delete it and use the existing distribution
|
236
|
+
if dist.pulp_href != dist_ref.href
|
237
|
+
dist_ref.destroy
|
238
|
+
save_distribution_references([dist.pulp_href])
|
239
|
+
end
|
235
240
|
return update_distribution
|
236
241
|
end
|
237
242
|
|
238
243
|
# Since we got this far, we need to create a new distribution
|
244
|
+
# Note: the distribution reference can't be saved yet because distribution creation is async
|
239
245
|
begin
|
240
246
|
create_distribution(relative_path)
|
241
247
|
rescue api.client_module::ApiError => e
|
@@ -253,6 +259,9 @@ module Katello
|
|
253
259
|
|
254
260
|
def create_distribution(path)
|
255
261
|
distribution_data = api.distribution_class.new(secure_distribution_options(path))
|
262
|
+
unless ::Katello::RepositoryTypeManager.find(repo.content_type).pulp3_skip_publication
|
263
|
+
fail_missing_publication(distribution_data.publication)
|
264
|
+
end
|
256
265
|
api.distributions_api.create(distribution_data)
|
257
266
|
end
|
258
267
|
|
@@ -260,9 +269,16 @@ module Katello
|
|
260
269
|
api.distributions_api.list(args).results
|
261
270
|
end
|
262
271
|
|
272
|
+
def read_distribution(href = distribution_reference.href)
|
273
|
+
ignore_404_exception { api.distributions_api.read(href) }
|
274
|
+
end
|
275
|
+
|
263
276
|
def update_distribution
|
264
277
|
if distribution_reference
|
265
278
|
options = secure_distribution_options(relative_path).except(:name)
|
279
|
+
unless ::Katello::RepositoryTypeManager.find(repo.content_type).pulp3_skip_publication
|
280
|
+
fail_missing_publication(options[:publication])
|
281
|
+
end
|
266
282
|
distribution_reference.update(:content_guard_href => options[:content_guard])
|
267
283
|
api.distributions_api.partial_update(distribution_reference.href, options)
|
268
284
|
end
|
@@ -321,6 +337,12 @@ module Katello
|
|
321
337
|
hrefs.each do |href|
|
322
338
|
pulp3_distribution_data = api.get_distribution(href)
|
323
339
|
path, content_guard_href = pulp3_distribution_data&.base_path, pulp3_distribution_data&.content_guard
|
340
|
+
if distribution_reference
|
341
|
+
found_distribution = read_distribution(distribution_reference.href)
|
342
|
+
unless found_distribution
|
343
|
+
distribution_reference.destroy
|
344
|
+
end
|
345
|
+
end
|
324
346
|
unless distribution_reference
|
325
347
|
# Ensure that duplicates won't be created in the case of a race condition
|
326
348
|
DistributionReference.where(path: path, href: href, repository_id: repo.id, content_guard_href: content_guard_href).first_or_create!
|
@@ -473,6 +495,12 @@ module Katello
|
|
473
495
|
return 0 if root.retain_package_versions_count.nil? || root.using_mirrored_content?
|
474
496
|
root.retain_package_versions_count.to_i
|
475
497
|
end
|
498
|
+
|
499
|
+
def fail_missing_publication(publication_href)
|
500
|
+
unless lookup_publication(publication_href)
|
501
|
+
fail _("The repository's publication is missing. Please run a 'complete sync' on %s." % repo.name)
|
502
|
+
end
|
503
|
+
end
|
476
504
|
end
|
477
505
|
end
|
478
506
|
end
|
@@ -2,7 +2,16 @@ object @resource
|
|
2
2
|
|
3
3
|
extends 'katello/api/v2/common/identifier'
|
4
4
|
|
5
|
-
attributes :name, :base_url, :subpaths, :content_type, :alternate_content_source_type, :smart_proxies, :upstream_username
|
5
|
+
attributes :name, :base_url, :subpaths, :content_type, :alternate_content_source_type, :smart_proxies, :upstream_username, :last_refreshed
|
6
|
+
|
7
|
+
child :latest_dynflow_refresh_task => :last_refresh do |_object|
|
8
|
+
attributes :id, :username, :started_at, :ended_at, :state, :result, :progress
|
9
|
+
node :last_refresh_words do |object|
|
10
|
+
if (object.respond_to?('started_at') && object.started_at)
|
11
|
+
time_ago_in_words(Time.parse(object.started_at.to_s))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
6
15
|
|
7
16
|
if params.key?(:include_permissions)
|
8
17
|
node :permissions do |alternate_content_source|
|
@@ -33,6 +33,18 @@ child :content_facet => :content_facet_attributes do
|
|
33
33
|
node :remote_execution_by_default do
|
34
34
|
Katello.remote_execution_by_default?
|
35
35
|
end
|
36
|
+
|
37
|
+
user = User.current # current_user is not available here
|
38
|
+
child :permissions do
|
39
|
+
node(:view_lifecycle_environments) { user.can?("view_lifecycle_environments") }
|
40
|
+
node(:view_content_views) { user.can?("view_content_views") }
|
41
|
+
node(:promote_or_remove_content_views_to_environments) { user.can?("promote_or_remove_content_views_to_environments") }
|
42
|
+
node(:view_host_collections) { user.can?("view_host_collections") }
|
43
|
+
node(:create_job_invocations) { user.can?("create_job_invocations") }
|
44
|
+
node(:view_activation_keys) { user.can?("view_activation_keys") }
|
45
|
+
node(:view_products) { user.can?("view_products") }
|
46
|
+
node(:create_bookmarks) { user.can?("create_bookmarks") }
|
47
|
+
end
|
36
48
|
end
|
37
49
|
|
38
50
|
attributes :description, :facts
|
@@ -37,6 +37,10 @@ child @resource.repositories => :repositories do
|
|
37
37
|
attributes :minor => :releasever
|
38
38
|
end
|
39
39
|
|
40
|
+
node :osRestricted do |pc|
|
41
|
+
pc.repositories&.first&.os_versions&.first
|
42
|
+
end
|
43
|
+
|
40
44
|
node :override do |pc|
|
41
45
|
pc.override if pc.respond_to? :override
|
42
46
|
end
|
data/config/routes/api/v2.rb
CHANGED
@@ -14,6 +14,10 @@ Katello::Engine.routes.draw do
|
|
14
14
|
# re-routes alphabetical
|
15
15
|
##############################
|
16
16
|
|
17
|
+
api_resources :alternate_content_sources, :only => [:index, :show, :create, :update, :destroy] do
|
18
|
+
get :auto_complete_search, :on => :collection
|
19
|
+
end
|
20
|
+
|
17
21
|
api_resources :capsules, :only => [:index, :show] do
|
18
22
|
member do
|
19
23
|
resource :content, :only => [], :controller => 'capsule_content' do
|
@@ -349,6 +353,18 @@ Katello::Engine.routes.draw do
|
|
349
353
|
##############################
|
350
354
|
##############################
|
351
355
|
|
356
|
+
api_resources :alternate_content_sources, :only => [], :constraints => { :id => /[0-9a-zA-Z\-_.]*/ } do
|
357
|
+
collection do
|
358
|
+
match '/bulk/destroy' => 'alternate_content_sources_bulk_actions#destroy_alternate_content_sources', :via => :put
|
359
|
+
match '/bulk/refresh' => 'alternate_content_sources_bulk_actions#refresh_alternate_content_sources', :via => :post
|
360
|
+
get :auto_complete_search
|
361
|
+
end
|
362
|
+
|
363
|
+
member do
|
364
|
+
post :refresh
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
352
368
|
api_resources :organizations do
|
353
369
|
api_resources :sync_plans do
|
354
370
|
member do
|
@@ -469,10 +485,6 @@ Katello::Engine.routes.draw do
|
|
469
485
|
get :auto_complete_search, :on => :collection
|
470
486
|
put :sync
|
471
487
|
end
|
472
|
-
|
473
|
-
api_resources :alternate_content_sources, :only => [:index, :show, :create, :update, :destroy] do
|
474
|
-
get :auto_complete_search, :on => :collection
|
475
|
-
end
|
476
488
|
end # module v2
|
477
489
|
end # '/api' namespace
|
478
490
|
end # '/katello' namespace
|