katello 3.4.0.2 → 3.4.1
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/host_and_hostgroup_edit.js +2 -27
- data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +3 -4
- data/app/controllers/katello/api/v2/activation_keys_controller.rb +5 -1
- data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +5 -1
- data/app/controllers/katello/api/v2/repositories_controller.rb +2 -2
- data/app/lib/actions/katello/product/create.rb +4 -0
- data/app/lib/actions/pulp/consumer/generate_applicability.rb +1 -5
- data/app/lib/actions/pulp/repository/update_importer.rb +8 -0
- data/app/lib/katello/resources/cdn.rb +20 -5
- data/app/models/katello/activation_key.rb +22 -3
- data/app/models/katello/candlepin/content.rb +2 -10
- data/app/models/katello/errata_status.rb +2 -2
- data/app/models/katello/glue/provider.rb +4 -2
- data/app/models/katello/glue/pulp/repo.rb +2 -2
- data/app/models/katello/product.rb +3 -2
- data/app/models/katello/provider.rb +0 -7
- data/app/models/katello/repository.rb +9 -0
- data/app/services/katello/candlepin/consumer.rb +22 -2
- data/app/views/foreman/smart_proxies/_content_sync.html.erb +1 -1
- data/app/views/katello/api/v2/content_facet/base.json.rabl +1 -0
- data/app/views/katello/api/v2/errata/_counts.json.rabl +10 -8
- data/app/views/katello/api/v2/hostgroups_extensions/show.json.rabl +1 -1
- data/db/seeds.d/75-job_templates.rb +6 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-repository-sets.controller.js +14 -4
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-details.html +3 -12
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-repository-sets.html +13 -10
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/api-error-handler.service.js +13 -5
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/select-action-dropdown.directive.js +45 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/select-action-dropdown.html +10 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-repository-sets.controller.js +14 -4
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-repository-sets.html +14 -12
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +2 -10
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-details.html +24 -32
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/views/docker-tag-info.html +2 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/views/host-collection-details.html +2 -11
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/views/ostree-branch-repositories.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +3 -12
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/views/product-details.html +3 -11
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html +2 -11
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-details.html +3 -12
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-products.html +1 -1
- data/lib/katello/plugin.rb +4 -4
- data/lib/katello/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a69d7fd688dc60f6918570d9a46f180c5837b95b
|
4
|
+
data.tar.gz: f59ba04326eeec8fbb1582ff99b6b118ae04de3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ba9d1e9c4b60b6cbb207bfcf911c21b08fa705e661ce855104cf23d5bacaf843dc7a685cabc179f1f3cd8fbc80140147c551f499f097970de7e1f9a360b7822
|
7
|
+
data.tar.gz: 299af24880144ecdc9b3fd6215fb26170e3f08c94aa17150721289ecd4807c5b724244342b7f7cb2865e5652f7d8d641d05df1b5f6d2a71de6b4d3f852f412fd
|
@@ -3,6 +3,8 @@ KT.hosts = {};
|
|
3
3
|
|
4
4
|
$(document).on('ContentLoad', function(){
|
5
5
|
KT.hosts.onKatelloHostEditLoad();
|
6
|
+
window.tfm.hosts.registerPluginAttributes("os",
|
7
|
+
['lifecycle_environment_id', 'content_view_id', 'environment_id', 'content_source_id', 'architecture_id']);
|
6
8
|
|
7
9
|
$("#hostgroup_lifecycle_environment_id").change(KT.hosts.fetchContentViews);
|
8
10
|
$("#host_lifecycle_environment_id").change(KT.hosts.fetchContentViews);
|
@@ -248,30 +250,3 @@ KT.hosts.set_media_selection_bindings = function() {
|
|
248
250
|
KT.hosts.set_synced_content_bindings();
|
249
251
|
KT.hosts.get_media_selector_elements().change(KT.hosts.media_selection_changed);
|
250
252
|
};
|
251
|
-
|
252
|
-
// Note we are overriding the os_selected method in foreman
|
253
|
-
// Hopefully when this gets resolved http://projects.theforeman.org/issues/14699
|
254
|
-
// This method will get backed out.
|
255
|
-
function os_selected(element){
|
256
|
-
var url = $(element).attr('data-url');
|
257
|
-
var type = $(element).attr('data-type');
|
258
|
-
var attrs = {};
|
259
|
-
attrs[type] = attribute_hash(['operatingsystem_id', 'organization_id', 'location_id', 'content_view_id',
|
260
|
-
'lifecycle_environment_id', 'content_source_id', 'architecture_id', 'hostgroup_id',
|
261
|
-
'medium_id', 'kickstart_repository_id']);
|
262
|
-
tfm.tools.showSpinner();
|
263
|
-
$.ajax({
|
264
|
-
data: attrs,
|
265
|
-
type:'post',
|
266
|
-
url: url,
|
267
|
-
complete: function(){
|
268
|
-
reloadOnAjaxComplete(element);
|
269
|
-
},
|
270
|
-
success: function(request) {
|
271
|
-
$('#media_select').html(request);
|
272
|
-
reload_host_params();
|
273
|
-
reload_puppetclass_params();
|
274
|
-
}
|
275
|
-
});
|
276
|
-
update_provisioning_image();
|
277
|
-
};
|
@@ -114,8 +114,7 @@ module Katello
|
|
114
114
|
# Note that this request comes in as content-type 'text/plain' so that
|
115
115
|
# tomcat won't parse the json. Here we just pass the plain body through to candlepin
|
116
116
|
def async_hypervisors_update
|
117
|
-
|
118
|
-
task = Katello::Resources::Candlepin::Consumer.async_hypervisors(params[:owner], raw_json)
|
117
|
+
task = Katello::Resources::Candlepin::Consumer.async_hypervisors(params[:owner], request.raw_post)
|
119
118
|
async_task(::Actions::Katello::Host::Hypervisors, nil, :task_id => task['id'])
|
120
119
|
|
121
120
|
render :json => task
|
@@ -137,7 +136,7 @@ module Katello
|
|
137
136
|
#param :date, String, :desc => N_("check-in time")
|
138
137
|
def consumer_checkin
|
139
138
|
@host.update_attributes(:last_checkin => params[:date])
|
140
|
-
Candlepin::Consumer.new(@host.subscription_facet.uuid).checkin(params[:date])
|
139
|
+
Candlepin::Consumer.new(@host.subscription_facet.uuid, @host.organization.label).checkin(params[:date])
|
141
140
|
render :json => Resources::Candlepin::Consumer.get(@host.subscription_facet.uuid)
|
142
141
|
end
|
143
142
|
|
@@ -165,7 +164,7 @@ module Katello
|
|
165
164
|
#desc 'Schedules the consumer identity certificate regeneration'
|
166
165
|
def regenerate_identity_certificates
|
167
166
|
uuid = @host.subscription_facet.uuid
|
168
|
-
Candlepin::Consumer.new(uuid).regenerate_identity_certificates
|
167
|
+
Candlepin::Consumer.new(uuid, @host.organization.label).regenerate_identity_certificates
|
169
168
|
render :json => Resources::Candlepin::Consumer.get(uuid)
|
170
169
|
end
|
171
170
|
|
@@ -131,8 +131,12 @@ module Katello
|
|
131
131
|
|
132
132
|
api :GET, "/activation_keys/:id/product_content", N_("Show content available for an activation key")
|
133
133
|
param :id, String, :desc => N_("ID of the activation key"), :required => true
|
134
|
+
param :content_access_mode_all, :bool, :desc => N_("Get all content available, not just that provided by subscriptions")
|
135
|
+
param :content_access_mode_env, :bool, :desc => N_("Limit content to just that available in the activation key's content view version")
|
134
136
|
def product_content
|
135
|
-
|
137
|
+
content_access_mode_all = ::Foreman::Cast.to_bool(params[:content_access_mode_all])
|
138
|
+
content_access_mode_env = ::Foreman::Cast.to_bool(params[:content_access_mode_env])
|
139
|
+
content = @activation_key.available_content(content_access_mode_all, content_access_mode_env)
|
136
140
|
response = {
|
137
141
|
:results => content,
|
138
142
|
:total => content.size,
|
@@ -167,8 +167,12 @@ module Katello
|
|
167
167
|
|
168
168
|
api :GET, "/hosts/:host_id/subscriptions/product_content", N_("Get content and overrides for the host")
|
169
169
|
param :host_id, String, :desc => N_("Id of the host"), :required => true
|
170
|
+
param :content_access_mode_all, :bool, :desc => N_("Get all content available, not just that provided by subscriptions")
|
171
|
+
param :content_access_mode_env, :bool, :desc => N_("Limit content to just that available in the host's content view version")
|
170
172
|
def product_content
|
171
|
-
|
173
|
+
content_access_mode_all = ::Foreman::Cast.to_bool(params[:content_access_mode_all])
|
174
|
+
content_access_mode_env = ::Foreman::Cast.to_bool(params[:content_access_mode_env])
|
175
|
+
content = @host.subscription_facet.candlepin_consumer.available_product_content(content_access_mode_all, content_access_mode_env)
|
172
176
|
overrides = @host.subscription_facet.candlepin_consumer.content_overrides
|
173
177
|
results = content.map { |product_content| Katello::ProductContentPresenter.new(product_content, overrides) }
|
174
178
|
|
@@ -366,9 +366,9 @@ module Katello
|
|
366
366
|
upload_ids = uploads.map { |upload| upload['id'] }
|
367
367
|
unit_keys = uploads.map do |upload|
|
368
368
|
if @repository.file?
|
369
|
-
upload.except('id').except('name')
|
370
|
-
else
|
371
369
|
upload.except('id')
|
370
|
+
else
|
371
|
+
upload.except('id').except('name')
|
372
372
|
end
|
373
373
|
end
|
374
374
|
|
@@ -7,11 +7,7 @@ module Actions
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def invoke_external_task
|
10
|
-
|
11
|
-
pulp_resources.consumer.regenerate_applicability_by_id(input[:uuids].first)
|
12
|
-
else
|
13
|
-
pulp_extensions.consumer.regenerate_applicability_by_ids(input[:uuids])
|
14
|
-
end
|
10
|
+
pulp_extensions.consumer.regenerate_applicability_by_ids(input[:uuids])
|
15
11
|
end
|
16
12
|
end
|
17
13
|
end
|
@@ -10,6 +10,14 @@ module Actions
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def run
|
13
|
+
# Update ssl options by themselves workaround for https://pulp.plan.io/issues/2727
|
14
|
+
ssl_ca_cert = input[:config].delete('ssl_ca_cert')
|
15
|
+
ssl_client_cert = input[:config].delete('ssl_client_cert')
|
16
|
+
ssl_client_key = input[:config].delete('ssl_client_key')
|
17
|
+
|
18
|
+
output[:response] = pulp_resources.repository.
|
19
|
+
update_importer(input[:repo_id], input[:id], :ssl_client_cert => ssl_client_cert,
|
20
|
+
:ssl_client_key => ssl_client_key, :ssl_ca_cert => ssl_ca_cert)
|
13
21
|
output[:response] = pulp_resources.repository.
|
14
22
|
update_importer(*input.values_at(:repo_id, :id, :config))
|
15
23
|
end
|
@@ -29,9 +29,16 @@ module Katello
|
|
29
29
|
options.reverse_merge!(:verify_ssl => 9)
|
30
30
|
options.assert_valid_keys(:ssl_client_key, :ssl_client_cert, :ssl_ca_file, :verify_ssl,
|
31
31
|
:product)
|
32
|
-
|
33
|
-
|
32
|
+
|
33
|
+
ca = Katello::Repository.feed_ca_file(url)
|
34
|
+
if ca && URI(url).scheme == 'https'
|
35
|
+
options.reverse_merge!(:ssl_ca_file => ca)
|
36
|
+
elsif URI(url).scheme == 'https'
|
37
|
+
store = OpenSSL::X509::Store.new
|
38
|
+
store.set_default_paths
|
39
|
+
options.reverse_merge!(:cert_store => store)
|
34
40
|
end
|
41
|
+
|
35
42
|
load_proxy_settings
|
36
43
|
@product = options[:product]
|
37
44
|
|
@@ -40,13 +47,21 @@ module Katello
|
|
40
47
|
@options = options
|
41
48
|
end
|
42
49
|
|
50
|
+
def self.redhat_cdn?(url)
|
51
|
+
url.include?(SETTINGS[:katello][:redhat_repository_url])
|
52
|
+
end
|
53
|
+
|
43
54
|
def http_downloader
|
44
55
|
net = net_http_class.new(@uri.host, @uri.port)
|
45
56
|
net.use_ssl = @uri.is_a?(URI::HTTPS)
|
46
57
|
|
47
|
-
|
48
|
-
|
49
|
-
|
58
|
+
if CdnResource.redhat_cdn?(@uri.to_s)
|
59
|
+
net.cert = @options[:ssl_client_cert]
|
60
|
+
net.key = @options[:ssl_client_key]
|
61
|
+
net.ca_file = @options[:ssl_ca_file] if @options[:ssl_ca_file]
|
62
|
+
else
|
63
|
+
net.cert_store = @options[:cert_store]
|
64
|
+
end
|
50
65
|
|
51
66
|
# NOTE: This was added because some proxies dont support SSLv23 and do not handle TLS 1.2
|
52
67
|
# Valid values in ruby 1.9.3 are 'SSLv23' or 'TLSV1'
|
@@ -101,11 +101,30 @@ module Katello
|
|
101
101
|
Rails.logger.error("Pool #{pool.id} is missing its subscription id.")
|
102
102
|
end
|
103
103
|
end
|
104
|
-
all_products.flatten
|
104
|
+
all_products.uniq.flatten
|
105
105
|
end
|
106
106
|
|
107
|
-
def
|
108
|
-
|
107
|
+
def all_products
|
108
|
+
Katello::Product.joins(:subscriptions => :pools).where(:organization_id => organization.id).enabled.uniq
|
109
|
+
end
|
110
|
+
|
111
|
+
def available_content(content_access_mode_all = false, content_access_mode_env = false)
|
112
|
+
if content_access_mode_env
|
113
|
+
return [] unless environment_id && content_view_id
|
114
|
+
version = ContentViewVersion.in_environment(environment_id).where(:content_view_id => content_view_id).first
|
115
|
+
content_view_version_id = version.id
|
116
|
+
end
|
117
|
+
|
118
|
+
if content_access_mode_all
|
119
|
+
content = all_products.flat_map do |product|
|
120
|
+
product.available_content(content_view_version_id)
|
121
|
+
end
|
122
|
+
else
|
123
|
+
content = products.flat_map do |product|
|
124
|
+
product.available_content(content_view_version_id)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
content.uniq
|
109
128
|
end
|
110
129
|
|
111
130
|
def valid_content_override_label?(content_label)
|
@@ -67,7 +67,7 @@ module Katello
|
|
67
67
|
:name => name,
|
68
68
|
:label => label,
|
69
69
|
:url => feed_url,
|
70
|
-
:feed_ca =>
|
70
|
+
:feed_ca => ::Katello::Repository.feed_ca_cert(feed_url),
|
71
71
|
:feed_cert => certificate_and_key[:cert],
|
72
72
|
:feed_key => certificate_and_key[:key],
|
73
73
|
:content_type => katello_content_type,
|
@@ -173,10 +173,6 @@ module Katello
|
|
173
173
|
""
|
174
174
|
end
|
175
175
|
end
|
176
|
-
|
177
|
-
def ca
|
178
|
-
File.read(::Katello::Resources::CDN::CdnResource.ca_file)
|
179
|
-
end
|
180
176
|
end
|
181
177
|
|
182
178
|
class DockerRepositoryMapper
|
@@ -216,7 +212,7 @@ module Katello
|
|
216
212
|
:docker_upstream_name => registry["name"],
|
217
213
|
:label => label,
|
218
214
|
:url => feed_url,
|
219
|
-
:feed_ca =>
|
215
|
+
:feed_ca => ::Katello::Repository.feed_ca_cert(feed_url),
|
220
216
|
:feed_cert => product.certificate,
|
221
217
|
:feed_key => product.key,
|
222
218
|
:content_type => ::Katello::Repository::DOCKER_TYPE,
|
@@ -251,10 +247,6 @@ module Katello
|
|
251
247
|
def relative_path
|
252
248
|
::Katello::Glue::Pulp::Repos.repo_path_from_content_path(product.organization.library, content.contentUrl)
|
253
249
|
end
|
254
|
-
|
255
|
-
def ca
|
256
|
-
File.read(::Katello::Resources::CDN::CdnResource.ca_file)
|
257
|
-
end
|
258
250
|
end
|
259
251
|
end
|
260
252
|
end
|
@@ -11,7 +11,7 @@ module Katello
|
|
11
11
|
|
12
12
|
def to_label(_options = {})
|
13
13
|
installable = Setting[:errata_status_installable]
|
14
|
-
case
|
14
|
+
case status
|
15
15
|
when NEEDED_SECURITY_ERRATA
|
16
16
|
installable ? N_("Security errata installable") : N_("Security errata applicable")
|
17
17
|
when NEEDED_ERRATA
|
@@ -26,7 +26,7 @@ module Katello
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def to_global(_options = {})
|
29
|
-
case
|
29
|
+
case status
|
30
30
|
when NEEDED_SECURITY_ERRATA
|
31
31
|
::HostStatus::Global::ERROR
|
32
32
|
when NEEDED_ERRATA
|
@@ -95,11 +95,13 @@ module Katello
|
|
95
95
|
#ca_file = '/etc/candlepin/certs/upstream/subscription.rhn.stage.redhat.com.crt'
|
96
96
|
ca_file = nil
|
97
97
|
|
98
|
-
|
98
|
+
params = {}
|
99
|
+
params[:capabilities] = Resources::Candlepin::CandlepinPing.ping['managerCapabilities'].inject([]) do |result, element|
|
99
100
|
result << {'name' => element}
|
100
101
|
end
|
102
|
+
params[:facts] = {:distributor_version => 'sat-6.3'}
|
101
103
|
Resources::Candlepin::UpstreamConsumer.update("#{url}#{upstream['uuid']}", upstream['idCert']['cert'],
|
102
|
-
upstream['idCert']['key'], ca_file,
|
104
|
+
upstream['idCert']['key'], ca_file, params)
|
103
105
|
end
|
104
106
|
|
105
107
|
def owner_upstream_export(upstream, zip_file_path, _options)
|
@@ -215,11 +215,11 @@ module Katello
|
|
215
215
|
:ssl_client_key => ueber_cert[:key],
|
216
216
|
:ssl_ca_cert => ::Cert::Certs.ca_cert
|
217
217
|
}
|
218
|
-
elsif self.try(:redhat?) && self.content_view.default?
|
218
|
+
elsif self.try(:redhat?) && self.content_view.default? && Katello::Resources::CDN::CdnResource.redhat_cdn?(url)
|
219
219
|
importer_options = {
|
220
220
|
:ssl_client_cert => self.product.certificate,
|
221
221
|
:ssl_client_key => self.product.key,
|
222
|
-
:ssl_ca_cert =>
|
222
|
+
:ssl_ca_cert => Katello::Repository.feed_ca_cert(url)
|
223
223
|
}
|
224
224
|
else
|
225
225
|
importer_options = {
|
@@ -214,9 +214,10 @@ module Katello
|
|
214
214
|
repositories.any?(&:url?)
|
215
215
|
end
|
216
216
|
|
217
|
-
def available_content
|
217
|
+
def available_content(content_view_version_id = nil)
|
218
218
|
self.productContent.select do |content|
|
219
|
-
self.repositories.subscribable.where(content_id: content.content.id)
|
219
|
+
repos = self.repositories.subscribable.where(content_id: content.content.id)
|
220
|
+
repos.exists? && (content_view_version_id.nil? || repos.where(content_view_version_id: content_view_version_id.to_i).count > 0)
|
220
221
|
end
|
221
222
|
end
|
222
223
|
|
@@ -22,7 +22,6 @@ module Katello
|
|
22
22
|
:allow_blank => false, :message => "Please select provider type from one of the following: #{TYPES.join(', ')}."}
|
23
23
|
validate :constraint_redhat_update
|
24
24
|
validate :only_one_rhn_provider
|
25
|
-
validate :only_cdn_https
|
26
25
|
validates_with Validators::KatelloNameFormatValidator, :attributes => :name
|
27
26
|
validates_with Validators::KatelloUrlFormatValidator, :if => :redhat_provider?,
|
28
27
|
:attributes => [:repository_url]
|
@@ -34,12 +33,6 @@ module Katello
|
|
34
33
|
scope :custom, -> { where(:provider_type => CUSTOM) }
|
35
34
|
scope :anonymous, -> { where(:provider_type => ANONYMOUS) }
|
36
35
|
|
37
|
-
def only_cdn_https
|
38
|
-
if repository_url.present? && repository_url.downcase.start_with?('https') && !repository_url.downcase.start_with?('https://cdn.redhat.com')
|
39
|
-
errors.add(:base, _("HTTPS URLs are not supported, with the exception of 'cdn.redhat.com'"))
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
36
|
def self.create_anonymous!(organization)
|
44
37
|
create!(:name => SecureRandom.uuid, :description => nil,
|
45
38
|
:organization => organization, :provider_type => ANONYMOUS,
|
@@ -207,6 +207,15 @@ module Katello
|
|
207
207
|
.where("#{Katello::ContentViewVersion.table_name}.content_view_id" => views.map(&:id))
|
208
208
|
end
|
209
209
|
|
210
|
+
def self.feed_ca_cert(url)
|
211
|
+
file = feed_ca_file(url)
|
212
|
+
File.read(file) if file
|
213
|
+
end
|
214
|
+
|
215
|
+
def self.feed_ca_file(url)
|
216
|
+
::Katello::Resources::CDN::CdnResource.ca_file if ::Katello::Resources::CDN::CdnResource.redhat_cdn?(url)
|
217
|
+
end
|
218
|
+
|
210
219
|
def archive?
|
211
220
|
self.environment.nil?
|
212
221
|
end
|
@@ -121,8 +121,28 @@ module Katello
|
|
121
121
|
Katello::Product.joins(:subscriptions => :pools).where("#{Katello::Pool.table_name}.cp_id" => pool_ids).enabled.uniq
|
122
122
|
end
|
123
123
|
|
124
|
-
def
|
125
|
-
|
124
|
+
def all_products
|
125
|
+
org_id = ::Katello::Host::SubscriptionFacet.find_by_uuid(self.uuid).host.organization.id
|
126
|
+
Katello::Product.joins(:subscriptions => :pools).where(:organization_id => org_id).enabled.uniq
|
127
|
+
end
|
128
|
+
|
129
|
+
def available_product_content(content_access_mode_all = false, content_access_mode_env = false)
|
130
|
+
if content_access_mode_env
|
131
|
+
host = ::Katello::Host::ContentFacet.find_by_uuid(self.uuid)
|
132
|
+
return [] unless host.lifecycle_environment_id && host.content_view_id
|
133
|
+
version = ContentViewVersion.in_environment(host.lifecycle_environment_id).where(:content_view_id => host.content_view_id).first
|
134
|
+
content_view_version_id = version.id
|
135
|
+
end
|
136
|
+
if content_access_mode_all
|
137
|
+
content = all_products.flat_map do |product|
|
138
|
+
product.available_content(content_view_version_id)
|
139
|
+
end
|
140
|
+
else
|
141
|
+
content = products.flat_map do |product|
|
142
|
+
product.available_content(content_view_version_id)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
content.uniq
|
126
146
|
end
|
127
147
|
|
128
148
|
def compliance_reasons
|
@@ -8,7 +8,7 @@
|
|
8
8
|
{{ syncTask.progressbar.value || 0 | number: 0 }}%
|
9
9
|
<a href="<%= @task_search_url %>" target="_self">
|
10
10
|
<div ng-class="{ active: isTaskInProgress(syncTask) }" class="progress progress-striped">
|
11
|
-
<span progressbar
|
11
|
+
<span uib-progressbar
|
12
12
|
animate="false"
|
13
13
|
value="syncTask.progressbar.value || 0"
|
14
14
|
type="{{ progressbarType(syncTask) }}"></span>
|
@@ -2,6 +2,7 @@ attributes :id, :uuid
|
|
2
2
|
attributes :content_view_id, :content_view_name
|
3
3
|
attributes :lifecycle_environment_id, :lifecycle_environment_name
|
4
4
|
attributes :content_source_id, :content_source_name
|
5
|
+
attributes :kickstart_repository_id
|
5
6
|
|
6
7
|
child :content_view => :content_view do
|
7
8
|
attributes :id, :name
|
@@ -1,15 +1,17 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
totals = @object.relation.group(:errata_type).count.with_indifferent_access
|
2
|
+
|
3
|
+
node :security do |_presenter|
|
4
|
+
totals[:security]
|
3
5
|
end
|
4
6
|
|
5
|
-
node :bugfix do |
|
6
|
-
|
7
|
+
node :bugfix do |_presenter|
|
8
|
+
totals[:bugfix]
|
7
9
|
end
|
8
10
|
|
9
|
-
node :enhancement do |
|
10
|
-
|
11
|
+
node :enhancement do |_presenter|
|
12
|
+
totals[:enhancement]
|
11
13
|
end
|
12
14
|
|
13
|
-
node :total do |
|
14
|
-
|
15
|
+
node :total do |_presenter|
|
16
|
+
totals.values.inject(:+)
|
15
17
|
end
|
@@ -1,3 +1,3 @@
|
|
1
1
|
object @hostgroup
|
2
2
|
extends 'api/v2/hostgroups/show'
|
3
|
-
attributes :content_source_id, :content_source_name, :content_view_id, :content_view_name, :lifecycle_environment_id, :lifecycle_environment_name
|
3
|
+
attributes :content_source_id, :content_source_name, :content_view_id, :content_view_name, :lifecycle_environment_id, :lifecycle_environment_name, :kickstart_repository_id
|
@@ -3,7 +3,12 @@ if Katello.with_remote_execution?
|
|
3
3
|
JobTemplate.without_auditing do
|
4
4
|
Dir[File.join("#{Katello::Engine.root}/app/views/foreman/job_templates/**/*.erb")].each do |template|
|
5
5
|
sync = !Rails.env.test? && Setting[:remote_execution_sync_templates]
|
6
|
-
|
6
|
+
# import! was renamed to import_raw! around 1.3.1
|
7
|
+
if JobTemplate.respond_to?('import_raw!')
|
8
|
+
JobTemplate.import_raw!(File.read(template), :default => true, :locked => true, :update => sync)
|
9
|
+
else
|
10
|
+
JobTemplate.import!(File.read(template), :default => true, :locked => true, :update => sync)
|
11
|
+
end
|
7
12
|
end
|
8
13
|
end
|
9
14
|
end
|
@@ -16,7 +16,7 @@
|
|
16
16
|
angular.module('Bastion.activation-keys').controller('ActivationKeyRepositorySetsController',
|
17
17
|
['$scope', 'translate', 'Nutupane', 'ActivationKey', 'ContentOverrideHelper', 'GlobalNotification', 'CurrentOrganization',
|
18
18
|
function ($scope, translate, Nutupane, ActivationKey, ContentOverrideHelper, GlobalNotification, CurrentOrganization) {
|
19
|
-
var
|
19
|
+
var params, saveContentOverride, success, error;
|
20
20
|
|
21
21
|
params = {
|
22
22
|
id: $scope.$stateParams.activationKeyId,
|
@@ -27,13 +27,23 @@ angular.module('Bastion.activation-keys').controller('ActivationKeyRepositorySet
|
|
27
27
|
};
|
28
28
|
|
29
29
|
$scope.controllerName = 'katello_products';
|
30
|
-
nutupane = new Nutupane(ActivationKey, params, 'repositorySets');
|
31
|
-
$scope.table = nutupane.table;
|
30
|
+
$scope.nutupane = new Nutupane(ActivationKey, params, 'repositorySets');
|
31
|
+
$scope.table = $scope.nutupane.table;
|
32
|
+
|
33
|
+
$scope.contentAccessModes = {
|
34
|
+
contentAccessModeAll: false,
|
35
|
+
contentAccessModeEnv: false
|
36
|
+
};
|
37
|
+
$scope.toggleFilters = function () {
|
38
|
+
$scope.nutupane.table.params['content_access_mode_env'] = $scope.contentAccessModes.contentAccessModeEnv;
|
39
|
+
$scope.nutupane.table.params['content_access_mode_all'] = $scope.contentAccessModes.contentAccessModeAll;
|
40
|
+
$scope.nutupane.refresh();
|
41
|
+
};
|
32
42
|
|
33
43
|
success = function () {
|
34
44
|
$scope.table.working = false;
|
35
45
|
GlobalNotification.setSuccessMessage(translate('Repository Sets settings saved successfully.'));
|
36
|
-
nutupane.refresh();
|
46
|
+
$scope.nutupane.refresh();
|
37
47
|
};
|
38
48
|
|
39
49
|
error = function (response) {
|
@@ -5,17 +5,8 @@
|
|
5
5
|
<h2>{{ activationKey.name }}</h2>
|
6
6
|
</header>
|
7
7
|
|
8
|
-
<div data-block="item-actions">
|
9
|
-
<
|
10
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
11
|
-
<span translate>Select Action</span>
|
12
|
-
</button>
|
13
|
-
|
14
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
15
|
-
<span class="caret"></span>
|
16
|
-
<span class="sr-only" translate>Toggle Dropdown</span>
|
17
|
-
</button>
|
18
|
-
|
8
|
+
<div data-block="item-actions" bst-feature-flag="custom_products">
|
9
|
+
<span select-action-dropdown>
|
19
10
|
<ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu role="menu">
|
20
11
|
<li role="menuitem" ng-hide="denied('create_activation_key')">
|
21
12
|
<a ui-sref="activation-key.copy" translate>
|
@@ -36,7 +27,7 @@
|
|
36
27
|
<div data-block="modal-header" translate>Remove Activation Key "{{ activationKey.name }}"?</div>
|
37
28
|
<div data-block="modal-body" translate>Are you sure you want to remove Activation Key "{{ activationKey.name }}"?</div>
|
38
29
|
</div>
|
39
|
-
</
|
30
|
+
</span>
|
40
31
|
</div>
|
41
32
|
|
42
33
|
<nav data-block="navigation">
|
@@ -16,17 +16,20 @@
|
|
16
16
|
ng-model="repositorySetFilter"/>
|
17
17
|
</div>
|
18
18
|
|
19
|
-
<div data-block="
|
20
|
-
<
|
21
|
-
|
22
|
-
<
|
23
|
-
|
24
|
-
|
19
|
+
<div data-block="filters">
|
20
|
+
<label class="checkbox-inline" title="{{ 'Show all Repository Sets in Organization' | translate }}">
|
21
|
+
<input type="checkbox" ng-model="contentAccessModes.contentAccessModeAll" ng-change="toggleFilters()"/>
|
22
|
+
<span translate>Show All</span>
|
23
|
+
</label>
|
24
|
+
<label class="checkbox-inline" title="{{ 'Limit Repository Sets to only those available in this Activation Key\'s Lifecycle Environment' | translate }}">
|
25
|
+
<input type="checkbox" ng-model="contentAccessModes.contentAccessModeEnv" ng-change="toggleFilters()"/>
|
26
|
+
<span translate>Limit to Environment</span>
|
27
|
+
</label>
|
28
|
+
</div>
|
25
29
|
|
26
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
27
|
-
<span class="caret"></span>
|
28
|
-
</button>
|
29
30
|
|
31
|
+
<div data-block="list-actions">
|
32
|
+
<div class="btn-group" select-action-dropdown>
|
30
33
|
<ul class="dropdown-menu-right" uib-dropdown-menu role="menu" aria-labelledby="split-button">
|
31
34
|
<li role="menuitem" ng-show="permitted('edit_activation_keys', activationKey)" ng-class="{disabled: table.numSelected === 0}">
|
32
35
|
<a ng-click="overrideToEnabled()" disable-link="table.numSelected === 0" translate>
|
@@ -82,4 +85,4 @@
|
|
82
85
|
</tbody>
|
83
86
|
</table>
|
84
87
|
</div>
|
85
|
-
</div>
|
88
|
+
</div>
|
@@ -9,7 +9,7 @@
|
|
9
9
|
* Provides common functionality in handling Katello/Foreman API Errors.
|
10
10
|
*/
|
11
11
|
function ApiErrorHandler(translate, GlobalNotification) {
|
12
|
-
|
12
|
+
function handleError(response, $scope, defaultErrorMessage) {
|
13
13
|
var hasScopeErrorMessages = $scope && $scope.hasOwnProperty('errorMessages');
|
14
14
|
|
15
15
|
if (response.hasOwnProperty('data') && response.data.hasOwnProperty('errors')) {
|
@@ -22,20 +22,28 @@
|
|
22
22
|
}
|
23
23
|
} else {
|
24
24
|
if (hasScopeErrorMessages) {
|
25
|
-
$scope.errorMessages = [
|
25
|
+
$scope.errorMessages = [defaultErrorMessage];
|
26
26
|
} else {
|
27
|
-
GlobalNotification.setErrorMessage(
|
27
|
+
GlobalNotification.setErrorMessage(defaultErrorMessage);
|
28
28
|
}
|
29
29
|
}
|
30
30
|
|
31
31
|
if ($scope && $scope.hasOwnProperty('panel')) {
|
32
32
|
$scope.panel.error = true;
|
33
33
|
}
|
34
|
+
}
|
35
|
+
|
36
|
+
this.handleGETRequestErrors = function (response, $scope) {
|
37
|
+
var defaultErrorMessage = translate('Something went wrong when retrieving the resource.');
|
38
|
+
handleError(response, $scope, defaultErrorMessage);
|
39
|
+
};
|
40
|
+
|
41
|
+
this.handlePUTRequestErrors = function (response, $scope) {
|
42
|
+
var defaultErrorMessage = translate('Something went wrong when saving the resource.');
|
43
|
+
handleError(response, $scope, defaultErrorMessage);
|
34
44
|
};
|
35
45
|
}
|
36
46
|
|
37
47
|
angular.module('Bastion.common').service('ApiErrorHandler', ApiErrorHandler);
|
38
|
-
|
39
48
|
ApiErrorHandler.$inject = ['translate', 'GlobalNotification'];
|
40
|
-
|
41
49
|
})();
|
@@ -0,0 +1,45 @@
|
|
1
|
+
(function () {
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @ngdoc directive
|
6
|
+
* @name Bastion.common.directive:selectActionDropdown
|
7
|
+
*
|
8
|
+
* @description
|
9
|
+
* Used to create a dropdown menu with a list of actions in it and the words "Select Action" on the button.
|
10
|
+
*
|
11
|
+
* Necessary because of https://github.com/angular-ui/bootstrap/issues/5841
|
12
|
+
*
|
13
|
+
* @example
|
14
|
+
* <span select-action-dropdown>
|
15
|
+
* <ul>...</ul>
|
16
|
+
* </span>
|
17
|
+
*/
|
18
|
+
function selectActionDropdown() {
|
19
|
+
return {
|
20
|
+
restrict: 'AE',
|
21
|
+
transclude: true,
|
22
|
+
scope: true,
|
23
|
+
templateUrl: 'common/views/select-action-dropdown.html',
|
24
|
+
compile: function (tElement, tAttribute, transclude) {
|
25
|
+
return function (scope, element) {
|
26
|
+
scope.status = {
|
27
|
+
isOpen: false
|
28
|
+
};
|
29
|
+
|
30
|
+
scope.toggleDropdown = function (event) {
|
31
|
+
event.preventDefault();
|
32
|
+
event.stopPropagation();
|
33
|
+
scope.status.isOpen = !scope.status.isOpen;
|
34
|
+
};
|
35
|
+
|
36
|
+
transclude(scope, function(clone) {
|
37
|
+
element.find('.btn-group').append(clone);
|
38
|
+
});
|
39
|
+
};
|
40
|
+
}
|
41
|
+
};
|
42
|
+
}
|
43
|
+
|
44
|
+
angular.module('Bastion.common').directive('selectActionDropdown', selectActionDropdown);
|
45
|
+
})();
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<div class="btn-group" uib-dropdown is-open="status.isOpen" keyboard-nav>
|
2
|
+
<button type="button" class="btn btn-default" ng-click="toggleDropdown($event)">
|
3
|
+
<span translate>Select Action</span>
|
4
|
+
</button>
|
5
|
+
|
6
|
+
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
7
|
+
<span class="caret"></span>
|
8
|
+
<span class="sr-only" translate>Toggle Dropdown</span>
|
9
|
+
</button>
|
10
|
+
</div>
|
@@ -16,7 +16,7 @@
|
|
16
16
|
angular.module('Bastion.content-hosts').controller('ContentHostRepositorySetsController',
|
17
17
|
['$scope', 'translate', 'Nutupane', 'HostSubscription', 'ContentOverrideHelper', 'GlobalNotification', 'CurrentOrganization',
|
18
18
|
function ($scope, translate, Nutupane, HostSubscription, ContentOverrideHelper, GlobalNotification, CurrentOrganization) {
|
19
|
-
var
|
19
|
+
var params, saveContentOverride, success, error;
|
20
20
|
|
21
21
|
params = {
|
22
22
|
id: $scope.$stateParams.hostId,
|
@@ -27,13 +27,23 @@ angular.module('Bastion.content-hosts').controller('ContentHostRepositorySetsCon
|
|
27
27
|
};
|
28
28
|
|
29
29
|
$scope.controllerName = 'katello_products';
|
30
|
-
nutupane = new Nutupane(HostSubscription, params, 'repositorySets');
|
31
|
-
$scope.table = nutupane.table;
|
30
|
+
$scope.nutupane = new Nutupane(HostSubscription, params, 'repositorySets');
|
31
|
+
$scope.table = $scope.nutupane.table;
|
32
|
+
|
33
|
+
$scope.contentAccessModes = {
|
34
|
+
contentAccessModeAll: false,
|
35
|
+
contentAccessModeEnv: false
|
36
|
+
};
|
37
|
+
$scope.toggleFilters = function () {
|
38
|
+
$scope.nutupane.table.params['content_access_mode_all'] = $scope.contentAccessModes.contentAccessModeAll;
|
39
|
+
$scope.nutupane.table.params['content_access_mode_env'] = $scope.contentAccessModes.contentAccessModeEnv;
|
40
|
+
$scope.nutupane.refresh();
|
41
|
+
};
|
32
42
|
|
33
43
|
success = function () {
|
34
44
|
$scope.table.working = false;
|
35
45
|
GlobalNotification.setSuccessMessage(translate('Repository Sets settings saved successfully.'));
|
36
|
-
nutupane.refresh();
|
46
|
+
$scope.nutupane.refresh();
|
37
47
|
};
|
38
48
|
|
39
49
|
error = function (response) {
|
@@ -23,17 +23,19 @@
|
|
23
23
|
ng-model="repositorySetFilter"/>
|
24
24
|
</div>
|
25
25
|
|
26
|
-
<div data-block="
|
27
|
-
<
|
28
|
-
|
29
|
-
<
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
<
|
34
|
-
|
35
|
-
|
26
|
+
<div data-block="filters">
|
27
|
+
<label class="checkbox-inline" title="{{ 'Show all Repository Sets in Organization' | translate }}">
|
28
|
+
<input type="checkbox" ng-model="contentAccessModes.contentAccessModeAll" ng-change="toggleFilters()"/>
|
29
|
+
<span translate>Show All</span>
|
30
|
+
</label>
|
31
|
+
<label class="checkbox-inline" title="{{ 'Limit Repository Sets to only those available in this Host\'s Lifecycle Environment' | translate }}">
|
32
|
+
<input type="checkbox" ng-model="contentAccessModes.contentAccessModeEnv" ng-change="toggleFilters()"/>
|
33
|
+
<span translate>Limit to Environment</span>
|
34
|
+
</label>
|
35
|
+
</div>
|
36
36
|
|
37
|
+
<div data-block="list-actions">
|
38
|
+
<span select-action-dropdown>
|
37
39
|
<ul class="dropdown-menu-right" uib-dropdown-menu role="menu" aria-labelledby="split-button">
|
38
40
|
<li role="menuitem" ng-show="permitted('edit_activation_keys', activationKey)" ng-class="{disabled: table.numSelected === 0}">
|
39
41
|
<a ng-click="overrideToEnabled()" disable-link="table.numSelected === 0" translate>
|
@@ -53,7 +55,7 @@
|
|
53
55
|
</a>
|
54
56
|
</li>
|
55
57
|
</ul>
|
56
|
-
</
|
58
|
+
</span>
|
57
59
|
</div>
|
58
60
|
|
59
61
|
<span data-block="no-rows-message" translate>
|
@@ -90,4 +92,4 @@
|
|
90
92
|
</table>
|
91
93
|
</div>
|
92
94
|
</div>
|
93
|
-
</div>
|
95
|
+
</div>
|
@@ -12,15 +12,7 @@
|
|
12
12
|
<span translate>Register Content Host</span>
|
13
13
|
</button>
|
14
14
|
|
15
|
-
<
|
16
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
17
|
-
<span translate>Select Action</span>
|
18
|
-
</button>
|
19
|
-
|
20
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
21
|
-
<span class="caret"></span>
|
22
|
-
</button>
|
23
|
-
|
15
|
+
<span select-action-dropdown>
|
24
16
|
<ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu role="menu" aria-labelledby="split-button">
|
25
17
|
<li role="menuitem" ng-show="permitted('edit_hosts')" ng-class="{disabled: table.numSelected === 0}">
|
26
18
|
<a ng-click="openHostCollectionsModal()" disable-link="table.numSelected === 0" translate>Change Host Collections</a>
|
@@ -49,7 +41,7 @@
|
|
49
41
|
<span bst-modal="performDestroyHosts()" template-url="content-hosts/bulk/views/content-hosts-bulk-destroy-modal.html"></span>
|
50
42
|
</li>
|
51
43
|
</ul>
|
52
|
-
</
|
44
|
+
</span>
|
53
45
|
</div>
|
54
46
|
|
55
47
|
<span data-block="no-rows-message" translate>
|
@@ -13,38 +13,30 @@
|
|
13
13
|
</div>
|
14
14
|
|
15
15
|
<nav data-block="item-actions">
|
16
|
-
<
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
<
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
</
|
37
|
-
</
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
<li role="menuitem" ng-hide="denied('destroy_content_views', contentView)">
|
42
|
-
<a ui-sref="content-view.deletion">
|
43
|
-
<span translate>Remove Content View</span>
|
44
|
-
</a>
|
45
|
-
</li>
|
46
|
-
</ul>
|
47
|
-
</div>
|
16
|
+
<button type="button" class="btn btn-primary" ng-hide="denied('publish_content_views', contentView)"
|
17
|
+
ui-sref="content-view.publish">
|
18
|
+
<span translate>Publish New Version</span>
|
19
|
+
</button>
|
20
|
+
|
21
|
+
<span bst-feature-flag="custom_products">
|
22
|
+
<span select-action-dropdown>
|
23
|
+
<ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu role="menu">
|
24
|
+
<li role="menuitem" ng-hide="denied('publish_content_views', contentView)">
|
25
|
+
<a ui-sref="content-view.copy">
|
26
|
+
<span translate>Copy Content View</span>
|
27
|
+
</a>
|
28
|
+
</li>
|
29
|
+
|
30
|
+
<li class="divider" ng-hide="denied('destroy_content_views', contentView)"></li>
|
31
|
+
|
32
|
+
<li role="menuitem" ng-hide="denied('destroy_content_views', contentView)">
|
33
|
+
<a ui-sref="content-view.deletion">
|
34
|
+
<span translate>Remove Content View</span>
|
35
|
+
</a>
|
36
|
+
</li>
|
37
|
+
</ul>
|
38
|
+
</span>
|
39
|
+
</span>
|
48
40
|
</nav>
|
49
41
|
|
50
42
|
<nav data-block="navigation">
|
@@ -5,14 +5,14 @@
|
|
5
5
|
<dl class="dl-horizontal dl-horizontal-left">
|
6
6
|
<dt translate>Product</dt>
|
7
7
|
<dd>
|
8
|
-
<a ui-sref="
|
8
|
+
<a ui-sref="product.info({productId: tag.product.id})">
|
9
9
|
{{ tag.product.name }}
|
10
10
|
</a>
|
11
11
|
</dd>
|
12
12
|
|
13
13
|
<dt translate>Repository</dt>
|
14
14
|
<dd>
|
15
|
-
<a ui-sref="
|
15
|
+
<a ui-sref="product.repository.manage-content.docker-manifests({productId: tag.product.id, repositoryId: tag.repository.id})">
|
16
16
|
{{ tag.repository.name }}
|
17
17
|
</a>
|
18
18
|
</dd>
|
@@ -6,16 +6,7 @@
|
|
6
6
|
</div>
|
7
7
|
|
8
8
|
<div data-block="item-actions">
|
9
|
-
<
|
10
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
11
|
-
<span translate>Select Action</span>
|
12
|
-
</button>
|
13
|
-
|
14
|
-
<button type="button" type="button" class="btn btn-default" uib-dropdown-toggle>
|
15
|
-
<span class="caret"></span>
|
16
|
-
<span class="sr-only" translate>Toggle Dropdown</span>
|
17
|
-
</button>
|
18
|
-
|
9
|
+
<span select-action-dropdown>
|
19
10
|
<ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu role="menu">
|
20
11
|
<li role="menuitem" ng-hide="denied('create_host_collections')">
|
21
12
|
<a ui-sref="host-collection.copy" translate>
|
@@ -36,7 +27,7 @@
|
|
36
27
|
<div data-block="modal-header" translate>Remove Host Collection "{{ hostCollection.name }}"?</div>
|
37
28
|
<div data-block="modal-body" translate>Are you sure you want to remove Host Collection "{{ hostCollection.name }}"?</div>
|
38
29
|
</div>
|
39
|
-
</
|
30
|
+
</span>
|
40
31
|
</div>
|
41
32
|
|
42
33
|
<nav data-block="navigation" ng-hide="isState('host-collection.copy')">
|
@@ -5,17 +5,8 @@
|
|
5
5
|
<h2 translate>{{ repository.name }}</h2>
|
6
6
|
</header>
|
7
7
|
|
8
|
-
<div data-block="item-actions">
|
9
|
-
<
|
10
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
11
|
-
<span translate>Select Action</span>
|
12
|
-
</button>
|
13
|
-
|
14
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
15
|
-
<span class="caret"></span>
|
16
|
-
<span class="sr-only" translate>Toggle Dropdown</span>
|
17
|
-
</button>
|
18
|
-
|
8
|
+
<div data-block="item-actions" bst-feature-flag="custom_products">
|
9
|
+
<span select-action-dropdown>
|
19
10
|
<ul class="dropdown-menu-right" uib-dropdown-menu role="menu">
|
20
11
|
<li role="menuitem" ng-hide="hideSyncButton(repository, false)" ng-class="{disabled: disableSyncLink()}">
|
21
12
|
<a ng-click="syncRepository(repository)" disable-link="disableSyncLink()" translate>
|
@@ -92,7 +83,7 @@
|
|
92
83
|
<div data-block="modal-header" translate>Remove Repository "{{ repository.name }}"?</div>
|
93
84
|
<div data-block="modal-body" translate>Are you sure you want to remove repository "{{ repository.name }}"?</div>
|
94
85
|
</div>
|
95
|
-
</
|
86
|
+
</span>
|
96
87
|
</div>
|
97
88
|
|
98
89
|
<div data-block="content">
|
@@ -5,16 +5,8 @@
|
|
5
5
|
<h2 translate>{{ product.name }}</h2>
|
6
6
|
</header>
|
7
7
|
|
8
|
-
<nav data-block="item-actions">
|
9
|
-
<
|
10
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
11
|
-
<span translate>Select Action</span>
|
12
|
-
</button>
|
13
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
14
|
-
<span class="caret"></span>
|
15
|
-
<span class="sr-only" translate>Toggle Dropdown</span>
|
16
|
-
</button>
|
17
|
-
|
8
|
+
<nav data-block="item-actions" bst-feature-flag="custom_products">
|
9
|
+
<span select-action-dropdown>
|
18
10
|
<ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu role="menu">
|
19
11
|
<li role="menuitem" ng-hide="denied('sync_products', product)">
|
20
12
|
<a ng-click="syncProduct()">
|
@@ -58,7 +50,7 @@
|
|
58
50
|
</span>
|
59
51
|
</li>
|
60
52
|
</ul>
|
61
|
-
</
|
53
|
+
</span>
|
62
54
|
|
63
55
|
<div bst-modal="removeProduct(product)" model="product">
|
64
56
|
<div data-block="modal-header" translate>Remove Product "{{ product.name }}"?</div>
|
data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html
CHANGED
@@ -21,16 +21,7 @@
|
|
21
21
|
<span translate>Repo Discovery</span>
|
22
22
|
</button>
|
23
23
|
|
24
|
-
<
|
25
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
26
|
-
<span translate>Select Action</span>
|
27
|
-
</button>
|
28
|
-
|
29
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
30
|
-
<span class="caret"></span>
|
31
|
-
<span class="sr-only" translate>Toggle Dropdown</span>
|
32
|
-
</button>
|
33
|
-
|
24
|
+
<span select-action-dropdown>
|
34
25
|
<ul class="dropdown-menu-right" uib-dropdown-menu role="menu" aria-labelledby="split-button">
|
35
26
|
<li role="menuitem" ng-class="{disabled: table.numSelected === 0}">
|
36
27
|
<a ng-click="syncProducts()" ng-show="permitted('sync_products')" disable-link="table.numSelected === 0" translate>
|
@@ -71,7 +62,7 @@
|
|
71
62
|
</div>
|
72
63
|
</li>
|
73
64
|
</ul>
|
74
|
-
</
|
65
|
+
</span>
|
75
66
|
</div>
|
76
67
|
|
77
68
|
<span data-block="no-rows-message" translate>
|
@@ -13,17 +13,8 @@
|
|
13
13
|
</div>
|
14
14
|
</div>
|
15
15
|
|
16
|
-
<nav data-block="item-actions">
|
17
|
-
<
|
18
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
19
|
-
<span translate>Select Action</span>
|
20
|
-
</button>
|
21
|
-
|
22
|
-
<button type="button" class="btn btn-default" uib-dropdown-toggle>
|
23
|
-
<span class="caret"></span>
|
24
|
-
<span class="sr-only" translate>Toggle Dropdown</span>
|
25
|
-
</button>
|
26
|
-
|
16
|
+
<nav data-block="item-actions" bst-feature-flag="custom_products">
|
17
|
+
<span select-action-dropdown>
|
27
18
|
<ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu role="menu">
|
28
19
|
<li role="menuitem" ng-hide="denied('sync_products')">
|
29
20
|
<a ng-click="runSyncPlan()">
|
@@ -44,7 +35,7 @@
|
|
44
35
|
<div data-block="modal-header" translate>Remove Sync Plan "{{ syncPlan.name }}"?</div>
|
45
36
|
<div data-block="modal-body" translate>Are you sure you want to remove Sync Plan "{{ syncPlan.name }}"?</div>
|
46
37
|
</div>
|
47
|
-
</
|
38
|
+
</span>
|
48
39
|
</nav>
|
49
40
|
|
50
41
|
<nav data-block="navigation">
|
@@ -63,7 +63,7 @@
|
|
63
63
|
<tbody>
|
64
64
|
<tr bst-table-row ng-repeat="product in table.rows" row-select="product">
|
65
65
|
<td bst-table-cell>
|
66
|
-
<a ui-sref="
|
66
|
+
<a ui-sref="product.info({productId: product.id})">
|
67
67
|
{{ product.name }}
|
68
68
|
</a>
|
69
69
|
</td>
|
data/lib/katello/plugin.rb
CHANGED
@@ -244,13 +244,13 @@ Foreman::Plugin.register :katello do
|
|
244
244
|
|
245
245
|
add_controller_action_scope(HostsController, :index) do |base_scope|
|
246
246
|
base_scope
|
247
|
-
.preload(:content_view, :lifecycle_environment, :subscription_facet
|
248
|
-
.preload(content_facet: [:bound_repositories, :
|
247
|
+
.preload(:content_view, :lifecycle_environment, :subscription_facet)
|
248
|
+
.preload(content_facet: [:bound_repositories, :content_view, :lifecycle_environment])
|
249
249
|
end
|
250
250
|
|
251
251
|
add_controller_action_scope(Api::V2::HostsController, :index) do |base_scope|
|
252
252
|
base_scope
|
253
|
-
.preload(:content_view, :lifecycle_environment, :subscription_facet
|
254
|
-
.preload(content_facet: [:bound_repositories, :
|
253
|
+
.preload(:content_view, :lifecycle_environment, :subscription_facet)
|
254
|
+
.preload(content_facet: [:bound_repositories, :content_view, :lifecycle_environment])
|
255
255
|
end
|
256
256
|
end
|
data/lib/katello/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: katello
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.4.
|
4
|
+
version: 3.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- N/A
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -1435,7 +1435,9 @@ files:
|
|
1435
1435
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/capsules/capsules.module.js
|
1436
1436
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/common/api-error-handler.service.js
|
1437
1437
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/common/common.module.js
|
1438
|
+
- engines/bastion_katello/app/assets/javascripts/bastion_katello/common/select-action-dropdown.directive.js
|
1438
1439
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/registration.html
|
1440
|
+
- engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/select-action-dropdown.html
|
1439
1441
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/subscription-add-or-remove.html
|
1440
1442
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-environment-modal.controller.js
|
1441
1443
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-errata-modal.controller.js
|