katello 3.7.0.rc1 → 3.7.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/content_views_controller.rb +5 -2
  3. data/app/controllers/katello/api/v2/environments_controller.rb +8 -3
  4. data/app/controllers/katello/api/v2/host_tracer_controller.rb +1 -1
  5. data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +4 -4
  6. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +5 -22
  7. data/app/lib/actions/katello/host/update_content_overrides.rb +1 -0
  8. data/app/lib/actions/katello/product/content_create.rb +1 -0
  9. data/app/lib/actions/katello/product/repositories_certs_reset.rb +25 -0
  10. data/app/lib/actions/katello/product/update.rb +6 -0
  11. data/app/lib/katello/resources/candlepin/activation_key.rb +8 -4
  12. data/app/lib/katello/resources/candlepin/product.rb +2 -1
  13. data/app/lib/katello/util/cdn_var_substitutor.rb +5 -3
  14. data/app/lib/katello/util/package.rb +21 -13
  15. data/app/lib/katello/util/package_filter.rb +33 -31
  16. data/app/lib/katello/validators/prior_validator.rb +6 -10
  17. data/app/models/katello/concerns/host_managed_extensions.rb +2 -0
  18. data/app/models/katello/concerns/organization_extensions.rb +1 -0
  19. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +10 -6
  20. data/app/models/katello/content.rb +23 -2
  21. data/app/models/katello/content_view_docker_filter.rb +1 -1
  22. data/app/models/katello/content_view_puppet_module.rb +3 -3
  23. data/app/models/katello/content_view_version.rb +4 -0
  24. data/app/models/katello/environment_prior.rb +7 -0
  25. data/app/models/katello/glue/candlepin/candlepin_object.rb +2 -2
  26. data/app/models/katello/glue/candlepin/pool.rb +10 -13
  27. data/app/models/katello/glue/candlepin/product.rb +19 -9
  28. data/app/models/katello/glue/candlepin/repository.rb +16 -0
  29. data/app/models/katello/glue/candlepin/subscription.rb +1 -1
  30. data/app/models/katello/glue/provider.rb +15 -81
  31. data/app/models/katello/host/subscription_facet.rb +1 -1
  32. data/app/models/katello/kt_environment.rb +39 -8
  33. data/app/models/katello/pool.rb +2 -1
  34. data/app/models/katello/rpm.rb +144 -2
  35. data/app/models/katello/upstream_pool.rb +7 -10
  36. data/app/services/katello/candlepin/pool_service.rb +18 -3
  37. data/app/services/katello/ui_notifications/pulp/proxy_disk_space.rb +13 -16
  38. data/app/views/dashboard/_content_views_widget.html.erb +3 -3
  39. data/app/views/dashboard/_errata_widget.html.erb +2 -2
  40. data/app/views/dashboard/_host_collection_widget.html.erb +3 -3
  41. data/app/views/dashboard/_subscription_status_widget.html.erb +2 -2
  42. data/app/views/dashboard/_subscription_widget.html.erb +1 -1
  43. data/app/views/dashboard/_sync_widget.html.erb +3 -3
  44. data/app/views/katello/api/v2/subscriptions/base.json.rabl +1 -1
  45. data/app/views/katello/api/v2/upstream_subscriptions/base.json.rabl +2 -6
  46. data/app/views/katello/layouts/react.html.erb +3 -3
  47. data/config/katello.yaml +89 -0
  48. data/config/routes.rb +3 -0
  49. data/db/migrate/20160302091113_change_environment_prior.rb +9 -0
  50. data/db/migrate/20180410140909_add_organization_id_to_pool.rb +2 -1
  51. data/db/migrate/20180612163403_add_foreign_key_to_hypervisor_id.rb +10 -0
  52. data/db/migrate/20180612164926_add_content_org_id.rb +39 -0
  53. data/db/migrate/20180612165011_remove_content_fields_from_host.rb +7 -0
  54. data/db/migrate/20180626160422_add_upstream_pool_id_to_katello_pool.rb +9 -0
  55. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-packages-modal.html +1 -1
  56. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register.html +1 -1
  57. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/environment-content.controller.js +2 -3
  58. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment.html +4 -2
  59. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.controller.js +19 -14
  60. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/new-environment.controller.js +18 -5
  61. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/paths.service.js +51 -0
  62. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/views/new-environment.html +16 -3
  63. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/products-bulk-advanced-sync-modal.controller.js +1 -1
  64. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +2 -2
  65. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/subscriptions.routes.js +3 -3
  66. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/tasks.module.js +1 -6
  67. data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +4 -0
  68. data/engines/bastion_katello/lib/bastion_katello/engine.rb +1 -1
  69. data/lib/katello/plugin.rb +2 -11
  70. data/lib/katello/scheduled_jobs.rb +2 -14
  71. data/lib/katello/tasks/clean_backend_objects.rake +2 -0
  72. data/lib/katello/tasks/repository.rake +11 -2
  73. data/lib/katello/tasks/upgrades/3.7/import_pools.rake +12 -0
  74. data/lib/katello/version.rb +1 -1
  75. data/package.json +4 -3
  76. data/webpack/components/PaginationRow/index.js +6 -2
  77. data/webpack/containers/Application/config.js +7 -2
  78. data/webpack/index.js +3 -5
  79. data/webpack/move_to_foreman/common/helpers.js +5 -24
  80. data/webpack/move_to_foreman/components/common/emptyState/index.js +12 -7
  81. data/webpack/move_to_foreman/components/common/table/components/CollapseSubscriptionGroupButton.js +31 -0
  82. data/webpack/move_to_foreman/components/common/table/components/CollapseSubscriptionGroupButton.test.js +16 -0
  83. data/webpack/move_to_foreman/components/common/table/components/Table.js +76 -0
  84. data/webpack/move_to_foreman/components/common/table/components/Table.test.js +31 -0
  85. data/webpack/move_to_foreman/components/common/table/components/TableBody.js +27 -0
  86. data/webpack/move_to_foreman/components/common/table/components/TableBody.test.js +18 -0
  87. data/webpack/move_to_foreman/components/common/table/components/TableBodyMessage.js +18 -0
  88. data/webpack/move_to_foreman/components/common/table/components/TableBodyMessage.test.js +12 -0
  89. data/webpack/move_to_foreman/components/common/table/components/TableFixtures.js +14 -0
  90. data/webpack/move_to_foreman/components/common/table/components/TableSelectionCell.js +39 -0
  91. data/webpack/move_to_foreman/components/common/table/components/TableSelectionCell.test.js +16 -0
  92. data/webpack/move_to_foreman/components/common/table/components/TableSelectionHeaderCell.js +34 -0
  93. data/webpack/move_to_foreman/components/common/table/components/TableSelectionHeaderCell.test.js +14 -0
  94. data/webpack/move_to_foreman/components/common/table/components/__snapshots__/CollapseSubscriptionGroupButton.test.js.snap +19 -0
  95. data/webpack/move_to_foreman/components/common/table/components/__snapshots__/Table.test.js.snap +167 -0
  96. data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableBody.test.js.snap +28 -0
  97. data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableBodyMessage.test.js.snap +13 -0
  98. data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionCell.test.js.snap +16 -0
  99. data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionHeaderCell.test.js.snap +15 -0
  100. data/webpack/move_to_foreman/components/common/table/components/index.js +6 -0
  101. data/webpack/move_to_foreman/components/common/table/formatters/cellFormatter.js +4 -0
  102. data/webpack/move_to_foreman/components/common/table/formatters/collapseableAndSelectionCellFormatter.js +18 -0
  103. data/webpack/move_to_foreman/components/common/table/formatters/ellipsisCellFormatter.js +5 -0
  104. data/webpack/move_to_foreman/components/common/table/formatters/headerFormatter.js +4 -0
  105. data/webpack/move_to_foreman/components/common/table/formatters/index.js +6 -0
  106. data/webpack/move_to_foreman/components/common/table/formatters/selectionCellFormatter.js +17 -0
  107. data/webpack/move_to_foreman/components/common/table/formatters/selectionHeaderCellFormatter.js +10 -0
  108. data/webpack/move_to_foreman/components/common/table/index.js +2 -88
  109. data/webpack/move_to_pf/LoadingState/LoadingState.js +35 -0
  110. data/webpack/move_to_pf/LoadingState/LoadingState.scss +12 -0
  111. data/webpack/move_to_pf/LoadingState/LoadingState.test.js +28 -0
  112. data/webpack/move_to_pf/LoadingState/__snapshots__/LoadingState.test.js.snap +20 -0
  113. data/webpack/move_to_pf/LoadingState/index.js +3 -0
  114. data/webpack/move_to_pf/test-utils/testHelpers.js +71 -0
  115. data/webpack/redux/actions/RedHatRepositories/enabled.js +1 -1
  116. data/webpack/redux/actions/RedHatRepositories/helpers.js +34 -9
  117. data/webpack/redux/actions/RedHatRepositories/sets.js +28 -6
  118. data/webpack/redux/consts.js +1 -0
  119. data/webpack/redux/reducers/RedHatRepositories/sets.fixtures.js +12 -2
  120. data/webpack/redux/reducers/RedHatRepositories/sets.js +34 -27
  121. data/webpack/redux/reducers/RedHatRepositories/sets.test.js +10 -2
  122. data/webpack/redux/reducers/index.js +2 -0
  123. data/webpack/scenes/Organizations/OrganizationActions.js +3 -3
  124. data/webpack/scenes/RedHatRepositories/components/RecommendedRepositorySetsToggler.js +44 -0
  125. data/webpack/scenes/RedHatRepositories/components/RecommendedRepositorySetsToggler.scss +16 -0
  126. data/webpack/scenes/RedHatRepositories/components/RepositorySet.js +8 -2
  127. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepositories.js +5 -3
  128. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository.js +4 -2
  129. data/webpack/scenes/RedHatRepositories/components/Search.js +1 -1
  130. data/webpack/scenes/RedHatRepositories/components/SearchBar.js +1 -1
  131. data/webpack/scenes/RedHatRepositories/components/__tests__/RecommendedRepositorySetsToggler.test.js +17 -0
  132. data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/RecommendedRepositorySetsToggler.test.js.snap +37 -0
  133. data/webpack/scenes/RedHatRepositories/helpers.js +1 -1
  134. data/webpack/scenes/RedHatRepositories/index.js +17 -7
  135. data/webpack/scenes/RedHatRepositories/index.scss +16 -4
  136. data/webpack/scenes/Subscriptions/Details/SubscriptionAttributes.js +17 -0
  137. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailActions.js +28 -0
  138. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailAssociations.js +47 -0
  139. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailConstants.js +3 -0
  140. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailInfo.js +65 -0
  141. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProducts.js +20 -0
  142. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailReducer.js +37 -0
  143. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +58 -0
  144. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailActions.test.js +47 -0
  145. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailAssociations.test.js +16 -0
  146. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailInfo.test.js +15 -0
  147. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailProducts.test.js +16 -0
  148. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailReducer.test.js +39 -0
  149. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetails.test.js +28 -0
  150. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailAssociations.test.js.snap +53 -0
  151. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailInfo.test.js.snap +185 -0
  152. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailProducts.test.js.snap +77 -0
  153. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +432 -0
  154. data/webpack/scenes/Subscriptions/Details/__tests__/subscriptionDetails.fixtures.js +167 -0
  155. data/webpack/scenes/Subscriptions/Details/index.js +19 -0
  156. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +58 -12
  157. data/webpack/scenes/Subscriptions/Manifest/Manifest.scss +6 -1
  158. data/webpack/scenes/Subscriptions/Manifest/ManifestActions.js +4 -4
  159. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryTableSchema.js +7 -7
  160. data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +6 -9
  161. data/webpack/scenes/Subscriptions/Manifest/index.js +2 -2
  162. data/webpack/scenes/Subscriptions/SubscriptionActions.js +5 -6
  163. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +2 -3
  164. data/webpack/scenes/Subscriptions/SubscriptionValidations.js +1 -1
  165. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +46 -30
  166. data/webpack/scenes/Subscriptions/SubscriptionsPage.scss +38 -0
  167. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +3 -3
  168. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +7 -6
  169. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsTableSchema.js +17 -14
  170. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +12 -15
  171. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/upstreamSubscriptions.fixtures.js +4 -4
  172. data/webpack/scenes/Subscriptions/__tests__/SubscriptionValidations.test.js +5 -0
  173. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +2 -2
  174. data/webpack/scenes/Subscriptions/{EntitlementsInlineEditFormatter.js → components/SubscriptionsTable/EntitlementsInlineEditFormatter.js} +7 -7
  175. data/webpack/scenes/Subscriptions/{SubscriptionsTable.js → components/SubscriptionsTable/SubscriptionsTable.js} +75 -47
  176. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +60 -0
  177. data/webpack/scenes/Subscriptions/{SubscriptionsTableSchema.js → components/SubscriptionsTable/SubscriptionsTableSchema.js} +37 -26
  178. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +56 -0
  179. data/webpack/scenes/Subscriptions/{__tests__ → components/SubscriptionsTable/__tests__}/__snapshots__/SubscriptionsTable.test.js.snap +16 -5
  180. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/index.js +2 -0
  181. data/webpack/scenes/Subscriptions/index.js +2 -2
  182. data/webpack/scenes/Tasks/TaskActions.js +18 -11
  183. data/webpack/scenes/Tasks/__tests__/TaskActions.test.js +92 -9
  184. data/webpack/scenes/Tasks/__tests__/task.fixtures.js +19 -9
  185. data/webpack/services/api/index.js +2 -2
  186. data/webpack/test_setup.js +1 -0
  187. metadata +79 -10
  188. data/webpack/scenes/Subscriptions/Subscriptions.scss +0 -14
  189. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsTable.test.js +0 -47
