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
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
# frozen_string_literal: true
module Clusters
module Kubernetes
class CreateOrUpdateServiceAccountService
def initialize(kubeclient, service_account_name:, service_account_namespace:, service_account_namespace_labels: nil, token_name:, rbac:, namespace_creator: false, role_binding_name: nil)
@kubeclient = kubeclient
@service_account_name = service_account_name
@service_account_namespace = service_account_namespace
@service_account_namespace_labels = service_account_namespace_labels
@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:, service_account_namespace_labels:, rbac:)
self.new(
kubeclient,
service_account_name: service_account_name,
service_account_namespace: service_account_namespace,
service_account_namespace_labels: service_account_namespace_labels,
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
create_or_update_crossplane_database_role
create_or_update_crossplane_database_role_binding
end
private
attr_reader :kubeclient, :service_account_name, :service_account_namespace, :service_account_namespace_labels, :token_name, :rbac, :namespace_creator, :role_binding_name
def ensure_project_namespace_exists
Gitlab::Kubernetes::Namespace.new(
service_account_namespace,
kubeclient,
labels: service_account_namespace_labels
).ensure_exists!
end
def create_role_or_cluster_role_binding
if namespace_creator
begin
kubeclient.delete_role_binding(role_binding_name, service_account_namespace)
rescue Kubeclient::ResourceNotFoundError
# Do nothing as we will create new role binding below
end
kubeclient.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
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
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
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
end
end
end
|