summaryrefslogtreecommitdiff
path: root/app/services/packages/terraform_module/create_package_service.rb
blob: d1bc79089a3043eb28113bb4828220bfc84df43f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# frozen_string_literal: true

module Packages
  module TerraformModule
    class CreatePackageService < ::Packages::CreatePackageService
      include Gitlab::Utils::StrongMemoize

      def execute
        return error('Version is empty.', 400) if params[:module_version].blank?
        return error('Access Denied', 403) if current_package_exists_elsewhere?
        return error('Package version already exists.', 403) if current_package_version_exists?
        return error('File is too large.', 400) if file_size_exceeded?

        ApplicationRecord.transaction { create_terraform_module_package! }
      end

      private

      def create_terraform_module_package!
        package = create_package!(:terraform_module, name: name, version: params[:module_version])

        ::Packages::CreatePackageFileService.new(package, file_params).execute

        package
      end

      def current_package_exists_elsewhere?
        ::Packages::Package
          .for_projects(project.root_namespace.all_projects.id_not_in(project.id))
          .with_package_type(:terraform_module)
          .with_name(name)
          .exists?
      end

      def current_package_version_exists?
        project.packages
          .with_package_type(:terraform_module)
          .with_name(name)
          .with_version(params[:module_version])
          .exists?
      end

      def name
        strong_memoize(:name) do
          "#{params[:module_name]}/#{params[:module_system]}"
        end
      end

      def file_name
        strong_memoize(:file_name) do
          "#{params[:module_name]}-#{params[:module_system]}-#{params[:module_version]}.tgz"
        end
      end

      def file_params
        {
          file: params[:file],
          size: params[:file].size,
          file_sha256: params[:file].sha256,
          file_name: file_name,
          build: params[:build]
        }
      end

      def file_size_exceeded?
        project.actual_limits.exceeded?(:generic_packages_max_file_size, params[:file].size)
      end
    end
  end
end