@@ -11,14 +11,12 @@ module Katello
11
11
  belongs_to :organization, :class_name => "Organization", :inverse_of => :environments
12
12
  has_many :activation_keys, :class_name => "Katello::ActivationKey",
13
13
  :dependent => :restrict_with_exception, :foreign_key => :environment_id
14
- # rubocop:disable HasAndBelongsToMany
15
- # TODO: change these into has_many associations
16
- has_and_belongs_to_many :priors, :class_name => "Katello::KTEnvironment", :foreign_key => :environment_id,
17
- :join_table => "katello_environment_priors",
18
- :association_foreign_key => "prior_id", :uniq => true
19
- has_and_belongs_to_many :successors, :class_name => "Katello::KTEnvironment", :foreign_key => "prior_id",
20
- :join_table => "katello_environment_priors",
21
- :association_foreign_key => :environment_id, :readonly => true
14
+
15
+ has_many :env_priors, :class_name => "Katello::EnvironmentPrior", :foreign_key => :environment_id, :dependent => :destroy
16
+ has_many :priors, :class_name => "Katello::KTEnvironment", :through => :env_priors, :source => :env_prior
17
+
18
+ has_many :env_successors, :class_name => "Katello::EnvironmentPrior", :foreign_key => :prior_id, :dependent => :destroy
19
+ has_many :successors, :class_name => "Katello::KTEnvironment", :through => :env_successors, :source => :env
22
20
 
