Commit 6a88f187 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'fix-kubernetes-namespace' into 'master'

Fix terminals support for Kubernetes service

Closes #31754

See merge request !11653
parents 5b67839b 911e1c2d
...@@ -77,6 +77,14 @@ class KubernetesService < DeploymentService ...@@ -77,6 +77,14 @@ class KubernetesService < DeploymentService
] ]
end end
def actual_namespace
if namespace.present?
namespace
else
default_namespace
end
end
# Check we can connect to the Kubernetes API # Check we can connect to the Kubernetes API
def test(*args) def test(*args)
kubeclient = build_kubeclient! kubeclient = build_kubeclient!
...@@ -91,7 +99,7 @@ class KubernetesService < DeploymentService ...@@ -91,7 +99,7 @@ class KubernetesService < DeploymentService
variables = [ variables = [
{ key: 'KUBE_URL', value: api_url, public: true }, { key: 'KUBE_URL', value: api_url, public: true },
{ key: 'KUBE_TOKEN', value: token, public: false }, { key: 'KUBE_TOKEN', value: token, public: false },
{ key: 'KUBE_NAMESPACE', value: namespace_variable, public: true } { key: 'KUBE_NAMESPACE', value: actual_namespace, public: true }
] ]
if ca_pem.present? if ca_pem.present?
...@@ -110,7 +118,7 @@ class KubernetesService < DeploymentService ...@@ -110,7 +118,7 @@ class KubernetesService < DeploymentService
with_reactive_cache do |data| with_reactive_cache do |data|
pods = data.fetch(:pods, nil) pods = data.fetch(:pods, nil)
filter_pods(pods, app: environment.slug). filter_pods(pods, app: environment.slug).
flat_map { |pod| terminals_for_pod(api_url, namespace, pod) }. flat_map { |pod| terminals_for_pod(api_url, actual_namespace, pod) }.
each { |terminal| add_terminal_auth(terminal, terminal_auth) } each { |terminal| add_terminal_auth(terminal, terminal_auth) }
end end
end end
...@@ -124,7 +132,7 @@ class KubernetesService < DeploymentService ...@@ -124,7 +132,7 @@ class KubernetesService < DeploymentService
# Store as hashes, rather than as third-party types # Store as hashes, rather than as third-party types
pods = begin pods = begin
kubeclient.get_pods(namespace: namespace).as_json kubeclient.get_pods(namespace: actual_namespace).as_json
rescue KubeException => err rescue KubeException => err
raise err unless err.error_code == 404 raise err unless err.error_code == 404
[] []
...@@ -142,20 +150,12 @@ class KubernetesService < DeploymentService ...@@ -142,20 +150,12 @@ class KubernetesService < DeploymentService
default_namespace || TEMPLATE_PLACEHOLDER default_namespace || TEMPLATE_PLACEHOLDER
end end
def namespace_variable
if namespace.present?
namespace
else
default_namespace
end
end
def default_namespace def default_namespace
"#{project.path}-#{project.id}" if project.present? "#{project.path}-#{project.id}" if project.present?
end end
def build_kubeclient!(api_path: 'api', api_version: 'v1') def build_kubeclient!(api_path: 'api', api_version: 'v1')
raise "Incomplete settings" unless api_url && namespace && token raise "Incomplete settings" unless api_url && actual_namespace && token
::Kubeclient::Client.new( ::Kubeclient::Client.new(
join_api_url(api_path), join_api_url(api_path),
......
---
title: Fix terminals support for Kubernetes Service
merge_request:
author:
...@@ -20,7 +20,6 @@ FactoryGirl.define do ...@@ -20,7 +20,6 @@ FactoryGirl.define do
project factory: :empty_project project factory: :empty_project
active true active true
properties({ properties({
namespace: 'somepath',
api_url: 'https://kubernetes.example.com', api_url: 'https://kubernetes.example.com',
token: 'a' * 40 token: 'a' * 40
}) })
......
...@@ -13,7 +13,7 @@ describe KubernetesService, models: true, caching: true do ...@@ -13,7 +13,7 @@ describe KubernetesService, models: true, caching: true do
let(:discovery_url) { service.api_url + '/api/v1' } let(:discovery_url) { service.api_url + '/api/v1' }
let(:discovery_response) { { body: kube_discovery_body.to_json } } let(:discovery_response) { { body: kube_discovery_body.to_json } }
let(:pods_url) { service.api_url + "/api/v1/namespaces/#{service.namespace}/pods" } let(:pods_url) { service.api_url + "/api/v1/namespaces/#{service.actual_namespace}/pods" }
let(:pods_response) { { body: kube_pods_body(kube_pod).to_json } } let(:pods_response) { { body: kube_pods_body(kube_pod).to_json } }
def stub_kubeclient_discover def stub_kubeclient_discover
...@@ -105,6 +105,34 @@ describe KubernetesService, models: true, caching: true do ...@@ -105,6 +105,34 @@ describe KubernetesService, models: true, caching: true do
end end
end end
describe '#actual_namespace' do
subject { service.actual_namespace }
it "returns the default namespace" do
is_expected.to eq(service.send(:default_namespace))
end
context 'when namespace is specified' do
before do
service.namespace = 'my-namespace'
end
it "returns the user-namespace" do
is_expected.to eq('my-namespace')
end
end
context 'when service is not assigned to project' do
before do
service.project = nil
end
it "does not return namespace" do
is_expected.to be_nil
end
end
end
describe '#test' do describe '#test' do
before do before do
stub_kubeclient_discover stub_kubeclient_discover
...@@ -194,6 +222,7 @@ describe KubernetesService, models: true, caching: true do ...@@ -194,6 +222,7 @@ describe KubernetesService, models: true, caching: true do
describe '#terminals' do describe '#terminals' do
let(:environment) { build(:environment, project: project, name: "env", slug: "env-000000") } let(:environment) { build(:environment, project: project, name: "env", slug: "env-000000") }
subject { service.terminals(environment) } subject { service.terminals(environment) }
context 'with invalid pods' do context 'with invalid pods' do
......
...@@ -41,7 +41,7 @@ module KubernetesHelpers ...@@ -41,7 +41,7 @@ module KubernetesHelpers
containers.map do |container| containers.map do |container|
terminal = { terminal = {
selectors: { pod: pod_name, container: container['name'] }, selectors: { pod: pod_name, container: container['name'] },
url: container_exec_url(service.api_url, service.namespace, pod_name, container['name']), url: container_exec_url(service.api_url, service.actual_namespace, pod_name, container['name']),
subprotocols: ['channel.k8s.io'], subprotocols: ['channel.k8s.io'],
headers: { 'Authorization' => ["Bearer #{service.token}"] }, headers: { 'Authorization' => ["Bearer #{service.token}"] },
created_at: DateTime.parse(pod['metadata']['creationTimestamp']), created_at: DateTime.parse(pod['metadata']['creationTimestamp']),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment