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
@@ -27,6 +27,8 @@ module Katello
27
27
  has_many :host_collection_hosts, :class_name => "::Katello::HostCollectionHosts", :foreign_key => :host_id, :dependent => :destroy
28
28
  has_many :host_collections, :class_name => "::Katello::HostCollection", :through => :host_collection_hosts
29
29
 
30
+ has_many :hypervisor_pools, :class_name => '::Katello::Pool', :foreign_key => :hypervisor_id, :dependent => :nullify
31
+
30
32
  before_save :correct_puppet_environment
31
33
 
32
34
  scoped_search :relation => :host_collections, :on => :id, :complete_value => false, :rename => :host_collection_id, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
@@ -24,6 +24,7 @@ module Katello
24
24
  has_many :gpg_keys, :class_name => "Katello::GpgKey", :dependent => :destroy, :inverse_of => :organization
25
25
  has_many :sync_plans, :class_name => "Katello::SyncPlan", :dependent => :destroy, :inverse_of => :organization
26
26
  has_many :host_collections, :class_name => "Katello::HostCollection", :dependent => :destroy, :inverse_of => :organization
27
+ has_many :contents, :class_name => "Katello::Content", :dependent => :destroy, :inverse_of => :organization
27
28
  has_many :content_views, :class_name => "Katello::ContentView", :dependent => :destroy, :inverse_of => :organization
28
29
  has_many :content_view_environments, :through => :content_views
29
30
  has_many :task_statuses, :class_name => "Katello::TaskStatus", :dependent => :destroy, :as => :task_owner
@@ -16,6 +16,16 @@ module Katello
16
16
 
17
17
  prepend ForemanTasks::Concerns::ActionTriggering
18
18
 
19
+ module Prepended
20
+ def update_action
21
+ if subscription_facet.try(:backend_update_needed?)
22
+ ::Actions::Katello::Host::Update
23
+ end
24
+ end
25
+ end
26
+
27
+ prepend Prepended
28
+
19
29
  accepts_nested_attributes_for :subscription_facet, :update_only => true, :reject_if => lambda { |attrs| attrs.values.compact.empty? }
20
30
 
21
31
  has_many :activation_keys, :through => :subscription_facet
@@ -43,12 +53,6 @@ module Katello
43
53
  scoped_search :on => :id, :relation => :pools, :rename => :subscription_id, :complete_value => true, :ext_method => :find_by_subscription_id
44
54
  end
45
55
 
46
- def update_action
47
- if subscription_facet.try(:backend_update_needed?)
48
- ::Actions::Katello::Host::Update
49
- end
50
- end
51
-
52
56
  module ClassMethods
53
57
  def find_by_activation_key(_key, operator, value)
54
58
  conditions = sanitize_sql_for_conditions(["#{Katello::ActivationKey.table_name}.name #{operator} ?", value_to_sql(operator, value)])
@@ -3,15 +3,36 @@ module Katello
3
3
  include Katello::Glue::Candlepin::Content
4
4
  has_many :product_contents, :class_name => 'Katello::ProductContent', :dependent => :destroy
5
5
  has_many :products, :through => :product_contents
6
+ belongs_to :organization, :inverse_of => :contents, :class_name => "::Organization"
6
7
 
7
- validates :label, :uniqueness => true
8
- validates :cp_content_id, :uniqueness => true
8
+ validates :label, :uniqueness => {:scope => :organization_id}
9
+ validates :cp_content_id, :uniqueness => {:scope => :organization_id}
9
10
 
10
11
  scoped_search :on => :name, :complete_value => true
11
12
  scoped_search :on => :content_type, :complete_value => true
12
13
  scoped_search :on => :label, :complete_value => true
13
14
  scoped_search :relation => :products, :on => :name, :rename => :product_name, :complete_value => true
14
15
 
16
+ after_save :update_repository_names, :if => :propagate_name_change?
17
+
18
+ def update_repository_names
19
+ self.repositories.each do |repo|
20
+ repo.update_attributes!(:name => repo.calculate_updated_name)
21
+ end
22
+ end
23
+
24
+ def repositories
25
+ Katello::Repository.where(:content_id => self.cp_content_id)
26
+ end
27
+
28
+ def redhat?
29
+ self.products.first.try(:redhat?)
30
+ end
31
+
32
+ def propagate_name_change?
33
+ self.saved_change_to_attribute?(:name) && self.redhat?
34
+ end
35
+
15
36
  def self.import_all
16
37
  Organization.all.each do |org|
17
38
  org.products.each do |product|