23
21
  has_many :repositories, :class_name => "Katello::Repository", dependent: :destroy, foreign_key: :environment_id
24
22
  has_many :content_view_environments, :class_name => "Katello::ContentViewEnvironment",
@@ -102,6 +100,28 @@ module Katello
102
100
  self.organization.promotion_paths[0][0] unless self.organization.promotion_paths.empty?
103
101
  end
104
102
 
103
+ # creates new env from create_params with self as a prior
104
+ def insert_successor(create_params, path)
105
+ self.class.transaction do
106
+ new_successor = self.class.create!(create_params)
107
+ if library?
108
+ if path
109
+ old_successor = path.first
110
+ old_successor.prior = new_successor
111
+ end
112
+ save_successor new_successor
113
+ elsif successor.nil?
114
+ save_successor new_successor
115
+ else
116
+ old_successor = successor
117
+ old_successor.prior = new_successor
118
+ save_successor new_successor
119
+ end
120
+ fail HttpErrors::UnprocessableEntity, _('An environment is missing a prior') unless all_have_prior?
121
+ new_successor
122
+ end
123
+ end
124
+
105
125
  def display_name
106
126
  self.name
107
127
  end
@@ -262,5 +282,16 @@ module Katello
262
282
  class Jail < ::Safemode::Jail
