74702f0e0e
Previously this behaviour was only available to group and instance-level clusters, as some project clusters relied on Kubernetes credentials being passed through to the runner instead of having their resources managed by GitLab (which is not available when using JIT). These clusters have been migrated to unmanaged, so resources can be created on demand for the remaining managed clusters.
123 lines
3.9 KiB
Ruby
123 lines
3.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Clusters
|
|
module Gcp
|
|
class FinalizeCreationService
|
|
attr_reader :provider
|
|
|
|
def execute(provider)
|
|
@provider = provider
|
|
|
|
configure_provider
|
|
create_gitlab_service_account!
|
|
configure_kubernetes
|
|
cluster.save!
|
|
rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e
|
|
log_service_error(e.class.name, provider.id, e.message)
|
|
provider.make_errored!(s_('ClusterIntegration|Failed to request to Google Cloud Platform: %{message}') % { message: e.message })
|
|
rescue Kubeclient::HttpError => e
|
|
log_service_error(e.class.name, provider.id, e.message)
|
|
provider.make_errored!(s_('ClusterIntegration|Failed to run Kubeclient: %{message}') % { message: e.message })
|
|
rescue ActiveRecord::RecordInvalid => e
|
|
log_service_error(e.class.name, provider.id, e.message)
|
|
provider.make_errored!(s_('ClusterIntegration|Failed to configure Google Kubernetes Engine Cluster: %{message}') % { message: e.message })
|
|
end
|
|
|
|
private
|
|
|
|
def create_gitlab_service_account!
|
|
Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService.gitlab_creator(
|
|
kube_client,
|
|
rbac: create_rbac_cluster?
|
|
).execute
|
|
end
|
|
|
|
def configure_provider
|
|
provider.endpoint = gke_cluster.endpoint
|
|
provider.status_event = :make_created
|
|
end
|
|
|
|
def configure_kubernetes
|
|
cluster.platform_type = :kubernetes
|
|
cluster.build_platform_kubernetes(
|
|
api_url: 'https://' + gke_cluster.endpoint,
|
|
ca_cert: Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate),
|
|
username: gke_cluster.master_auth.username,
|
|
password: gke_cluster.master_auth.password,
|
|
authorization_type: authorization_type,
|
|
token: request_kubernetes_token)
|
|
end
|
|
|
|
def request_kubernetes_token
|
|
Clusters::Gcp::Kubernetes::FetchKubernetesTokenService.new(
|
|
kube_client,
|
|
Clusters::Gcp::Kubernetes::GITLAB_ADMIN_TOKEN_NAME,
|
|
Clusters::Gcp::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAMESPACE
|
|
).execute
|
|
end
|
|
|
|
def authorization_type
|
|
create_rbac_cluster? ? 'rbac' : 'abac'
|
|
end
|
|
|
|
def create_rbac_cluster?
|
|
!provider.legacy_abac?
|
|
end
|
|
|
|
def kube_client
|
|
@kube_client ||= build_kube_client!(
|
|
'https://' + gke_cluster.endpoint,
|
|
Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate),
|
|
gke_cluster.master_auth.username,
|
|
gke_cluster.master_auth.password
|
|
)
|
|
end
|
|
|
|
def build_kube_client!(api_url, ca_pem, username, password)
|
|
raise "Incomplete settings" unless api_url && username && password
|
|
|
|
Gitlab::Kubernetes::KubeClient.new(
|
|
api_url,
|
|
auth_options: { username: username, password: password },
|
|
ssl_options: kubeclient_ssl_options(ca_pem),
|
|
http_proxy_uri: ENV['http_proxy']
|
|
)
|
|
end
|
|
|
|
def kubeclient_ssl_options(ca_pem)
|
|
opts = { verify_ssl: OpenSSL::SSL::VERIFY_PEER }
|
|
|
|
if ca_pem.present?
|
|
opts[:cert_store] = OpenSSL::X509::Store.new
|
|
opts[:cert_store].add_cert(OpenSSL::X509::Certificate.new(ca_pem))
|
|
end
|
|
|
|
opts
|
|
end
|
|
|
|
def gke_cluster
|
|
@gke_cluster ||= provider.api_client.projects_zones_clusters_get(
|
|
provider.gcp_project_id,
|
|
provider.zone,
|
|
cluster.name)
|
|
end
|
|
|
|
def cluster
|
|
@cluster ||= provider.cluster
|
|
end
|
|
|
|
def logger
|
|
@logger ||= Gitlab::Kubernetes::Logger.build
|
|
end
|
|
|
|
def log_service_error(exception, provider_id, message)
|
|
logger.error(
|
|
exception: exception.class.name,
|
|
service: self.class.name,
|
|
provider_id: provider_id,
|
|
message: message
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|