@@ -32,7 +32,7 @@ module Katello
32
32
 
33
33
  query = manifest_klass.in_repositories(repo).where("id in (#{tags_query.to_sql})")
34
34
  names = query.all.collect do |manifest|
35
- manifest.docker_tags.where(:repository => repo).all.collect do |tag|
35
+ manifest.docker_tags.where(:repository => repo).where("name ilike ?", query_name).all.collect do |tag|
36
36
  tag.uuid
37
37
  end
38
38
  end
@@ -5,7 +5,7 @@ module Katello
5
5
 
6
6
  validates_lengths_from_database
7
7
  validates :content_view_id, :presence => true
8
- validates :name, :uniqueness => { :scope => :content_view_id }, :allow_blank => true
8
+ validates :name, :uniqueness => { :scope => :content_view_id, :message => _('There is already a module named "%{value}" in this content view.') }
9
9
  validates :uuid, :uniqueness => { :scope => :content_view_id }, :allow_blank => true
10
10
 
11
11
  validates_with Validators::ContentViewPuppetModuleValidator
@@ -15,6 +15,8 @@ module Katello
15
15
  scoped_search :on => :uuid, :complete_value => true
16
16
  scoped_search :on => :name, :relation => :content_view, :rename => :content_view_name
17
17
 
18
+ before_validation :set_attributes
19
+
18
20
  def puppet_module
19
21
  PuppetModule.find_by_uuid(self.uuid)
20
22
  end
@@ -38,8 +40,6 @@ module Katello
38
40
  self.computed_version.eql?(latest_from_list.try(:version))
39
41
  end
40
42
 
41
- before_save :set_attributes
42
-
43
43
  private
44
44
 
45
45
  def set_attributes
@@ -277,6 +277,10 @@ module Katello
277
277
  ::Katello::DockerMetaTag.where(:repository_id => repositories.archived.docker_type).count
278
278
  end
279
279
 
280
+ def docker_tags
281
+ ::Katello::DockerMetaTag.where(:repository_id => repositories.docker_type)
282
+ end
283
+
280
284
  def debs
281
285
  Katello::Deb.in_repositories(self.repositories.archived)
282
286
  end
@@ -0,0 +1,7 @@
1
+ module Katello
2
+ class EnvironmentPrior < Katello::Model
3
+ belongs_to :env, :class_name => "Katello::KTEnvironment", :inverse_of => :env_priors, :foreign_key => :environment_id
4
+ belongs_to :env_prior, :class_name => "Katello::KTEnvironment", :inverse_of => :env_successors, :foreign_key => :prior_id
5
+ validates :prior_id, :presence => true
6
+ end
7
+ end
@@ -32,7 +32,7 @@ module Katello
32
32
  where("#{self.table_name}.id = (?) or #{self.table_name}.cp_id = (?)", id_integers, ids)
33
33
  end
34
34
 
35
- def import_all(organization = nil)
35
+ def import_all(organization = nil, import_managed_associations = true)
36
36
  organizations = organization ? [organization] : Organization.all
37
37
 
38
38
  organizations.each do |org|
@@ -42,7 +42,7 @@ module Katello
42
42
  objects.each do |item|
43
43
  if candlepin_ids.include?(item.cp_id)
44
44
  item.import_data
45
- item.import_managed_associations if item.respond_to?(:import_managed_associations)
45
+ item.import_managed_associations if import_managed_associations && item.respond_to?(:import_managed_associations)
46
46
  else
47
47
  item.destroy
48
48
  end
@@ -9,8 +9,8 @@ module Katello
9
9
  lazy_accessor :pool_facts, :initializer => lambda { |_s| self.import_lazy_attributes }
10
10
  lazy_accessor :subscription_facts, :initializer => lambda { |_s| self.subscription ? self.subscription.attributes : {} }
11
11
 
12
- lazy_accessor :pool_derived, :owner, :source_pool_id, :virt_limit, :arch, :description, :upstream_pool_id,
13
- :product_family, :variant, :suggested_quantity, :support_type, :product_id, :type, :upstream_entitlement_id,
12
+ lazy_accessor :pool_derived, :owner, :source_pool_id, :virt_limit, :arch, :description, :product_family,
13
+ :variant, :suggested_quantity, :support_type, :product_id, :type, :upstream_entitlement_id,
14
14
  :initializer => :pool_facts
15
15
 
16
16
  lazy_accessor :name, :support_level, :org, :sockets, :cores, :instance_multiplier,
@@ -66,7 +66,6 @@ module Katello
66
66
 
67
67
  json["product_id"] = json["productId"] if json["productId"]