263
283
  allow :name, :label
264
284
  end
285
+
286
+ private
287
+
288
+ def all_have_prior?
289
+ organization.kt_environments.reject { |env| env.library? || env.prior.present? }.empty?
290
+ end
291
+
292
+ def save_successor(new_successor)
293
+ new_successor.prior = self
294
+ new_successor.save
295
+ end
265
296
  end
266
297
  end
@@ -12,7 +12,8 @@ module Katello
12
12
  has_many :subscription_facet_pools, :class_name => "Katello::SubscriptionFacetPool", :dependent => :destroy
13
13
  has_many :subscription_facets, :through => :subscription_facet_pools
14
14
 
15
- belongs_to :organization, :class_name => "Organization", :inverse_of => :pools
15
+ belongs_to :organization, :class_name => 'Organization', :inverse_of => :pools
16
+ belongs_to :hypervisor, :class_name => 'Host::Managed', :inverse_of => :hypervisor_pools
16
17
 
17
18
  scope :in_organization, ->(org_id) { where(:organization_id => org_id) }
18
19
  scope :for_activation_key, ->(ak) { joins(:activation_keys).where("#{Katello::ActivationKey.table_name}.id" => ak.id) }
@@ -12,10 +12,11 @@ module Katello
12
12
  has_many :content_facets, :through => :content_facet_applicable_rpms, :class_name => "Katello::Host::ContentFacet"
13
13
 
14
14
  scoped_search :on => :name, :complete_value => true
15
- scoped_search :on => :version, :complete_value => true
16
- scoped_search :on => :release, :complete_value => true
15
+ scoped_search :on => :version, :complete_value => true, :ext_method => :scoped_search_version
16
+ scoped_search :on => :release, :complete_value => true, :ext_method => :scoped_search_release
17
17
  scoped_search :on => :arch, :complete_value => true
18
18
  scoped_search :on => :epoch, :complete_value => true
19
+ scoped_search :on => :evr, :ext_method => :scoped_search_evr
19
20
  scoped_search :on => :filename, :complete_value => true
20
21
  scoped_search :on => :sourcerpm, :complete_value => true
21
22
  scoped_search :on => :checksum
@@ -30,6 +31,147 @@ module Katello
30
31
  RepositoryRpm
31
32
  end
32
33
 
34
+ def self.scoped_search_version(_key, operator, value)
35
+ self.scoped_search_sortable('version', operator, value)
36
+ end
37
+
38
+ def self.scoped_search_release(_key, operator, value)
39
+ self.scoped_search_sortable('release', operator, value)
40
+ end
41
+
42
+ def self.scoped_search_sortable(column, operator, value)
43
+ if ['>', '>=', '<', '<='].include?(operator)
44
+ conditions = "#{self.table_name}.#{column}_sortable COLLATE \"C\" #{operator} ? COLLATE \"C\""
45
+ parameter = Util::Package.sortable_version(value)
46
+ return { :conditions => conditions, :parameter => [parameter] }
47
+ end
48
+
49
+ # Use the default behavior for all other operators.
50
+ # Unfortunately there is no way to call the default behavior from here, so
51
+ # we replicate the default behavior from sql_test() in
52
+ # https://github.com/wvanbergen/scoped_search/blob/master/lib/scoped_search/query_builder.rb
53
+ if ['LIKE', 'NOT LIKE'].include?(operator)
54
+ conditions = "#{self.table_name}.#{column} #{operator} ?"
55
+ parameter = (value !~ /^\%|\*/ && value !~ /\%|\*$/) ? "%#{value}%" : value.tr_s('%*', '%')
56
+ return { :conditions => conditions, :parameter => [parameter] }
57
+ elsif ['IN', 'NOT IN'].include?(operator)
58
+ conditions = "#{self.table_name}.#{column} #{operator} (#{value.split(',').collect { '?' }.join(',')})"
59
+ parameters = value.split(',').collect { |v| v.strip }
60
+ return { :conditions => conditions, :parameter => parameters }
61
+ else
62
+ conditions = "#{self.table_name}.#{column} #{operator} ?"
63
+ parameter = value
64
+ return { :conditions => conditions, :parameter => [parameter] }
65
+ end
66
+ end
67
+
68
+ def self.scoped_search_evr(_key, operator, value)
69
+ if ['=', '<>'].include?(operator)
70
+ return self.scoped_search_evr_equal(operator, value)
71
+ elsif ['IN', 'NOT IN'].include?(operator)
72
+ return self.scoped_search_evr_in(operator, value)
73
+ elsif ['LIKE', 'NOT LIKE'].include?(operator)
74
+ return self.scoped_search_evr_like(operator, value)
75
+ elsif ['>', '>=', '<', '<='].include?(operator)
76
+ return self.scoped_search_evr_compare(operator, value)
77
+ else
78
+ return {}
79
+ end
80
+ end
81
+
82
+ def self.scoped_search_evr_equal(operator, value)
83
+ joiner = (operator == '=' ? 'AND' : 'OR')
84
+ evr = Util::Package.parse_evr(value)
85
+ (e, v, r) = [evr[:epoch], evr[:version], evr[:release]]
86
+ e = e.to_i # nil or blank becomes 0
87
+ conditions = "CAST(#{self.table_name}.epoch AS INT) #{operator} ?"
88
+ parameters = [e]
89
+ unless v.nil? || v.blank?
90
+ conditions += " #{joiner} #{self.table_name}.version #{operator} ?"
91
+ parameters += [v]
92
+ end
93
+ unless r.nil? || r.blank?
94
+ conditions += " #{joiner} #{self.table_name}.release #{operator} ?"
95
+ parameters += [r]
96
+ end
97
+ return { :conditions => conditions, :parameter => parameters }
98
+ end
99
+
100
+ def self.scoped_search_evr_in(operator, value)
101
+ op = (operator == 'IN' ? '=' : '<>')
102
+ joiner1 = (operator == 'IN' ? 'AND' : 'OR')
103
+ joiner2 = (operator == 'IN' ? 'OR' : 'AND')
104
+ conditions = []
105
+ parameters = []
106
+ value.split(',').collect { |v| v.strip }.each do |val|
107
+ evr = Util::Package.parse_evr(val)
108
+ (e, v, r) = [evr[:epoch], evr[:version], evr[:release]]
109
+ e = e.to_i # nil or blank becomes 0
110
+ condition = "CAST(#{self.table_name}.epoch AS INT) #{op} ?"
111
+ parameters += [e]
112
+ unless v.nil? || v.blank?
113
+ condition += " #{joiner1} #{self.table_name}.version #{op} ?"
114
+ parameters += [v]
115
+ end
116
+ unless r.nil? || r.blank?
117
+ condition += " #{joiner1} #{self.table_name}.release #{op} ?"
118
+ parameters += [r]
119
+ end
120
+ conditions += ["(#{condition})"]
121
+ end
122
+ return { :conditions => conditions.join(" #{joiner2} "), :parameter => parameters }
123
+ end
124
+
125
+ def self.scoped_search_evr_like(operator, value)
126
+ val = (value !~ /^\%|\*/ && value !~ /\%|\*$/) ? "%#{value}%" : value.tr_s('%*', '%')
127
+ evr = Util::Package.parse_evr(val)
128
+ (e, v, r) = [evr[:epoch], evr[:version], evr[:release]]
129
+ conditions = []
130
+ parameters = []
131
+ unless e.nil? || e.blank?
132
+ conditions += ["CAST(#{self.table_name}.epoch AS VARCHAR(10)) #{operator} ?"]
133
+ parameters += [e]
134
+ end
135
+ unless v.nil? || v.blank?
136
+ conditions += ["#{self.table_name}.version #{operator} ?"]
137
+ parameters += [v]
138
+ end
139
+ unless r.nil? || r.blank?
140
+ conditions += ["#{self.table_name}.release #{operator} ?"]
141
+ parameters += [r]
142
+ end
143
+ return {} if conditions.empty?
144
+ joiner = (operator == 'LIKE' ? 'AND' : 'OR')
145
+ return { :conditions => conditions.join(" #{joiner} "), :parameter => parameters }
146
+ end
147
+
148
+ def self.scoped_search_evr_compare(operator, value)
149
+ evr = Util::Package.parse_evr(value)
150
+ (e, v, r) = [evr[:epoch], evr[:version], evr[:release]]
151
+ e = e.to_i # nil or blank becomes 0
152
+ conditions = ''
153
+ if v.nil? || v.blank?
154
+ conditions = "CAST(#{self.table_name}.epoch AS INT) #{operator} ?"
155
+ parameters = [e]
156
+ else
157
+ sv = Util::Package.sortable_version(v)
158
+ if r.nil? || r.blank?
159
+ conditions = "#{self.table_name}.version_sortable COLLATE \"C\" #{operator} ? COLLATE \"C\""
160
+ parameters = [sv]
161
+ else
162
+ conditions =
163
+ "#{self.table_name}.version_sortable COLLATE \"C\" #{operator[0]} ? COLLATE \"C\" OR " \
164
+ "(#{self.table_name}.version_sortable = ? AND " \
165
+ "#{self.table_name}.release_sortable COLLATE \"C\" #{operator} ? COLLATE \"C\")"
166
+ sv = Util::Package.sortable_version(v)
167
+ parameters = [sv, sv, Util::Package.sortable_version(r)]
168
+ end
169
+ conditions = "CAST(#{self.table_name}.epoch AS INT) #{operator[0]} ? OR (CAST(#{self.table_name}.epoch AS INT) = ? AND (#{conditions}))"
170
+ parameters = [e, e] + parameters
171
+ end
172
+ return { :conditions => conditions, :parameter => parameters }
173
+ end
174
+
33
175
  def self.search_version_range(min = nil, max = nil)
