katello 3.14.0.rc2 → 3.14.0
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/controllers/katello/api/v2/subscriptions_controller.rb +3 -2
- data/app/models/katello/ping.rb +14 -18
- data/app/services/katello/candlepin_event_listener.rb +20 -44
- data/app/services/katello/candlepin_listening_service.rb +6 -3
- data/app/services/katello/event_daemon.rb +46 -3
- data/app/services/katello/event_monitor/poller_thread.rb +18 -13
- data/app/services/katello/pulp/importer_comparison.rb +28 -0
- data/app/services/katello/pulp/repository.rb +2 -7
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/content-access-mode-banner.directive.js +22 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +5 -0
- data/lib/katello/tasks/reimport.rake +1 -1
- data/lib/katello/version.rb +1 -1
- data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +72 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionNameFormatter.js +23 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +3 -9
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +21 -1
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +92 -0
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4753e9076eca5c39d6930c003dd67a5cbd01bbbd97b47bef6e81a74d6e576ceb
|
4
|
+
data.tar.gz: 561e374445d3f901344a42d4e08701b8bd5d48ce57802bb477a296959ccfc0f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8741afc15f04b339ca2fd45f537bea05e9ae8bc1b5de956620702781cda16ca95d64cb88641dd2118a4247585d656d0075738af58ddca50e959d123482ccd29d
|
7
|
+
data.tar.gz: b18ce1b57e91ca577393412f27f20718683abbc1f53ed3645e9df47c3bd762f63f0221b5b1a118b3101d0f4cbe1ee69a4a65cba460a76f33cb92d2411c43eaec
|
@@ -77,8 +77,9 @@ module Katello
|
|
77
77
|
def show
|
78
78
|
org_id = Organization.current&.id
|
79
79
|
@resource = Katello::Pool.with_identifier(params[:id])
|
80
|
-
|
81
|
-
|
80
|
+
fail ActiveRecord::RecordNotFound, N_('Subscription not found') unless @resource
|
81
|
+
if @resource.organization_id != org_id && !User.current.organizations&.pluck(:id)&.include?(@resource.organization_id)
|
82
|
+
fail ActiveRecord::RecordNotFound, N_('This subscription is not relevant to the current user and organization.')
|
82
83
|
end
|
83
84
|
respond(:resource => @resource)
|
84
85
|
end
|
data/app/models/katello/ping.rb
CHANGED
@@ -2,7 +2,6 @@ module Katello
|
|
2
2
|
class Ping
|
3
3
|
OK_RETURN_CODE = 'ok'.freeze
|
4
4
|
FAIL_RETURN_CODE = 'FAIL'.freeze
|
5
|
-
WARN_RETURN_CODE = 'WARN'.freeze
|
6
5
|
PACKAGES = %w(katello candlepin pulp qpid foreman tfm hammer).freeze
|
7
6
|
|
8
7
|
class << self
|
@@ -33,7 +32,7 @@ module Katello
|
|
33
32
|
# set overall status result code
|
34
33
|
result = {:services => result}
|
35
34
|
result[:services].each_value do |v|
|
36
|
-
result[:status] =
|
35
|
+
result[:status] = v[:status] == OK_RETURN_CODE ? OK_RETURN_CODE : FAIL_RETURN_CODE
|
37
36
|
end
|
38
37
|
result
|
39
38
|
end
|
@@ -45,31 +44,28 @@ module Katello
|
|
45
44
|
}
|
46
45
|
end
|
47
46
|
|
48
|
-
def
|
49
|
-
|
47
|
+
def event_daemon_status(status, result)
|
48
|
+
running = status&.dig(:running)
|
49
|
+
|
50
|
+
if running
|
51
|
+
result[:message] = "#{status[:processed_count]} Processed, #{status[:failed_count]} Failed"
|
52
|
+
else
|
53
|
+
result[:status] = FAIL_RETURN_CODE
|
54
|
+
result[:message] = _("Not running")
|
55
|
+
end
|
50
56
|
end
|
51
57
|
|
52
58
|
def ping_katello_events(result)
|
53
59
|
exception_watch(result) do
|
54
|
-
status = Katello::EventMonitor::PollerThread.status
|
55
|
-
|
56
|
-
if status[:queue_depth] && status[:queue_depth] > 1000
|
57
|
-
result[:status] = WARN_RETURN_CODE
|
58
|
-
end
|
59
|
-
|
60
|
-
result[:message] = daemon_status_message(status)
|
60
|
+
status = Katello::EventMonitor::PollerThread.status(refresh: false)
|
61
|
+
event_daemon_status(status, result)
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
64
65
|
def ping_candlepin_events(result)
|
65
66
|
exception_watch(result) do
|
66
|
-
status = Katello::CandlepinEventListener.status
|
67
|
-
|
68
|
-
if status[:queue_depth] && status[:queue_depth] > 1000
|
69
|
-
result[:status] = WARN_RETURN_CODE
|
70
|
-
end
|
71
|
-
|
72
|
-
result[:message] = daemon_status_message(status)
|
67
|
+
status = Katello::CandlepinEventListener.status(refresh: false)
|
68
|
+
event_daemon_status(status, result)
|
73
69
|
end
|
74
70
|
end
|
75
71
|
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Katello
|
2
2
|
class CandlepinEventListener
|
3
|
-
|
4
|
-
FAILED_COUNT_CACHE_KEY = 'candlepin_events_failed'.freeze
|
5
|
-
AMQP_QUEUE_NAME = 'event.org.candlepin.audit.AMQPBusPublisher'.freeze
|
3
|
+
STATUS_CACHE_KEY = 'candlepin_events_status'.freeze
|
6
4
|
|
7
5
|
CandlepinEvent = Struct.new(:message_id, :subject, :content)
|
8
6
|
|
@@ -10,38 +8,17 @@ module Katello
|
|
10
8
|
@failed_count = 0
|
11
9
|
@processed_count = 0
|
12
10
|
|
13
|
-
def self.start_service
|
14
|
-
loop do
|
15
|
-
begin
|
16
|
-
result = Katello::CandlepinListeningService.instance.start
|
17
|
-
|
18
|
-
break if result == :connected
|
19
|
-
|
20
|
-
@logger.info("Attempting to restart Candlepin Listening Service")
|
21
|
-
sleep 5
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
11
|
def self.run
|
27
|
-
|
12
|
+
initialize_listening_service
|
28
13
|
|
29
|
-
|
30
|
-
|
31
|
-
Rails.application.executor.wrap do
|
32
|
-
initialize_listening_service
|
33
|
-
start_service
|
14
|
+
result = Katello::CandlepinListeningService.instance.start
|
15
|
+
return unless result == :connected
|
34
16
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
elsif message[:error]
|
41
|
-
@logger.error("Disconnected from Candlepin Listening Service, reconnecting")
|
42
|
-
start_service
|
43
|
-
end
|
44
|
-
end
|
17
|
+
Katello::CandlepinListeningService.instance.poll_for_messages do |message|
|
18
|
+
if message[:result]
|
19
|
+
result = message[:result]
|
20
|
+
event = CandlepinEvent.new(result.message_id, result.subject, result.content)
|
21
|
+
act_on_event(event)
|
45
22
|
end
|
46
23
|
end
|
47
24
|
rescue => e
|
@@ -50,17 +27,20 @@ module Katello
|
|
50
27
|
raise e
|
51
28
|
end
|
52
29
|
|
53
|
-
def self.status
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
30
|
+
def self.status(refresh: true)
|
31
|
+
Rails.cache.fetch(STATUS_CACHE_KEY, force: refresh) do
|
32
|
+
{
|
33
|
+
processed_count: @processed_count,
|
34
|
+
failed_count: @failed_count,
|
35
|
+
running: Katello::CandlepinListeningService.instance&.running? || false
|
36
|
+
}
|
37
|
+
end
|
59
38
|
end
|
60
39
|
|
61
40
|
def self.reset_status
|
62
|
-
|
63
|
-
|
41
|
+
@processed_count = 0
|
42
|
+
@failed_count = 0
|
43
|
+
Rails.cache.delete(STATUS_CACHE_KEY)
|
64
44
|
end
|
65
45
|
|
66
46
|
def self.act_on_event(event)
|
@@ -68,11 +48,8 @@ module Katello
|
|
68
48
|
::Katello::Candlepin::EventHandler.new(@logger).handle(event)
|
69
49
|
end
|
70
50
|
@processed_count += 1
|
71
|
-
|
72
|
-
Rails.cache.write(PROCESSED_COUNT_CACHE_KEY, @processed_count, expires_in: 24.hours)
|
73
51
|
rescue => e
|
74
52
|
@failed_count += 1
|
75
|
-
Rails.cache.write(FAILED_COUNT_CACHE_KEY, @failed_count, expires_in: 24.hours)
|
76
53
|
@logger.error("Error handling Candlepin event")
|
77
54
|
@logger.error(e.message)
|
78
55
|
@logger.error(e.backtrace.join("\n"))
|
@@ -99,7 +76,6 @@ module Katello
|
|
99
76
|
|
100
77
|
def self.close
|
101
78
|
Katello::CandlepinListeningService.close
|
102
|
-
@thread.kill if @thread
|
103
79
|
reset_status
|
104
80
|
end
|
105
81
|
end
|
@@ -64,10 +64,13 @@ module Katello
|
|
64
64
|
@receiver = @session.create_receiver(@address)
|
65
65
|
@logger.info("Candlepin Event Listener started")
|
66
66
|
end
|
67
|
-
|
68
67
|
:connected
|
69
68
|
rescue => e
|
70
|
-
|
69
|
+
@logger.error("Unable to establish candlepin events connection: #{e.message}")
|
70
|
+
end
|
71
|
+
|
72
|
+
def running?
|
73
|
+
@connection.open? && @thread&.status || false
|
71
74
|
end
|
72
75
|
|
73
76
|
def fetch_message
|
@@ -83,7 +86,7 @@ module Katello
|
|
83
86
|
message = fetch_message
|
84
87
|
yield(message) if block_given?
|
85
88
|
|
86
|
-
sleep SLEEP_INTERVAL if message[:result].nil?
|
89
|
+
sleep SLEEP_INTERVAL if message[:result].nil?
|
87
90
|
end
|
88
91
|
end
|
89
92
|
end
|
@@ -1,5 +1,45 @@
|
|
1
1
|
module Katello
|
2
2
|
class EventDaemon
|
3
|
+
class Monitor
|
4
|
+
def initialize(service_classes)
|
5
|
+
@service_classes = service_classes
|
6
|
+
end
|
7
|
+
|
8
|
+
def start
|
9
|
+
error = nil
|
10
|
+
status = nil
|
11
|
+
loop do
|
12
|
+
check_services(error, status)
|
13
|
+
sleep 15
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_services(error, status)
|
18
|
+
@service_classes.each do |service_class|
|
19
|
+
begin
|
20
|
+
status = service_class.status
|
21
|
+
rescue => error
|
22
|
+
Rails.logger.error("Error occurred while pinging #{service_class}")
|
23
|
+
Rails.logger.error(error.message)
|
24
|
+
Rails.logger.error(error.backtrace.join('\n'))
|
25
|
+
ensure
|
26
|
+
if error || !status&.dig(:running)
|
27
|
+
begin
|
28
|
+
service_class.close
|
29
|
+
service_class.run
|
30
|
+
rescue => error
|
31
|
+
Rails.logger.error("Error occurred while starting #{service_class}")
|
32
|
+
Rails.logger.error(error.message)
|
33
|
+
Rails.logger.error(error.backtrace.join('\n'))
|
34
|
+
ensure
|
35
|
+
error = nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
3
43
|
class << self
|
4
44
|
def initialize
|
5
45
|
FileUtils.touch(lock_file)
|
@@ -37,6 +77,7 @@ module Katello
|
|
37
77
|
|
38
78
|
def stop
|
39
79
|
return unless pid == Process.pid
|
80
|
+
@monitor_thread.kill
|
40
81
|
services.values.each(&:close)
|
41
82
|
File.unlink(pid_file) if pid_file && File.exist?(pid_file)
|
42
83
|
end
|
@@ -49,7 +90,7 @@ module Katello
|
|
49
90
|
lockfile.flock(File::LOCK_EX)
|
50
91
|
return if started? # ensure it wasn't started while we waited for the lock
|
51
92
|
|
52
|
-
|
93
|
+
start_monitor_thread
|
53
94
|
write_pid_file
|
54
95
|
|
55
96
|
at_exit do
|
@@ -69,8 +110,10 @@ module Katello
|
|
69
110
|
false
|
70
111
|
end
|
71
112
|
|
72
|
-
def
|
73
|
-
|
113
|
+
def start_monitor_thread
|
114
|
+
@monitor_thread = Thread.new do
|
115
|
+
Monitor.new(services.values).start
|
116
|
+
end
|
74
117
|
end
|
75
118
|
|
76
119
|
def runnable?
|
@@ -2,8 +2,7 @@ module Katello
|
|
2
2
|
module EventMonitor
|
3
3
|
class PollerThread
|
4
4
|
SLEEP_INTERVAL = 3
|
5
|
-
|
6
|
-
FAILED_COUNT_CACHE_KEY = 'katello_events_failed'.freeze
|
5
|
+
STATUS_CACHE_KEY = 'katello_events_status'.freeze
|
7
6
|
|
8
7
|
cattr_accessor :instance
|
9
8
|
|
@@ -25,17 +24,14 @@ module Katello
|
|
25
24
|
instance.poll_for_events
|
26
25
|
end
|
27
26
|
|
28
|
-
def self.status
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
queue_depth: Katello::EventQueue.queue_depth
|
33
|
-
}
|
27
|
+
def self.status(refresh: true)
|
28
|
+
Rails.cache.fetch(STATUS_CACHE_KEY, force: refresh) do
|
29
|
+
instance&.status
|
30
|
+
end
|
34
31
|
end
|
35
32
|
|
36
33
|
def self.reset_status
|
37
|
-
Rails.cache.
|
38
|
-
Rails.cache.write(FAILED_COUNT_CACHE_KEY, 0)
|
34
|
+
Rails.cache.delete(STATUS_CACHE_KEY)
|
39
35
|
end
|
40
36
|
|
41
37
|
def initialize(logger = nil)
|
@@ -49,6 +45,18 @@ module Katello
|
|
49
45
|
@thread.kill if @thread
|
50
46
|
end
|
51
47
|
|
48
|
+
def running?
|
49
|
+
@thread&.status || false
|
50
|
+
end
|
51
|
+
|
52
|
+
def status
|
53
|
+
{
|
54
|
+
processed_count: @processed_count,
|
55
|
+
failed_count: @failed_count,
|
56
|
+
running: running?
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
52
60
|
def run_event(event)
|
53
61
|
@logger.debug("event_queue_event: type=#{event.event_type}, object_id=#{event.object_id}")
|
54
62
|
|
@@ -60,8 +68,6 @@ module Katello
|
|
60
68
|
end
|
61
69
|
rescue => e
|
62
70
|
@failed_count += 1
|
63
|
-
Rails.cache.write(FAILED_COUNT_CACHE_KEY, @failed_count, expires_in: 24.hours)
|
64
|
-
|
65
71
|
@logger.error("event_queue_error: type=#{event.event_type}, object_id=#{event.object_id}")
|
66
72
|
@logger.error(e.message)
|
67
73
|
@logger.error(e.backtrace.join("\n"))
|
@@ -89,7 +95,6 @@ module Katello
|
|
89
95
|
until (event = ::Katello::EventQueue.next_event).nil?
|
90
96
|
run_event(event)
|
91
97
|
@processed_count += 1
|
92
|
-
Rails.cache.write(PROCESSED_COUNT_CACHE_KEY, @processed_count, expires_in: 24.hours)
|
93
98
|
end
|
94
99
|
end
|
95
100
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Katello
|
2
|
+
module Pulp
|
3
|
+
module ImporterComparison
|
4
|
+
def importer_matches?(generated_importer, capsule_importer)
|
5
|
+
if capsule_importer.try(:[], 'importer_type_id') != generated_importer.id
|
6
|
+
return false
|
7
|
+
end
|
8
|
+
|
9
|
+
generated_config = generated_importer.config
|
10
|
+
capsule_config = capsule_importer['config']
|
11
|
+
if generated_config['proxy_host'] == ""
|
12
|
+
proxy_keys = %w(proxy_host proxy_username proxy_password)
|
13
|
+
proxy_keys.each do |key|
|
14
|
+
generated_config.delete(key)
|
15
|
+
capsule_config.delete(key)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
if generated_config['proxy_password'] == "" && capsule_config['proxy_password'] == "*****"
|
20
|
+
generated_config.delete('proxy_password')
|
21
|
+
capsule_config.delete('proxy_password')
|
22
|
+
end
|
23
|
+
|
24
|
+
generated_config.compact == capsule_config.compact
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Katello
|
2
2
|
module Pulp
|
3
3
|
class Repository < ::Actions::Pulp::Abstract
|
4
|
+
include ImporterComparison
|
4
5
|
attr_accessor :repo, :input
|
5
6
|
attr_accessor :smart_proxy
|
6
7
|
delegate :root, to: :repo
|
@@ -139,7 +140,7 @@ module Katello
|
|
139
140
|
repo_details = backend_data
|
140
141
|
return unless repo_details
|
141
142
|
capsule_importer = repo_details["importers"][0]
|
142
|
-
!importer_matches?(capsule_importer)
|
143
|
+
!importer_matches?(generate_importer, capsule_importer)
|
143
144
|
end
|
144
145
|
|
145
146
|
def needs_distributor_updates?
|
@@ -319,12 +320,6 @@ module Katello
|
|
319
320
|
generated.compact == actual.compact
|
320
321
|
end
|
321
322
|
|
322
|
-
def importer_matches?(capsule_importer)
|
323
|
-
generated_importer = generate_importer
|
324
|
-
capsule_importer.try(:[], 'importer_type_id') == generated_importer.id &&
|
325
|
-
generated_importer.config.compact == capsule_importer['config'].compact
|
326
|
-
end
|
327
|
-
|
328
323
|
def distributors_match?(capsule_distributors)
|
329
324
|
generated_distributor_configs = generate_distributors
|
330
325
|
generated_distributor_configs.all? do |gen_dist|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
/**
|
2
|
+
* @ngdoc directive
|
3
|
+
* @name Bastion.subscriptions:contentAccessModeBanner
|
4
|
+
*
|
5
|
+
* @requires contentAccessMode
|
6
|
+
*
|
7
|
+
* @description
|
8
|
+
* Component for showing information about content access mode (whether content is
|
9
|
+
* allowed with or without a subscription)
|
10
|
+
*/
|
11
|
+
angular.module('Bastion.subscriptions').directive('contentAccessModeBanner',
|
12
|
+
['contentAccessMode',
|
13
|
+
function (contentAccessMode) {
|
14
|
+
return {
|
15
|
+
restrict: 'AE',
|
16
|
+
controller: ['$scope', function ($scope) {
|
17
|
+
$scope.contentAccessMode = contentAccessMode;
|
18
|
+
}],
|
19
|
+
templateUrl: 'subscriptions/views/content-access-mode-banner.html'
|
20
|
+
};
|
21
|
+
}
|
22
|
+
]);
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<div bst-alert="info" ng-show="contentAccessMode === 'org_environment'">
|
2
|
+
<span translate>
|
3
|
+
Access to repositories is unrestricted in this organization. Hosts can consume all repositories available in the Content View they are registered to, regardless of subscription status.
|
4
|
+
</span>
|
5
|
+
</div>
|
@@ -24,7 +24,6 @@ namespace :katello do
|
|
24
24
|
Katello::Srpm,
|
25
25
|
Katello::ModuleStream,
|
26
26
|
Katello::YumMetadataFile,
|
27
|
-
Katello::Deb,
|
28
27
|
Katello::FileUnit,
|
29
28
|
Katello::Subscription,
|
30
29
|
Katello::Pool,
|
@@ -35,6 +34,7 @@ namespace :katello do
|
|
35
34
|
Katello::Content]
|
36
35
|
|
37
36
|
models << Katello::OstreeBranch if Katello::RepositoryTypeManager.find(Katello::Repository::OSTREE_TYPE).present?
|
37
|
+
models << Katello::Deb if Katello::RepositoryTypeManager.find(Katello::Repository::DEB_TYPE).present?
|
38
38
|
|
39
39
|
models.each do |model|
|
40
40
|
print "Importing #{model.name}\n"
|
data/lib/katello/version.rb
CHANGED
@@ -183,6 +183,77 @@ export const quantitiesRequestSuccessResponse = Immutable({
|
|
183
183
|
total: 3,
|
184
184
|
});
|
185
185
|
|
186
|
+
export const groupedSubscriptions = Immutable({
|
187
|
+
loading: false,
|
188
|
+
manifestModalOpened: false,
|
189
|
+
results: [
|
190
|
+
{
|
191
|
+
id: 3,
|
192
|
+
cp_id: 'ff8080815ea5ea44015ea617b1a5000b',
|
193
|
+
subscription_id: 3,
|
194
|
+
name: 'zoo',
|
195
|
+
start_date: '2017-09-21 16:18:44 -0400',
|
196
|
+
end_date: '2047-09-14 15:18:44 -0500',
|
197
|
+
available: -2,
|
198
|
+
quantity: -1,
|
199
|
+
consumed: 1,
|
200
|
+
account_number: null,
|
201
|
+
contract_number: null,
|
202
|
+
support_level: null,
|
203
|
+
product_id: '853987721546',
|
204
|
+
sockets: null,
|
205
|
+
cores: null,
|
206
|
+
ram: null,
|
207
|
+
instance_multiplier: 1,
|
208
|
+
stacking_id: null,
|
209
|
+
multi_entitlement: null,
|
210
|
+
type: 'NORMAL',
|
211
|
+
product_name: 'zoo',
|
212
|
+
unmapped_guest: false,
|
213
|
+
virt_only: false,
|
214
|
+
virt_who: false,
|
215
|
+
},
|
216
|
+
{
|
217
|
+
id: 4,
|
218
|
+
cp_id: 'ff8080815ea5ea44015ebb08e95a0024',
|
219
|
+
subscription_id: 3,
|
220
|
+
name: 'hsdfhsdh',
|
221
|
+
start_date: '2017-09-25 17:54:36 -0400',
|
222
|
+
end_date: '2047-09-18 16:54:36 -0500',
|
223
|
+
available: -1,
|
224
|
+
quantity: -1,
|
225
|
+
consumed: 0,
|
226
|
+
account_number: null,
|
227
|
+
contract_number: null,
|
228
|
+
support_level: null,
|
229
|
+
product_id: '853987721546',
|
230
|
+
sockets: null,
|
231
|
+
cores: null,
|
232
|
+
ram: null,
|
233
|
+
instance_multiplier: 1,
|
234
|
+
stacking_id: null,
|
235
|
+
multi_entitlement: null,
|
236
|
+
type: 'NORMAL',
|
237
|
+
product_name: 'hsdfhsdh',
|
238
|
+
unmapped_guest: false,
|
239
|
+
virt_only: false,
|
240
|
+
virt_who: false,
|
241
|
+
},
|
242
|
+
],
|
243
|
+
searchIsActive: false,
|
244
|
+
search: undefined,
|
245
|
+
pagination: {
|
246
|
+
page: 1,
|
247
|
+
perPage: 2,
|
248
|
+
},
|
249
|
+
itemCount: 81,
|
250
|
+
quantitiesLoading: false,
|
251
|
+
availableQuantities: null,
|
252
|
+
tasks: [],
|
253
|
+
tableColumns: [],
|
254
|
+
selectedTableColumns: [],
|
255
|
+
});
|
256
|
+
|
186
257
|
export const successState = Immutable({
|
187
258
|
loading: false,
|
188
259
|
manifestModalOpened: false,
|
@@ -452,6 +523,7 @@ export const tableColumns = [
|
|
452
523
|
value: true,
|
453
524
|
},
|
454
525
|
];
|
526
|
+
|
455
527
|
export const loadTableColumnsSuccessAction = [
|
456
528
|
{
|
457
529
|
type: 'UPDATE_SUBSCRIPTION_COLUMNS',
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { Link } from 'react-router-dom';
|
3
|
+
import { urlBuilder } from 'foremanReact/common/urlHelpers';
|
4
|
+
|
5
|
+
export const subscriptionNameFormatter = (value, { rowData }) => {
|
6
|
+
let cellContent;
|
7
|
+
|
8
|
+
if (rowData.collapsible) {
|
9
|
+
cellContent = (rowData.name);
|
10
|
+
} else {
|
11
|
+
cellContent = (
|
12
|
+
<Link to={urlBuilder('subscriptions', '', rowData.id)}>{rowData.name}</Link>
|
13
|
+
);
|
14
|
+
}
|
15
|
+
|
16
|
+
return (
|
17
|
+
<td>
|
18
|
+
{cellContent}
|
19
|
+
</td>
|
20
|
+
);
|
21
|
+
};
|
22
|
+
|
23
|
+
export default subscriptionNameFormatter;
|
@@ -1,11 +1,10 @@
|
|
1
1
|
/* eslint-disable import/prefer-default-export */
|
2
2
|
import React from 'react';
|
3
3
|
import { Icon } from 'patternfly-react';
|
4
|
-
import { Link } from 'react-router-dom';
|
5
|
-
import { urlBuilder } from 'foremanReact/common/urlHelpers';
|
6
4
|
import { translate as __ } from 'foremanReact/common/I18n';
|
7
5
|
import { entitlementsInlineEditFormatter } from '../../../../move_to_foreman/components/common/table/formatters/EntitlementsInlineEditFormatter';
|
8
6
|
import { subscriptionTypeFormatter } from './SubscriptionTypeFormatter';
|
7
|
+
import { subscriptionNameFormatter } from './SubscriptionNameFormatter';
|
9
8
|
import {
|
10
9
|
headerFormatter,
|
11
10
|
cellFormatter,
|
@@ -54,13 +53,8 @@ export const createSubscriptionsTableSchema = (
|
|
54
53
|
formatters: [headerFormatter],
|
55
54
|
},
|
56
55
|
cell: {
|
57
|
-
formatters: [
|
58
|
-
|
59
|
-
<td>
|
60
|
-
<Link to={urlBuilder('subscriptions', '', rowData.id)}>{rowData.name}</Link>
|
61
|
-
</td>
|
62
|
-
),
|
63
|
-
],
|
56
|
+
formatters: [subscriptionNameFormatter]
|
57
|
+
,
|
64
58
|
},
|
65
59
|
},
|
66
60
|
{
|
data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js
CHANGED
@@ -4,7 +4,7 @@ import toJson from 'enzyme-to-json';
|
|
4
4
|
import { MemoryRouter } from 'react-router-dom';
|
5
5
|
import { translate as __ } from 'foremanReact/common/I18n';
|
6
6
|
import SubscriptionsTable from '../SubscriptionsTable';
|
7
|
-
import { successState, loadingState, emptyState } from '../../../__tests__/subscriptions.fixtures';
|
7
|
+
import { successState, loadingState, emptyState, groupedSubscriptions } from '../../../__tests__/subscriptions.fixtures';
|
8
8
|
import { loadSubscriptions, updateQuantity } from '../../../SubscriptionActions';
|
9
9
|
|
10
10
|
jest.mock('foremanReact/components/Pagination/PaginationWrapper');
|
@@ -18,6 +18,26 @@ const tableColumns = [
|
|
18
18
|
'end_date',
|
19
19
|
];
|
20
20
|
describe('subscriptions table', () => {
|
21
|
+
it('should render subscription name without hyperlink for grouped subscriptions', async () => {
|
22
|
+
/* eslint-disable react/jsx-indent */
|
23
|
+
|
24
|
+
const page = render(<MemoryRouter>
|
25
|
+
<SubscriptionsTable
|
26
|
+
subscriptions={groupedSubscriptions}
|
27
|
+
groupedSubscriptions={groupedSubscriptions}
|
28
|
+
loadSubscriptions={loadSubscriptions}
|
29
|
+
tableColumns={tableColumns}
|
30
|
+
updateQuantity={updateQuantity}
|
31
|
+
subscriptionDeleteModalOpen={false}
|
32
|
+
onDeleteSubscriptions={() => {}}
|
33
|
+
onSubscriptionDeleteModalClose={() => { }}
|
34
|
+
toggleDeleteButton={() => {}}
|
35
|
+
emptyState={{}}
|
36
|
+
/>
|
37
|
+
</MemoryRouter>);
|
38
|
+
expect(toJson(page)).toMatchSnapshot();
|
39
|
+
});
|
40
|
+
|
21
41
|
it('should render a table', async () => {
|
22
42
|
// Wrapping SubscriptionTable in MemoryRouter here since it contains
|
23
43
|
// a Link componenent, which can't be used outside a Router
|
@@ -218,3 +218,95 @@ exports[`subscriptions table should render an empty state 1`] = `
|
|
218
218
|
EmptyState: {"header":"Yay empty state","description":"There is nothing to see here"}
|
219
219
|
</div>
|
220
220
|
`;
|
221
|
+
|
222
|
+
exports[`subscriptions table should render subscription name without hyperlink for grouped subscriptions 1`] = `
|
223
|
+
<div>
|
224
|
+
<table
|
225
|
+
class="table table-striped table-bordered table-hover pf-table-inline-edit table-fixed"
|
226
|
+
>
|
227
|
+
<thead>
|
228
|
+
<tr
|
229
|
+
class=""
|
230
|
+
>
|
231
|
+
<th
|
232
|
+
aria-label="Select all rows"
|
233
|
+
class="table-view-pf-select"
|
234
|
+
>
|
235
|
+
<label
|
236
|
+
class="control-label sr-only"
|
237
|
+
for="selectAll"
|
238
|
+
>
|
239
|
+
Select all rows
|
240
|
+
</label>
|
241
|
+
<input
|
242
|
+
id="selectAll"
|
243
|
+
type="checkbox"
|
244
|
+
/>
|
245
|
+
</th>
|
246
|
+
<th
|
247
|
+
class=""
|
248
|
+
>
|
249
|
+
Name
|
250
|
+
</th>
|
251
|
+
<th
|
252
|
+
class=""
|
253
|
+
>
|
254
|
+
SKU
|
255
|
+
</th>
|
256
|
+
<th
|
257
|
+
class=""
|
258
|
+
>
|
259
|
+
Contract
|
260
|
+
</th>
|
261
|
+
<th
|
262
|
+
class=""
|
263
|
+
>
|
264
|
+
Start Date
|
265
|
+
</th>
|
266
|
+
<th
|
267
|
+
class=""
|
268
|
+
>
|
269
|
+
End Date
|
270
|
+
</th>
|
271
|
+
</tr>
|
272
|
+
</thead>
|
273
|
+
<tbody>
|
274
|
+
<tr
|
275
|
+
class=""
|
276
|
+
>
|
277
|
+
<td
|
278
|
+
class="table-view-pf-select"
|
279
|
+
>
|
280
|
+
<span
|
281
|
+
aria-hidden="true"
|
282
|
+
class="fa fa-angle-right collapse-subscription-group-button"
|
283
|
+
/>
|
284
|
+
</td>
|
285
|
+
<td>
|
286
|
+
hsdfhsdh
|
287
|
+
</td>
|
288
|
+
<td
|
289
|
+
class=""
|
290
|
+
>
|
291
|
+
853987721546
|
292
|
+
</td>
|
293
|
+
<td
|
294
|
+
class=""
|
295
|
+
>
|
296
|
+
NA
|
297
|
+
</td>
|
298
|
+
<td
|
299
|
+
class=""
|
300
|
+
>
|
301
|
+
NA
|
302
|
+
</td>
|
303
|
+
<td
|
304
|
+
class=""
|
305
|
+
>
|
306
|
+
NA
|
307
|
+
</td>
|
308
|
+
</tr>
|
309
|
+
</tbody>
|
310
|
+
</table>
|
311
|
+
</div>
|
312
|
+
`;
|
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.14.0
|
4
|
+
version: 3.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- N/A
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -1250,6 +1250,7 @@ files:
|
|
1250
1250
|
- app/services/katello/pulp/docker_tag.rb
|
1251
1251
|
- app/services/katello/pulp/erratum.rb
|
1252
1252
|
- app/services/katello/pulp/file_unit.rb
|
1253
|
+
- app/services/katello/pulp/importer_comparison.rb
|
1253
1254
|
- app/services/katello/pulp/module_stream.rb
|
1254
1255
|
- app/services/katello/pulp/ostree_branch.rb
|
1255
1256
|
- app/services/katello/pulp/package_category.rb
|
@@ -3988,10 +3989,12 @@ files:
|
|
3988
3989
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/repository-sets/repository-sets.module.js
|
3989
3990
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/settings/setting.factory.js
|
3990
3991
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/settings/settings.module.js
|
3992
|
+
- engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/content-access-mode-banner.directive.js
|
3991
3993
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/subscriptionConsumed.filter.js
|
3992
3994
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/subscriptions-helper.service.js
|
3993
3995
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/subscriptions.factory.js
|
3994
3996
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/subscriptions.module.js
|
3997
|
+
- engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html
|
3995
3998
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-add-products.controller.js
|
3996
3999
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-details-info.controller.js
|
3997
4000
|
- engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-details.controller.js
|
@@ -4521,6 +4524,7 @@ files:
|
|
4521
4524
|
- webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsReducer.test.js.snap
|
4522
4525
|
- webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsSelectors.test.js.snap
|
4523
4526
|
- webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js
|
4527
|
+
- webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionNameFormatter.js
|
4524
4528
|
- webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionTypeFormatter.js
|
4525
4529
|
- webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js
|
4526
4530
|
- webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js
|
@@ -4569,9 +4573,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
4569
4573
|
version: '0'
|
4570
4574
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
4571
4575
|
requirements:
|
4572
|
-
- - "
|
4576
|
+
- - ">="
|
4573
4577
|
- !ruby/object:Gem::Version
|
4574
|
-
version:
|
4578
|
+
version: '0'
|
4575
4579
|
requirements: []
|
4576
4580
|
rubygems_version: 3.0.3
|
4577
4581
|
signing_key:
|