68
68
  json["upstream_entitlement_id"] = json["upstreamEntitlementId"]
69
- json["upstream_pool_id"] = json["upstreamPoolId"]
70
69
 
71
70
  if self.subscription
72
71
  subscription.backend_data["attributes"].map { |attr| json[attr["name"].underscore.to_sym] = attr["value"] }
@@ -91,8 +90,8 @@ module Katello
91
90
  subscription
92
91
  end
93
92
 
94
- # rubocop:disable MethodLength
95
- def import_data(index_hosts = false)
93
+ # rubocop:disable MethodLength,Metrics/AbcSize
94
+ def import_data(index_hosts_and_activation_keys = false)
96
95
  pool_attributes = {}.with_indifferent_access
97
96
  pool_json = self.backend_data
98
97
 
@@ -113,6 +112,7 @@ module Katello
113
112
  pool_attributes[json_attribute.underscore] = pool_json[json_attribute]
114
113
  end
115
114
  pool_attributes[:pool_type] = pool_json["type"] if pool_json.key?("type")
115
+ pool_attributes[:upstream_pool_id] = pool_json["upstreamPoolId"] if pool_json.key?("upstreamPoolId")
116
116
 
117
117
  if pool_attributes.key?(:multi_entitlement)
118
118
  pool_attributes[:multi_entitlement] = pool_attributes[:multi_entitlement] == "yes"
@@ -141,10 +141,11 @@ module Katello
141
141
  exceptions = pool_attributes.keys.map(&:to_sym) - self.attribute_names.map(&:to_sym)
142
142
  self.update_attributes(pool_attributes.except!(*exceptions))
143
143
  self.save!
144
- self.create_activation_key_associations
144
+ self.create_activation_key_associations if index_hosts_and_activation_keys
145
145
  self.create_product_associations
146
- self.import_hosts if index_hosts
146
+ self.import_hosts if index_hosts_and_activation_keys
147
147
  end
148
+ # rubocop:enable MethodLength,Metrics/AbcSize
148
149
 
149
150
  def create_product_associations
150
151
  products = self.backend_data["providedProducts"] + self.backend_data["derivedProvidedProducts"]
@@ -183,6 +184,7 @@ module Katello
183
184
 
184
185
  def import_managed_associations
185
186
  import_hosts
187
+ create_activation_key_associations
186
188
  end
187
189
 
188
190
  def hosts
@@ -190,7 +192,7 @@ module Katello
190
192
  end
191
193
 
192
194
  def create_activation_key_associations
193
- keys = Resources::Candlepin::ActivationKey.get(nil, "?include=id&include=pools.pool.id")
195
+ keys = Resources::Candlepin::ActivationKey.get(nil, "?include=id&include=pools.pool.id", organization.label)
194
196
  activation_key_ids = keys.collect do |key|
195
197
  key['id'] if key['pools'].present? && key['pools'].any? { |pool| pool['pool'].try(:[], 'id') == cp_id }
196
198
  end
@@ -199,11 +201,6 @@ module Katello
199
201
  Katello::PoolActivationKey.where(:activation_key_id => key.id, :pool_id => self.id).first_or_create
200
202
  end
201
203
  end
202
-
203
- def hypervisor
204
- host = ::Host.unscoped.find_by(id: self.hypervisor_id) if self.hypervisor_id
205
- return host if (host && host.authorized?(:view_hosts))
206
- end
207
204
  end
208
205
  end
209
206
  end
@@ -32,14 +32,22 @@ module Katello
32
32
  name.gsub(/[^a-z0-9\-_ ]/i, "")
33
33
  end
34
34
 
35
- def self.import_from_cp(attrs = nil, &block)
35
+ def self.engineering_product_id?(id)
36
+ id.match(/^\d+$/) #engineering products are numeric
37
+ end
38
+
39
+ def self.import_from_cp(attrs, organization)
36
40
  product_content_attrs = attrs.delete(:productContent) || []
37
41
  import_logger = attrs[:import_logger]
38
42
 
39
- attrs = attrs.merge('name' => validate_name(attrs['name']), 'label' => Util::Model.labelize(attrs['name']))
43
+ product_attrs = {'name' => validate_name(attrs['name']),
44
+ 'cp_id' => attrs['id'],
45
+ 'label' => Util::Model.labelize(attrs['name']),
46
+ 'multiplier' => attrs['multiplier'],
47
+ 'organization_id' => organization.id,
48
+ 'provider_id' => organization.redhat_provider.id}
40
49
 