34
176
  query = self.all
35
177
  query = Katello::Util::PackageFilter.new(query, min, Katello::Util::PackageFilter::GREATER_THAN).results if min.present?
@@ -5,7 +5,7 @@ module Katello
5
5
  class << self
6
6
  def fetch_pools(params)
7
7
  quantities_only = ::Foreman::Cast.to_bool(params.delete(:quantities_only))
8
- pool_id_map = upstream_pool_id_map(params.delete(:pool_ids))
8
+ pool_id_map = Katello::Candlepin::PoolService.upstream_pool_id_map(params.delete(:pool_ids))
9
9
 
10
10
  cp_params = request_params(
11
11
  base_params: base_params(params),
@@ -38,20 +38,17 @@ module Katello
38
38
  CP_POOL.upstream_consumer_id
39
39
  end
40
40
 
41
- def upstream_pool_id_map(local_pool_ids)
42
- return {} unless local_pool_ids
43
-
44
- Katello::Candlepin::PoolService.local_to_upstream_ids(local_pool_ids)
45
- end
46
-
47
41
  def response_to_pools(response, pool_id_map: {})
48
42
  pools = JSON.parse(response)
43
+ if pool_id_map.empty?
44
+ pool_id_map = Katello::Candlepin::PoolService.map_upstream_pools_to_local(pools)
45
+ end
49
46
  pools.map { |pool| self.new(map_attributes(pool, pool_id_map: pool_id_map)) }
50
47
  end
51
48
 
52
49
  def kat_to_cp_map
53
50
  {
54
- pool_id: 'id',
51
+ id: 'id',
55
52
  active: 'activeSubscription',
56
53
  quantity: 'quantity',
57
54
  start_date: 'startDate',
@@ -70,13 +67,13 @@ module Katello
70
67
  attributes[kat] = pool[cp] if pool[cp]
71
68
  end
72
69
 
73
- attributes[:local_pool_ids] = pool_id_map[attributes[:pool_id]]
70
+ attributes[:local_pool_ids] = pool_id_map[attributes[:id]]
74
71
 
75
72
  attributes
76
73
  end
77
74
 
78
75
  def minimal_fields
79
- kat_to_cp_map.values_at(:pool_id, :quantity)
76
+ kat_to_cp_map.values_at(:id, :quantity)
80
77
  end
81
78
 
82
79
  def all_fields
@@ -1,17 +1,32 @@
1
1
  module Katello
2
2
  module Candlepin
3
3
  class PoolService
4
- def self.local_to_upstream_ids(local_pool_ids)
5
- pools = Katello::Pool.find(local_pool_ids)
4
+ def self.upstream_pool_id_map(local_pool_ids, fail_on_not_found: true)
5
+ return {} unless local_pool_ids
6
+
7
+ local_to_upstream_ids(local_pool_ids, fail_on_not_found: fail_on_not_found)
8
+ end
9
+
10
+ def self.local_to_upstream_ids(local_pool_ids, fail_on_not_found: true)
11
+ pools = Katello::Pool.where(id: local_pool_ids)
6
12
  id_map = Hash.new { |hash, key| hash[key] = [] }
7
13
 
8
14
  pools.each do |pool|
9
- fail 'No upstream pool ID was found for Katello::Pool with ID: %s' % pool.id unless pool.upstream_pool_id
15
+ if fail_on_not_found && !pool.upstream_pool_id
16
+ fail 'No upstream pool ID was found for Katello::Pool with ID: %s' % pool.id
17
+ end
10
18
  id_map[pool.upstream_pool_id] << pool.id
11
19
  end
12
20
 
13
21
  id_map
14
22
  end
23
+
24
+ # For mapping the upstream pools after the candlepin request has returned them
25
+ def self.map_upstream_pools_to_local(pools)
26
+ upstream_pool_ids = pools.map { |x| x['id'] }
27
+ local_pool_ids = Katello::Pool.where(upstream_pool_id: upstream_pool_ids).pluck(:id)
28
+ return upstream_pool_id_map(local_pool_ids, fail_on_not_found: false)
29
+ end
15
30
  end
16
31
  end
17
32
  end
@@ -8,27 +8,24 @@ module Katello
8
8
  percentage = proxy.statuses[:pulp].storage['pulp_dir']['percent']
9
9
  if percentage[0..2].to_i < 90 && notification_already_exists?(proxy)
10
10
  blueprint.notifications.where(subject: proxy).destroy_all
11
- next
12
- end
13
- next unless update_notifications(proxy).empty?
14
- ::Notification.create!(
15
- :subject => proxy,
16
- :initiator => User.anonymous_admin,
17
- :audience => Notification::AUDIENCE_ADMIN,
18
- :message => ::UINotifications::StringParser.new(
19
- blueprint.message,
11
+ elsif update_notifications(proxy).empty? && percentage[0..2].to_i > 90
12
+ ::Notification.create!(
20
13
  :subject => proxy,
21
- :percentage => percentage
22
- ),
23
- :notification_blueprint => blueprint
24
- )
14
+ :initiator => User.anonymous_admin,
15
+ :audience => Notification::AUDIENCE_ADMIN,
16
+ :message => ::UINotifications::StringParser.new(
17
+ blueprint.message,
18
+ :subject => proxy,
19
+ :percentage => percentage
20
+ ),
21
+ :notification_blueprint => blueprint
22
+ )
23
+ end
25
24
  end
26
25
  end
27
26
 
28
27
  def notification_already_exists?(subject)
29
- low_disk_notification = Notification.unscoped.find_by(:subject => subject)
30
- return false if low_disk_notification.blank?
31
- low_disk_notification.notification_blueprint == blueprint
28
+ blueprint.notifications.where(:subject => subject).any?
32
29
  end
33
30
 
34
31
  def update_notifications(subject)
@@ -12,9 +12,9 @@
12
12
  <table class="table table-fixed table-striped table-bordered">
13
13
  <thead>
14
14
  <tr>
15
- <th><%= _("Content View") %></th>
16
- <th><%= _("Task") %></th>
17
- <th><%= _("Status") %></th>
15
+ <th class='ellipsis'><%= _("Content View") %></th>
16
+ <th class='ellipsis'><%= _("Task") %></th>
17
+ <th class='ellipsis'><%= _("Status") %></th>
18
18
  </tr>
19
19
  </thead>
20
20
  <tbody>
@@ -12,8 +12,8 @@
12
12
  <table class="table table-fixed table-striped">
13
13
  <thead>
14
14
  <tr>
15
- <th><%= _("Type") %></th>
16
- <th><%= _("Errata") %></th>
15
+ <th class='ellipsis'><%= _("Type") %></th>
16
+ <th class='ellipsis'><%= _("Errata") %></th>
17
17
  </tr>
18
18
  </thead>
19
19
  <tbody>
@@ -12,9 +12,9 @@
12
12
  <table class="table table-fixed table-striped table-bordered">
13
13
  <thead>
14
14
  <tr>
15
- <th><%= _("Updates") %></th>
16
- <th><%= _("Name") %></th>
17
- <th><%= _("Content Hosts") %></th>
15
+ <th class='ellipsis'><%= _("Updates") %></th>
16
+ <th class='ellipsis'><%= _("Name") %></th>
17
+ <th class='ellipsis'><%= _("Content Hosts") %></th>
18
18
  </tr>
19
19
  </thead>
20
20
  <tbody>
@@ -13,8 +13,8 @@
13
13
  <table class="table table-fixed table-striped table-bordered">
14
14
  <thead>
15
15
  <tr>
16
- <th><%= _("Subscription Status") %></th>
17
- <th><%= _("Count") %></th>
16
+ <th class='ellipsis'><%= _("Subscription Status") %></th>
17
+ <th class='ellipsis'><%= _("Count") %></th>
18
18
  </tr>
19
19
  </thead>
20
20
  <tbody>
@@ -18,7 +18,7 @@
18
18
  <thead>
19
19
  <tr>
20
20
  <th></th>
21
- <th><%= _("Count") %></th>
21
+ <th class='ellipsis'><%= _("Count") %></th>
22
22
  </tr>
23
23
  </thead>
24
24
  <tbody>
@@ -14,9 +14,9 @@
14
14
  <table class="table table-fixed table-striped table-bordered">
15
15
  <thead>
16
16
  <tr>
17
- <th><%= _("Product") %></th>
18
- <th><%= _("Status") %></th>
19
- <th><%= _("Finished") %></th>
17
+ <th class='ellipsis'><%= _("Product") %></th>
18
+ <th class='ellipsis'><%= _("Status") %></th>
19
+ <th class='ellipsis'><%= _("Finished") %></th>
20
20
  </tr>
21
21
  </thead>
22
22
  <tbody>
@@ -18,7 +18,7 @@ attributes :virt_only
18
18
  attributes :virt_who
19
19
  attributes :upstream? => :upstream
20
20
 
21
- node :hypervisor, :if => lambda { |sub| sub && sub.try(:hypervisor) && sub.hypervisor_id } do |subscription|
21
+ node :hypervisor, :if => lambda { |sub| sub && sub.respond_to?(:hypervisor) && sub.hypervisor } do |subscription|
22
22
  {
23
23
  id: subscription.hypervisor.id,
24
24
  name: subscription.hypervisor.name