module Katello module Pulp3 module ContentViewVersion class ImportValidator BASEDIR = '/var/lib/pulp'.freeze attr_accessor :metadata, :path, :content_view def initialize(content_view:, path:, metadata:) self.content_view = content_view self.path = path self.metadata = metadata end def check! check_permissions! ensure_importing_cvv_does_not_exist! ensure_from_cvv_exists! ensure_repositories_metadata_and_content_view_match! end def ensure_importing_cvv_does_not_exist! major = metadata[:content_view_version][:major] minor = metadata[:content_view_version][:minor] if ::Katello::ContentViewVersion.where(major: major, minor: minor, content_view: content_view).exists? fail _("Content View Version specified in the metadata - '%{name}' already exists. "\ "If you wish to replace the existing version, delete %{name} and try again. " % { name: "#{content_view.name} #{major}.#{minor}" }) end end def ensure_from_cvv_exists! major = metadata[:content_view_version][:major] minor = metadata[:content_view_version][:minor] if metadata[:from_content_view_version].present? from_major = metadata[:from_content_view_version][:major] from_minor = metadata[:from_content_view_version][:minor] unless ::Katello::ContentViewVersion.where(major: from_major, minor: from_minor, content_view: content_view).exists? fail _("Prior Content View Version specified in the metadata - '%{name}' does not exist. "\ "Please import the metadata for '%{name}' before importing '%{current}' " % { name: "#{content_view.name} #{from_major}.#{from_minor}", current: "#{content_view.name} #{major}.#{minor}"}) end end end def ensure_repositories_metadata_and_content_view_match! product_repos_in_content_view = content_view.repositories.yum_type.map { |repo| [repo.product.name, repo.name, repo.redhat?] } product_repos_in_metadata = metadata[:repository_mapping].values.map { |repo| [repo[:product], repo[:repository], repo[:redhat]] } product_repos_in_content_view.sort! product_repos_in_metadata.sort! # product_repos_in_content_view & product_repos_in_metadata look like [["prod1", "repo1", false], ["prod2", "repo2", false]] if product_repos_in_content_view != product_repos_in_metadata repos_in_content_view = generate_product_repo_i18n_string(product_repos_in_content_view) repos_in_import = generate_product_repo_i18n_string(product_repos_in_metadata) fail _("Repositories in the importing content view do not match the repositories provided in the import metadata.\n "\ "Repositories in Content View '%{content_view}': %{repos_in_content_view}\n "\ "Repositories in the Import Metadata: %{repos_in_import}" % { content_view: content_view.name, repos_in_content_view: repos_in_content_view.join(""), repos_in_import: repos_in_import.join("")} ) end end def check_permissions! fail _("Invalid path specified.") if path.blank? || !File.directory?(path) fail _("The import path must be in a subdirectory under '%s'." % BASEDIR) unless path.starts_with?(BASEDIR) fail _("Pulp user or group unable to read content in '%s'." % path) unless pulp_user_accessible?(path) Dir.glob("#{path}/*").each do |file| fail _("Pulp user or group unable to read '%s'." % file) unless pulp_user_accessible?(file) end toc_path = "#{path}/#{metadata[:toc]}" fail _("The TOC file specified in the metadata does not exist. %s " % toc_path) unless File.exist?(toc_path) end def pulp_user_accessible?(path) pulp_info = fetch_pulp_user_info return false if pulp_info.blank? stat = File.stat(path) stat.gid.to_s == pulp_info.gid || stat.uid.to_s == pulp_info.uid || stat.mode.to_s(8)[-1].to_i >= 4 end def fetch_pulp_user_info pulp_user = nil Etc.passwd { |u| pulp_user = u if u.name == 'pulp' } pulp_user end def generate_product_repo_i18n_string(product_repos) # product_repos look like [["prod1", "repo1", false], ["prod2", "repo2", false]] product_repos.map do |product, repo, redhat| repo_type = redhat ? _("Red Hat") : _("Custom") _("\n* Product = '%{product}', Repository = '%{repository}', Repository Type = '%{repo_type}'" % { product: product, repository: repo, repo_type: repo_type}) end end end end end end