Skip to content
Snippets Groups Projects
Commit 42e5c35c authored by João Alexandre Cunha's avatar João Alexandre Cunha :rocket: Committed by João Alexandre Cunha
Browse files

Fix deploy boards for Kubernetes 1.22

The extensions/v1beta1 was removed on Kubernetes 1.22: https://kubernetes.io/blog/2021/07/14/upcoming-changes-in-kubernetes-1-22/
Whenever we call extensions_client.discover the code raises a 404 not found and we fail to load deployments and ingresses.
Consequently our deploy_boards also fail.

The fix is simply to not use this client anymore, since we don't need to look for resources in this APIs anymore.
We should simply use the new APIs as suggested by the Kubernetes 1.22 documentation.
That is networking.k8s.io/v1 for ingresses and apps/v1 for deployments.

Changelog: fixed
parent 0897e267
No related branches found
No related tags found
1 merge request!90448Resolve "Gitlab doesn't detect the deployment pods after K8s cluster upgrade to v1.22"
This commit is part of merge request !90448. Comments created here will be created in the context of that merge request.
......@@ -81,6 +81,10 @@ class KubeClient
:update_gateway,
to: :istio_client
delegate :get_ingresses, :patch_ingress, to: :networking_client
delegate :get_deployments, to: :apps_client
attr_reader :api_prefix, :kubeclient_options
DEFAULT_KUBECLIENT_OPTIONS = {
......@@ -127,46 +131,6 @@ def initialize(api_prefix, **kubeclient_options)
validate_url!
end
# Deployments resource is currently on the apis/extensions api group
# until Kubernetes 1.15. Kubernetest 1.16+ has deployments resources in
# the apis/apps api group.
#
# As we still support Kubernetes 1.12+, we will need to support both.
def get_deployments(**args)
extensions_client.discover unless extensions_client.discovered
if extensions_client.respond_to?(:get_deployments)
extensions_client.get_deployments(**args)
else
apps_client.get_deployments(**args)
end
end
# Ingresses resource is currently on the apis/extensions api group
# until Kubernetes 1.21. Kubernetest 1.22+ has ingresses resources in
# the networking.k8s.io/v1 api group.
#
# As we still support Kubernetes 1.12+, we will need to support both.
def get_ingresses(**args)
extensions_client.discover unless extensions_client.discovered
if extensions_client.respond_to?(:get_ingresses)
extensions_client.get_ingresses(**args)
else
networking_client.get_ingresses(**args)
end
end
def patch_ingress(*args)
extensions_client.discover unless extensions_client.discovered
if extensions_client.respond_to?(:patch_ingress)
extensions_client.patch_ingress(*args)
else
networking_client.patch_ingress(*args)
end
end
def create_or_update_cluster_role_binding(resource)
update_cluster_role_binding(resource)
end
......
......@@ -171,20 +171,6 @@ def method_call(client, method_name)
end
end
describe '#extensions_client' do
subject { client.extensions_client }
it_behaves_like 'a Kubeclient'
it 'has the extensions API group endpoint' do
expect(subject.api_endpoint.to_s).to match(%r{\/apis\/extensions\Z})
end
it 'has the api_version' do
expect(subject.instance_variable_get(:@api_version)).to eq('v1beta1')
end
end
describe '#istio_client' do
subject { client.istio_client }
......@@ -307,86 +293,38 @@ def method_call(client, method_name)
end
end
describe '#get_deployments' do
let(:extensions_client) { client.extensions_client }
describe 'apps/v1 API group' do
let(:apps_client) { client.apps_client }
include_examples 'redirection not allowed', 'get_deployments'
include_examples 'dns rebinding not allowed', 'get_deployments'
it 'delegates to the extensions client' do
expect(extensions_client).to receive(:get_deployments)
client.get_deployments
end
context 'extensions does not have deployments for Kubernetes 1.16+ clusters' do
before do
WebMock
.stub_request(:get, api_url + '/apis/extensions/v1beta1')
.to_return(kube_response(kube_1_16_extensions_v1beta1_discovery_body))
end
describe 'get_deployments' do
include_examples 'redirection not allowed', 'get_deployments'
include_examples 'dns rebinding not allowed', 'get_deployments'
it 'delegates to the apps client' do
expect(apps_client).to receive(:get_deployments)
client.get_deployments
expect(client).to delegate_method(:get_deployments).to(:apps_client)
end
end
end
describe '#get_ingresses' do
let(:extensions_client) { client.extensions_client }
let(:networking_client) { client.networking_client }
include_examples 'redirection not allowed', 'get_ingresses'
include_examples 'dns rebinding not allowed', 'get_ingresses'
it 'delegates to the extensions client' do
expect(extensions_client).to receive(:get_ingresses)
client.get_ingresses
end
context 'extensions does not have deployments for Kubernetes 1.22+ clusters' do
before do
WebMock
.stub_request(:get, api_url + '/apis/extensions/v1beta1')
.to_return(kube_response(kube_1_22_extensions_v1beta1_discovery_body))
end
it 'delegates to the apps client' do
expect(networking_client).to receive(:get_ingresses)
client.get_ingresses
it 'responds to the method' do
expect(client).to respond_to :get_deployments
end
end
end
describe '#patch_ingress' do
let(:extensions_client) { client.extensions_client }
describe 'networking.k8s.io/v1 API group' do
let(:networking_client) { client.networking_client }
include_examples 'redirection not allowed', 'patch_ingress'
include_examples 'dns rebinding not allowed', 'patch_ingress'
it 'delegates to the extensions client' do
expect(extensions_client).to receive(:patch_ingress)
client.patch_ingress
end
context 'extensions does not have ingress for Kubernetes 1.22+ clusters' do
before do
WebMock
.stub_request(:get, api_url + '/apis/extensions/v1beta1')
.to_return(kube_response(kube_1_22_extensions_v1beta1_discovery_body))
end
[:get_ingresses, :patch_ingress].each do |method|
describe "##{method}" do
include_examples 'redirection not allowed', method
include_examples 'dns rebinding not allowed', method
it 'delegates to the apps client' do
expect(networking_client).to receive(:patch_ingress)
it 'delegates to the networking client' do
expect(client).to delegate_method(method).to(:networking_client)
end
client.patch_ingress
it 'responds to the method' do
expect(client).to respond_to method
end
end
end
end
......
......@@ -39,9 +39,6 @@ def kube_ingresses_response(with_canary: false)
def stub_kubeclient_discover_base(api_url)
WebMock.stub_request(:get, api_url + '/api/v1').to_return(kube_response(kube_v1_discovery_body))
WebMock
.stub_request(:get, api_url + '/apis/extensions/v1beta1')
.to_return(kube_response(kube_extensions_v1beta1_discovery_body))
WebMock
.stub_request(:get, api_url + '/apis/apps/v1')
.to_return(kube_response(kube_apps_v1_discovery_body))
......@@ -149,7 +146,7 @@ def stub_kubeclient_logs(pod_name, namespace, container: nil, status: nil, messa
def stub_kubeclient_deployments(namespace, status: nil)
stub_kubeclient_discover(service.api_url)
deployments_url = service.api_url + "/apis/extensions/v1beta1/namespaces/#{namespace}/deployments"
deployments_url = service.api_url + "/apis/apps/v1/namespaces/#{namespace}/deployments"
response = { status: status } if status
WebMock.stub_request(:get, deployments_url).to_return(response || kube_deployments_response)
......@@ -157,7 +154,7 @@ def stub_kubeclient_deployments(namespace, status: nil)
def stub_kubeclient_ingresses(namespace, status: nil, method: :get, resource_path: "", response: kube_ingresses_response)
stub_kubeclient_discover(service.api_url)
ingresses_url = service.api_url + "/apis/extensions/v1beta1/namespaces/#{namespace}/ingresses#{resource_path}"
ingresses_url = service.api_url + "/apis/networking.k8s.io/v1/namespaces/#{namespace}/ingresses#{resource_path}"
response = { status: status } if status
WebMock.stub_request(method, ingresses_url).to_return(response)
......@@ -314,24 +311,6 @@ def kube_v1_discovery_body
}
end
# From Kubernetes 1.16+ Deployments are no longer served from apis/extensions
def kube_1_16_extensions_v1beta1_discovery_body
{
"kind" => "APIResourceList",
"resources" => [
{ "name" => "ingresses", "namespaced" => true, "kind" => "Deployment" }
]
}
end
# From Kubernetes 1.22+ Ingresses are no longer served from apis/extensions
def kube_1_22_extensions_v1beta1_discovery_body
{
"kind" => "APIResourceList",
"resources" => []
}
end
def kube_knative_discovery_body
{
"kind" => "APIResourceList",
......@@ -339,18 +318,6 @@ def kube_knative_discovery_body
}
end
def kube_extensions_v1beta1_discovery_body
{
"kind" => "APIResourceList",
"resources" => [
{ "name" => "deployments", "namespaced" => true, "kind" => "Deployment" },
{ "name" => "ingresses", "namespaced" => true, "kind" => "Ingress" }
]
}
end
# Yes, deployments are defined in both apis/extensions/v1beta1 and apis/v1
# (for Kubernetes < 1.16). This matches what Kubenetes API server returns.
def kube_apps_v1_discovery_body
{
"kind" => "APIResourceList",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment