Read about our upcoming Code of Conduct on this issue

create_or_update_service_account_service.rb 7.2 KB
Newer Older
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
# frozen_string_literal: true

module Clusters
  module Kubernetes
    class CreateOrUpdateServiceAccountService
      def initialize(kubeclient, service_account_name:, service_account_namespace:, token_name:, rbac:, namespace_creator: false, role_binding_name: nil)
        @kubeclient = kubeclient
        @service_account_name = service_account_name
        @service_account_namespace = service_account_namespace
        @token_name = token_name
        @rbac = rbac
        @namespace_creator = namespace_creator
        @role_binding_name = role_binding_name
      end

      def self.gitlab_creator(kubeclient, rbac:)
        self.new(
          kubeclient,
          service_account_name: Clusters::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAME,
          service_account_namespace: Clusters::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAMESPACE,
          token_name: Clusters::Kubernetes::GITLAB_ADMIN_TOKEN_NAME,
          rbac: rbac
        )
      end

      def self.namespace_creator(kubeclient, service_account_name:, service_account_namespace:, rbac:)
        self.new(
          kubeclient,
          service_account_name: service_account_name,
          service_account_namespace: service_account_namespace,
          token_name: "#{service_account_namespace}-token",
          rbac: rbac,
          namespace_creator: true,
          role_binding_name: "gitlab-#{service_account_namespace}"
        )
      end

      def execute
        ensure_project_namespace_exists if namespace_creator

        kubeclient.create_or_update_service_account(service_account_resource)
        kubeclient.create_or_update_secret(service_account_token_resource)

        return unless rbac

        create_role_or_cluster_role_binding

        return unless namespace_creator

        create_or_update_knative_serving_role
        create_or_update_knative_serving_role_binding
52

53
54
        create_or_update_crossplane_database_role
        create_or_update_crossplane_database_role_binding
55
56
57
58
59

        return unless knative_serving_namespace

        create_or_update_knative_version_role
        create_or_update_knative_version_role_binding
60
61
62
63
64
65
66
67
68
69
70
71
72
      end

      private

      attr_reader :kubeclient, :service_account_name, :service_account_namespace, :token_name, :rbac, :namespace_creator, :role_binding_name

      def ensure_project_namespace_exists
        Gitlab::Kubernetes::Namespace.new(
          service_account_namespace,
          kubeclient
        ).ensure_exists!
      end

73
      def knative_serving_namespace
74
75
76
        kubeclient.get_namespace(Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE)
      rescue Kubeclient::ResourceNotFoundError
        nil
77
78
      end

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
      def create_role_or_cluster_role_binding
        if namespace_creator
          kubeclient.create_or_update_role_binding(role_binding_resource)
        else
          kubeclient.create_or_update_cluster_role_binding(cluster_role_binding_resource)
        end
      end

      def create_or_update_knative_serving_role
        kubeclient.update_role(knative_serving_role_resource)
      end

      def create_or_update_knative_serving_role_binding
        kubeclient.update_role_binding(knative_serving_role_binding_resource)
      end

95
96
97
98
99
100
101
102
      def create_or_update_crossplane_database_role
        kubeclient.update_role(crossplane_database_role_resource)
      end

      def create_or_update_crossplane_database_role_binding
        kubeclient.update_role_binding(crossplane_database_role_binding_resource)
      end

103
104
105
106
107
108
109
110
      def create_or_update_knative_version_role
        kubeclient.update_cluster_role(knative_version_role_resource)
      end

      def create_or_update_knative_version_role_binding
        kubeclient.update_cluster_role_binding(knative_version_role_binding_resource)
      end

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
      def service_account_resource
        Gitlab::Kubernetes::ServiceAccount.new(
          service_account_name,
          service_account_namespace
        ).generate
      end

      def service_account_token_resource
        Gitlab::Kubernetes::ServiceAccountToken.new(
          token_name,
          service_account_name,
          service_account_namespace
        ).generate
      end

      def cluster_role_binding_resource
        subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: service_account_namespace }]

        Gitlab::Kubernetes::ClusterRoleBinding.new(
          Clusters::Kubernetes::GITLAB_CLUSTER_ROLE_BINDING_NAME,
          Clusters::Kubernetes::GITLAB_CLUSTER_ROLE_NAME,
          subjects
        ).generate
      end

      def role_binding_resource
        Gitlab::Kubernetes::RoleBinding.new(
          name: role_binding_name,
          role_name: Clusters::Kubernetes::PROJECT_CLUSTER_ROLE_NAME,
          role_kind: :ClusterRole,
          namespace: service_account_namespace,
          service_account_name: service_account_name
        ).generate
      end

      def knative_serving_role_resource
        Gitlab::Kubernetes::Role.new(
          name: Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME,
          namespace: service_account_namespace,
          rules: [{
            apiGroups: %w(serving.knative.dev),
            resources: %w(configurations configurationgenerations routes revisions revisionuids autoscalers services),
            verbs: %w(get list create update delete patch watch)
          }]
        ).generate
      end

      def knative_serving_role_binding_resource
        Gitlab::Kubernetes::RoleBinding.new(
          name: Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME,
          role_name: Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME,
          role_kind: :Role,
          namespace: service_account_namespace,
          service_account_name: service_account_name
        ).generate
      end
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

      def crossplane_database_role_resource
        Gitlab::Kubernetes::Role.new(
          name: Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME,
          namespace: service_account_namespace,
          rules: [{
            apiGroups: %w(database.crossplane.io),
            resources: %w(postgresqlinstances),
            verbs: %w(get list create watch)
          }]
        ).generate
      end

      def crossplane_database_role_binding_resource
        Gitlab::Kubernetes::RoleBinding.new(
          name: Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME,
          role_name: Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME,
          role_kind: :Role,
          namespace: service_account_namespace,
          service_account_name: service_account_name
        ).generate
      end
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

      def knative_version_role_resource
        Gitlab::Kubernetes::ClusterRole.new(
          name: Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_NAME,
          rules: [{
            apiGroups: %w(apps),
            resources: %w(deployments),
            verbs: %w(list get)
          }]
        ).generate
      end

      def knative_version_role_binding_resource
        subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: service_account_namespace }]

        Gitlab::Kubernetes::ClusterRoleBinding.new(
          Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME,
          Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_NAME,
          subjects
        ).generate
      end
210
211
212
    end
  end
end