41
- product = Product.new(attrs, &block)
42
- product.save!
50
+ product = Product.create!(product_attrs)
43
51
  import_product_content(product, product_content_attrs)
44
52
  rescue => e
45
53
  [Rails.logger, import_logger].each do |logger|
@@ -60,16 +68,18 @@ module Katello
60
68
  content_type: pc[:type],
61
69
  vendor: pc[:vendor],
62
70
  gpg_url: pc[:gpgUrl],
63
- content_url: pc[:contentUrl]
71
+ content_url: pc[:contentUrl],
72
+ organization_id: product.organization_id
64
73
  }
65
74
 
66
- # current product has this content - update it
75
+ # current product has this content - update its name if needed
67
76
  # otherwise create a reference to existing content OR new content altogether
68
77
  if (existing = product.product_content_by_id(pc[:id]))
69
- existing.content.update_attributes!(content_attrs)
70
- existing.update_attributes(enabled: params['enabled'])
78
+ new_name = pc['name']
79
+ existing.content.update_attributes!(:name => new_name) if existing.content.name != new_name
80
+ existing.update_attributes!(enabled: params['enabled']) if existing.enabled != params['enabled']
71
81
  else
72
- content = ::Katello::Content.find_by_cp_content_id(pc[:id])
82
+ content = ::Katello::Content.where(:cp_content_id => pc[:id], :organization_id => product.organization_id).first
73
83
  content ||= ::Katello::Content.create!(content_attrs)
74
84
 
