Class: Gitlab::Kubernetes::KubeClient

Inherits:
Object
  • Object
show all
Includes:
Utils::StrongMemoize
Defined in:
lib/gitlab/kubernetes/kube_client.rb

Overview

Wrapper around Kubeclient::Client to dispatch the right message to the client that can respond to the message. We must have a kubeclient for each ApiGroup as there is no other way to use the Kubeclient gem.

See github.com/abonas/kubeclient/issues/348.

Constant Summary collapse

SUPPORTED_API_GROUPS =
{
  core: { group: 'api', version: 'v1' },
  rbac: { group: 'apis/rbac.authorization.k8s.io', version: 'v1' },
  apps: { group: 'apis/apps', version: 'v1' },
  extensions: { group: 'apis/extensions', version: 'v1beta1' },
  istio: { group: 'apis/networking.istio.io', version: 'v1alpha3' },
  knative: { group: 'apis/serving.knative.dev', version: 'v1alpha1' },
  metrics: { group: 'apis/metrics.k8s.io', version: 'v1beta1' },
  networking: { group: 'apis/networking.k8s.io', version: 'v1' },
  cilium_networking: { group: 'apis/cilium.io', version: 'v2' }
}.freeze
DEFAULT_KUBECLIENT_OPTIONS =
{
  timeouts: {
    open: 10,
    read: 30
  }
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils::StrongMemoize

#clear_memoization, #strong_memoize, #strong_memoized?

Constructor Details

#initialize(api_prefix, **kubeclient_options) ⇒ KubeClient

We disable redirects through 'http_max_redirects: 0', so that KubeClient does not follow redirects and expose internal services.


146
147
148
149
150
151
152
153
# File 'lib/gitlab/kubernetes/kube_client.rb', line 146

def initialize(api_prefix, **kubeclient_options)
  @api_prefix = api_prefix
  @kubeclient_options = DEFAULT_KUBECLIENT_OPTIONS
    .deep_merge(kubeclient_options)
    .merge(http_max_redirects: 0)

  validate_url!
end

Instance Attribute Details

#api_prefixObject (readonly)

Returns the value of attribute api_prefix


109
110
111
# File 'lib/gitlab/kubernetes/kube_client.rb', line 109

def api_prefix
  @api_prefix
end

#kubeclient_optionsObject (readonly)

Returns the value of attribute kubeclient_options


109
110
111
# File 'lib/gitlab/kubernetes/kube_client.rb', line 109

def kubeclient_options
  @kubeclient_options
end

Class Method Details

.graceful_request(cluster_id) ⇒ Object


118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/gitlab/kubernetes/kube_client.rb', line 118

def self.graceful_request(cluster_id)
  { status: :connected, response: yield }
rescue *Gitlab::Kubernetes::Errors::CONNECTION
  { status: :unreachable, connection_error: :connection_error }
rescue *Gitlab::Kubernetes::Errors::AUTHENTICATION
  { status: :authentication_failure, connection_error: :authentication_error }
rescue Kubeclient::HttpError => e
  { status: kubeclient_error_status(e.message), connection_error: :http_error }
rescue => e
  Gitlab::ErrorTracking.track_exception(e, cluster_id: cluster_id)

  { status: :unknown_failure, connection_error: :unknown_error }
end

.kubeclient_error_status(message) ⇒ Object

KubeClient uses the same error class For connection errors (eg. timeout) and for Kubernetes errors.


135
136
137
138
139
140
141
# File 'lib/gitlab/kubernetes/kube_client.rb', line 135

def self.kubeclient_error_status(message)
  if message&.match?(/timed out|timeout/i)
    :unreachable
  else
    :authentication_failure
  end
end

Instance Method Details

#create_or_update_cluster_role_binding(resource) ⇒ Object


170
171
172
# File 'lib/gitlab/kubernetes/kube_client.rb', line 170

def create_or_update_cluster_role_binding(resource)
  update_cluster_role_binding(resource)
end

#create_or_update_role_binding(resource) ⇒ Object


174
175
176
# File 'lib/gitlab/kubernetes/kube_client.rb', line 174

def create_or_update_role_binding(resource)
  update_role_binding(resource)
end

#create_or_update_secret(resource) ⇒ Object


186
187
188
189
190
191
192
# File 'lib/gitlab/kubernetes/kube_client.rb', line 186

def create_or_update_secret(resource)
  if secret_exists?(resource)
    update_secret(resource)
  else
    create_secret(resource)
  end
end

#create_or_update_service_account(resource) ⇒ Object


178
179
180
181
182
183
184
# File 'lib/gitlab/kubernetes/kube_client.rb', line 178

def (resource)
  if (resource)
    (resource)
  else
    (resource)
  end
end

#get_deployments(**args) ⇒ Object

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.


160
161
162
163
164
165
166
167
168
# File 'lib/gitlab/kubernetes/kube_client.rb', line 160

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