diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index b2494a0be6e9ca9904167edca1ac81d61c30e1b1..8977a7cdafe397d2d94257d53132f91139d97f5c 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -77,6 +77,14 @@ class KubernetesService < DeploymentService ] end + def actual_namespace + if namespace.present? + namespace + else + default_namespace + end + end + # Check we can connect to the Kubernetes API def test(*args) kubeclient = build_kubeclient! @@ -91,7 +99,7 @@ class KubernetesService < DeploymentService variables = [ { key: 'KUBE_URL', value: api_url, public: true }, { 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? @@ -110,7 +118,7 @@ class KubernetesService < DeploymentService with_reactive_cache do |data| pods = data.fetch(:pods, nil) 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) } end end @@ -124,7 +132,7 @@ class KubernetesService < DeploymentService # Store as hashes, rather than as third-party types pods = begin - kubeclient.get_pods(namespace: namespace).as_json + kubeclient.get_pods(namespace: actual_namespace).as_json rescue KubeException => err raise err unless err.error_code == 404 [] @@ -142,20 +150,12 @@ class KubernetesService < DeploymentService default_namespace || TEMPLATE_PLACEHOLDER end - def namespace_variable - if namespace.present? - namespace - else - default_namespace - end - end - def default_namespace "#{project.path}-#{project.id}" if project.present? end 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( join_api_url(api_path), diff --git a/changelogs/unreleased/fix-terminals-support-for-kubernetes-service.yml b/changelogs/unreleased/fix-terminals-support-for-kubernetes-service.yml new file mode 100644 index 0000000000000000000000000000000000000000..fb91da9510c2580e3e924cdcf2c7eb7dfbe26973 --- /dev/null +++ b/changelogs/unreleased/fix-terminals-support-for-kubernetes-service.yml @@ -0,0 +1,4 @@ +--- +title: Fix terminals support for Kubernetes Service +merge_request: +author: diff --git a/spec/factories/services.rb b/spec/factories/services.rb index 28ddd0da753ff4914fc9e207cc6983487472bc6b..3fad4d2d6588b94fd49abdb3e2013cfcd7999e2a 100644 --- a/spec/factories/services.rb +++ b/spec/factories/services.rb @@ -20,7 +20,6 @@ FactoryGirl.define do project factory: :empty_project active true properties({ - namespace: 'somepath', api_url: 'https://kubernetes.example.com', token: 'a' * 40 }) diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index c1c2f2a721982ba08307372e3211c88a478a09f6..57c51ebea7bb0828b1798b384bf204ba368b6d8c 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -13,7 +13,7 @@ describe KubernetesService, models: true, caching: true do let(:discovery_url) { service.api_url + '/api/v1' } 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 } } def stub_kubeclient_discover @@ -105,6 +105,34 @@ describe KubernetesService, models: true, caching: true do 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 before do stub_kubeclient_discover @@ -194,6 +222,7 @@ describe KubernetesService, models: true, caching: true do describe '#terminals' do let(:environment) { build(:environment, project: project, name: "env", slug: "env-000000") } + subject { service.terminals(environment) } context 'with invalid pods' do diff --git a/spec/support/kubernetes_helpers.rb b/spec/support/kubernetes_helpers.rb index d2a1ded57ff2e1d76e290b179958166c9a38ee6c..9280fad4ace2ff4062152c16dfe81f8a8273ac32 100644 --- a/spec/support/kubernetes_helpers.rb +++ b/spec/support/kubernetes_helpers.rb @@ -41,7 +41,7 @@ module KubernetesHelpers containers.map do |container| terminal = { 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'], headers: { 'Authorization' => ["Bearer #{service.token}"] }, created_at: DateTime.parse(pod['metadata']['creationTimestamp']),