summaryrefslogtreecommitdiff
path: root/lib/api/variables.rb
blob: 50d137ec7c1dde14475bcff8157e37f2debf9bc1 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# frozen_string_literal: true

module API
  class Variables < Grape::API::Instance
    include PaginationParams

    before { authenticate! }
    before { authorize! :admin_build, user_project }

    helpers do
      def filter_variable_parameters(params)
        # This method exists so that EE can more easily filter out certain
        # parameters, without having to modify the source code directly.
        params
      end

      def find_variable(params)
        variables = ::Ci::VariablesFinder.new(user_project, params).execute.to_a

        return variables.first unless ::Gitlab::Ci::Features.variables_api_filter_environment_scope?
        return variables.first unless variables.many? # rubocop: disable CodeReuse/ActiveRecord

        conflict!("There are multiple variables with provided parameters. Please use 'filter[environment_scope]'")
      end
    end

    params do
      requires :id, type: String, desc: 'The ID of a project'
    end

    resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
      desc 'Get project variables' do
        success Entities::Variable
      end
      params do
        use :pagination
      end
      get ':id/variables' do
        variables = user_project.variables
        present paginate(variables), with: Entities::Variable
      end

      desc 'Get a specific variable from a project' do
        success Entities::Variable
      end
      params do
        requires :key, type: String, desc: 'The key of the variable'
      end
      # rubocop: disable CodeReuse/ActiveRecord
      get ':id/variables/:key' do
        variable = find_variable(params)
        not_found!('Variable') unless variable

        present variable, with: Entities::Variable
      end
      # rubocop: enable CodeReuse/ActiveRecord

      desc 'Create a new variable in a project' do
        success Entities::Variable
      end
      params do
        requires :key, type: String, desc: 'The key of the variable'
        requires :value, type: String, desc: 'The value of the variable'
        optional :protected, type: Boolean, desc: 'Whether the variable is protected'
        optional :masked, type: Boolean, desc: 'Whether the variable is masked'
        optional :variable_type, type: String, values: ::Ci::Variable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file. Defaults to env_var'
        optional :environment_scope, type: String, desc: 'The environment_scope of the variable'
      end
      post ':id/variables' do
        variable_params = declared_params(include_missing: false)
        variable_params = filter_variable_parameters(variable_params)

        variable = user_project.variables.create(variable_params)

        if variable.valid?
          present variable, with: Entities::Variable
        else
          render_validation_error!(variable)
        end
      end

      desc 'Update an existing variable from a project' do
        success Entities::Variable
      end
      params do
        optional :key, type: String, desc: 'The key of the variable'
        optional :value, type: String, desc: 'The value of the variable'
        optional :protected, type: Boolean, desc: 'Whether the variable is protected'
        optional :masked, type: Boolean, desc: 'Whether the variable is masked'
        optional :variable_type, type: String, values: ::Ci::Variable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file'
        optional :environment_scope, type: String, desc: 'The environment_scope of the variable'
        optional :filter, type: Hash, desc: 'Available filters: [environment_scope]. Example: filter[environment_scope]=production'
      end
      # rubocop: disable CodeReuse/ActiveRecord
      put ':id/variables/:key' do
        variable = find_variable(params)
        not_found!('Variable') unless variable

        variable_params = declared_params(include_missing: false).except(:key, :filter)
        variable_params = filter_variable_parameters(variable_params)

        if variable.update(variable_params)
          present variable, with: Entities::Variable
        else
          render_validation_error!(variable)
        end
      end
      # rubocop: enable CodeReuse/ActiveRecord

      desc 'Delete an existing variable from a project' do
        success Entities::Variable
      end
      params do
        requires :key, type: String, desc: 'The key of the variable'
        optional :filter, type: Hash, desc: 'Available filters: [environment_scope]. Example: filter[environment_scope]=production'
      end
      # rubocop: disable CodeReuse/ActiveRecord
      delete ':id/variables/:key' do
        variable = find_variable(params)
        not_found!('Variable') unless variable

        # Variables don't have a timestamp. Therefore, destroy unconditionally.
        variable.destroy

        no_content!
      end
      # rubocop: enable CodeReuse/ActiveRecord
    end
  end
end