112 lines
3.2 KiB
Ruby
112 lines
3.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'openssl'
|
|
|
|
module Clusters
|
|
module Kubernetes
|
|
class ConfigureIstioIngressService
|
|
PASSTHROUGH_RESOURCE = Kubeclient::Resource.new(
|
|
mode: 'PASSTHROUGH'
|
|
).freeze
|
|
|
|
MTLS_RESOURCE = Kubeclient::Resource.new(
|
|
mode: 'MUTUAL',
|
|
privateKey: '/etc/istio/ingressgateway-certs/tls.key',
|
|
serverCertificate: '/etc/istio/ingressgateway-certs/tls.crt',
|
|
caCertificates: '/etc/istio/ingressgateway-ca-certs/cert.pem'
|
|
).freeze
|
|
|
|
def initialize(cluster:)
|
|
@cluster = cluster
|
|
@platform = cluster.platform
|
|
@kubeclient = platform.kubeclient
|
|
@knative = cluster.application_knative
|
|
end
|
|
|
|
def execute
|
|
return configure_certificates if serverless_domain_cluster
|
|
|
|
configure_passthrough
|
|
rescue Kubeclient::HttpError => e
|
|
knative.make_errored!(_('Kubernetes error: %{error_code}') % { error_code: e.error_code })
|
|
rescue StandardError
|
|
knative.make_errored!(_('Failed to update.'))
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :cluster, :platform, :kubeclient, :knative
|
|
|
|
def serverless_domain_cluster
|
|
knative&.serverless_domain_cluster
|
|
end
|
|
|
|
def configure_certificates
|
|
create_or_update_istio_cert_and_key
|
|
set_gateway_wildcard_https(MTLS_RESOURCE)
|
|
end
|
|
|
|
def create_or_update_istio_cert_and_key
|
|
name = OpenSSL::X509::Name.parse("CN=#{knative.hostname}")
|
|
|
|
key = OpenSSL::PKey::RSA.new(2048)
|
|
|
|
cert = OpenSSL::X509::Certificate.new
|
|
cert.version = 2
|
|
cert.serial = 0
|
|
cert.not_before = Time.current
|
|
cert.not_after = Time.current + 1000.years
|
|
|
|
cert.public_key = key.public_key
|
|
cert.subject = name
|
|
cert.issuer = name
|
|
cert.sign(key, OpenSSL::Digest.new('SHA256'))
|
|
|
|
serverless_domain_cluster.update!(
|
|
key: key.to_pem,
|
|
certificate: cert.to_pem
|
|
)
|
|
|
|
kubeclient.create_or_update_secret(istio_ca_certs_resource)
|
|
kubeclient.create_or_update_secret(istio_certs_resource)
|
|
end
|
|
|
|
def istio_ca_certs_resource
|
|
Gitlab::Kubernetes::GenericSecret.new(
|
|
'istio-ingressgateway-ca-certs',
|
|
{
|
|
'cert.pem': Base64.strict_encode64(serverless_domain_cluster.certificate)
|
|
},
|
|
Clusters::Kubernetes::ISTIO_SYSTEM_NAMESPACE
|
|
).generate
|
|
end
|
|
|
|
def istio_certs_resource
|
|
Gitlab::Kubernetes::TlsSecret.new(
|
|
'istio-ingressgateway-certs',
|
|
serverless_domain_cluster.certificate,
|
|
serverless_domain_cluster.key,
|
|
Clusters::Kubernetes::ISTIO_SYSTEM_NAMESPACE
|
|
).generate
|
|
end
|
|
|
|
def set_gateway_wildcard_https(tls_resource)
|
|
gateway_resource = gateway
|
|
gateway_resource.spec.servers.each do |server|
|
|
next unless server.hosts == ['*'] && server.port.name == 'https'
|
|
|
|
server.tls = tls_resource
|
|
end
|
|
kubeclient.update_gateway(gateway_resource)
|
|
end
|
|
|
|
def configure_passthrough
|
|
set_gateway_wildcard_https(PASSTHROUGH_RESOURCE)
|
|
end
|
|
|
|
def gateway
|
|
kubeclient.get_gateway('knative-ingress-gateway', Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE)
|
|
end
|
|
end
|
|
end
|
|
end
|