75
85
  ::Katello::ProductContent.create!(enabled: params[:enabled],
@@ -10,6 +10,22 @@ module Katello
10
10
  end
11
11
 
12
12
  module InstanceMethods
13
+ def substitutions
14
+ {
15
+ :releasever => self.minor,
16
+ :basearch => self.arch
17
+ }
18
+ end
19
+
20
+ def content
21
+ Katello::Content.find_by(:cp_content_id => self.content_id, :organization_id => self.product.organization_id)
22
+ end
23
+
24
+ def calculate_updated_name
25
+ fail _("Cannot calculate name for custom repos") if custom?
26
+ Katello::Candlepin::RepositoryMapper.new(self.product, self.content, self.substitutions).name
27
+ end
28
+
13
29
  def should_update_content?
14
30
  (self.gpg_key_id_was.nil? && !self.gpg_key_id.nil? && self.content.gpgUrl == '') ||
15
31
  (!self.gpg_key_id_was.nil? && self.gpg_key_id.nil? && self.content.gpgUrl != '')
@@ -18,7 +18,7 @@ module Katello
18
18
  def get_for_owner(organization)
19
19
  Katello::Resources::Candlepin::Product.all(organization).select do |product|
20
20
  #this product's id is non-numeric (marketing product), or its a custom product
21
- product['id'].to_i.to_s != product['id'] || Katello::Product.find_by(:cp_id => product['id']).try(:custom?)
21
+ !Glue::Candlepin::Product.engineering_product_id?(product['id']) || Katello::Product.find_by(:cp_id => product['id']).try(:custom?)
22
22
  end
23
23
  end
24
24
  end
@@ -123,68 +123,28 @@ module Katello
123
123
  ::Foreman::Logging.logger('katello/manifest_import_logger')
124
124
  end
125
125
 
126
- def update_product_content_from_cp(katello_and_cp_ids)
127
- katello_and_cp_ids.each do |id_pair|
128
- attrs = Resources::Candlepin::Product.get(self.organization.label, id_pair.second, %w(productContent)).first
129
- product_content_attrs = attrs.delete(:productContent) || []
130
- product = ::Katello::Product.find(id_pair.first)
131
- Glue::Candlepin::Product.import_product_content(product, product_content_attrs)
132
- end
133
- end
134
-
135
- # TODO: break up method
136
- def import_products_from_cp # rubocop:disable MethodLength
137
- db_and_cp_ids = self.organization.providers.redhat.first.products.pluck(:id, :cp_id)
138
-
139
- # this method only imports products which are not already in Katello
140
- # no need for a full import on them - just update the product content
141
- update_product_content_from_cp(db_and_cp_ids)
142
-
143
- product_in_katello_ids = db_and_cp_ids.map(&:second)
144
- products_in_candlepin_ids = []
145
-
146
- marketing_to_engineering_product_ids_mapping.each do |marketing_product_id, engineering_product_ids|
147
- engineering_product_ids = engineering_product_ids.uniq
148
- products_in_candlepin_ids << marketing_product_id
149
- products_in_candlepin_ids.concat(engineering_product_ids)
150
- added_eng_products = (engineering_product_ids - product_in_katello_ids).map do |id|
151
- Resources::Candlepin::Product.get(self.organization.label, id)[0]
152
- end
153
- adjusted_eng_products = []
154
- added_eng_products.each do |product_attrs|
155
- begin
156
- Glue::Candlepin::Product.import_from_cp(product_attrs) do |p|
157
- p.provider = self
158
- p.organization_id = self.organization.id
159
- end
160
- adjusted_eng_products << product_attrs
161
- import_logger.info "import of product '#{product_attrs["name"]}' from Candlepin OK"
162
- rescue Errors::SecurityViolation => e
163
- # Do not add non-accessible products
164
- logger.info "import of product '#{product_attrs["name"]}' from Candlepin failed"
165
- import_logger.info e
166
- end
167
- end
168
-
169
- product_in_katello_ids.concat(adjusted_eng_products.map { |p| p["id"] })
170
-
171
- marketing_product = Katello::Product.find_by_cp_id(marketing_product_id)
172
- marketing_product.destroy if marketing_product && marketing_product.redhat?
173
- end
126
+ def import_products_from_cp
127
+ cp_products = ::Katello::Resources::Candlepin::Product.all(organization.label, [:id, :name, :multiplier, :productContent])
128
+ cp_products = cp_products.select { |prod| Glue::Candlepin::Product.engineering_product_id?(prod['id']) }
174
129
 
175
- product_to_remove_ids = (product_in_katello_ids - products_in_candlepin_ids).uniq
176
- product_to_remove_ids.each do |cp_id|
177
- product = Product.find_by_cp_id(cp_id, self.organization)
178
- Rails.logger.warn "Orphaned Product id #{product.id} found while refreshing/importing manifest."
179
- end
130
+ cp_products.each { |product| import_product(product) }
180
131
 
181
132
  self.index_subscriptions(self.organization)
182
- true
133
+ end
134
+
135
+ def import_product(cp_product)
136
+ product = organization.products.find_by(:cp_id => cp_product['id'])
137
+ if product && product.redhat?
138
+ product.update_attributes!(:name => cp_product['name']) unless product.name == cp_product['name']
139
+ Glue::Candlepin::Product.import_product_content(product, cp_product['productContent'])
140
+ elsif product.nil?
141
+ Glue::Candlepin::Product.import_from_cp(cp_product, organization)
142
+ end
183
143
  end
184
144
 
185
145
  def index_subscriptions(organization = nil)
186
146
  Katello::Subscription.import_all(organization)
187
- Katello::Pool.import_all(organization)
147
+ Katello::Pool.import_all(organization, false)
188
148
  end
189
149
 
190
150
  def rules_source
@@ -197,32 +157,6 @@ module Katello
197
157
 
198
158
  protected
199
159
 
200
- # When a subscription is defined as a virtual data center subscription,
201
- # its pools will have a seperate 'derived' marketing product and a seperate set
202
- # of 'derived' engineering products. These products become the marketing and
203
- # engineering products for the sub pool once a host binds to the original pool.
204
- # We need to make sure to include these 'derived' products when creating our mapping.
205
- def marketing_to_engineering_product_ids_mapping
206
- mapping = {}
207
- pools = Resources::Candlepin::Owner.pools self.organization.label
208
- pools.each do |pool|
209
- mapping[pool[:productId]] ||= []
210
- if pool[:providedProducts]
211
- eng_product_ids = pool[:providedProducts].map { |provided| provided[:productId] }
212
- mapping[pool[:productId]].concat(eng_product_ids)
213
- end
214
- # Check to see if there are any 'derived' products defined.
215
- if pool[:derivedProductId]
216
- mapping[pool[:derivedProductId]] ||= []
217
- if pool[:derivedProvidedProducts]
218
- eng_product_ids = pool[:derivedProvidedProducts].map { |provided| provided[:productId] }
219
- mapping[pool[:derivedProductId]].concat(eng_product_ids)
220
- end
221
- end
222
- end
223
- mapping
224
- end
225
-
226
160
  def candlepin_ping
227
161
  @candlepin_ping ||= Resources::Candlepin::CandlepinPing.ping
228
162
  end
@@ -1,7 +1,7 @@
1
1
  module Katello
2
2
  module Host
3
3
  class SubscriptionFacet < Katello::Model
4
- audited :associations => [:pools]
4
+ audited :associations => [:pools], :except => [:last_checkin]
5
5
  self.table_name = 'katello_subscription_facets'
6
6
  include Facets::Base
7
7