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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fdc69d79c80c2099fe91eff58b35861a0cebf3dd5ac4affa128d2b8751619769
4
- data.tar.gz: 41cc9a3b3b657e44325274002b19884ae4c5b993c106ff191bfccf749d5a9a6c
3
+ metadata.gz: 4753e9076eca5c39d6930c003dd67a5cbd01bbbd97b47bef6e81a74d6e576ceb
4
+ data.tar.gz: 561e374445d3f901344a42d4e08701b8bd5d48ce57802bb477a296959ccfc0f3
5
5
  SHA512:
6
- metadata.gz: b28ea4eeb0db67f2b2bdba025b9191a57c54830e928f222b5c6f281eb1fc51a89cbb15d18f17eed853e914765ea57d9f1577f04a604fcc697786fe4c3b4217fd
7
- data.tar.gz: e94f4bc8c64f672d5886ac900df8e13cc7322338fa048ec8eedcce1181adbaeb5c749119ebc86df734e021a014f89142554b236457fcb80819b535a2c60716dd
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
- if @resource.organization_id != org_id
81
- fail ActiveRecord::RecordNotFound, N_('This subscription is not relevant to the current organization.')
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
@@ -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] = [OK_RETURN_CODE, WARN_RETURN_CODE].include?(v[:status]) ? OK_RETURN_CODE : FAIL_RETURN_CODE
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 daemon_status_message(status)
49
- "#{status[:processed_count]} Processed, #{status[:failed_count]} Failed, #{status[:queue_depth]} in queue"
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
- PROCESSED_COUNT_CACHE_KEY = 'candlepin_events_processed'.freeze
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
- @thread.kill if @thread
12
+ initialize_listening_service
28
13
 
29
- # run in own thread so connecting to qpid won't block the main process
30
- @thread = Thread.new do
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
- Katello::CandlepinListeningService.instance.poll_for_messages do |message|
36
- if message[:result]
37
- result = message[:result]
38
- event = CandlepinEvent.new(result.message_id, result.subject, result.content)
39
- act_on_event(event)
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
- processed_count: Rails.cache.fetch(PROCESSED_COUNT_CACHE_KEY) { @processed_count },
56
- failed_count: Rails.cache.fetch(FAILED_COUNT_CACHE_KEY) { @failed_count },
57
- queue_depth: Katello::Resources::Candlepin::Admin.queue_depth(AMQP_QUEUE_NAME)
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
- Rails.cache.write(PROCESSED_COUNT_CACHE_KEY, 0)
63
- Rails.cache.write(FAILED_COUNT_CACHE_KEY, 0)
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
- raise e unless e.class.name.include? "TransportFailure"
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? && message[:error].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
- start_services
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 start_services
73
- services.values.each(&:run)
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
- PROCESSED_COUNT_CACHE_KEY = 'katello_events_processed'.freeze
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
- processed_count: Rails.cache.fetch(PROCESSED_COUNT_CACHE_KEY) { 0 },
31
- failed_count: Rails.cache.fetch(FAILED_COUNT_CACHE_KEY) { 0 },
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.write(PROCESSED_COUNT_CACHE_KEY, 0)
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"
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "3.14.0.rc2".freeze
2
+ VERSION = "3.14.0".freeze
3
3
  end
@@ -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
- (value, { rowData }) => (
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
  {
@@ -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.rc2
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-25 00:00:00.000000000 Z
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: 1.3.1
4578
+ version: '0'
4575
4579
  requirements: []
4576
4580
  rubygems_version: 3.0.3
4577
4581
  signing_key: