Class: K8s::Client
- Inherits:
-
Object
- Object
- K8s::Client
- Includes:
- MonitorMixin
- Defined in:
- lib/k8s/client.rb,
lib/k8s/client/version.rb
Overview
Top-level client wrapper. Uses a Transport instance to talk to the kube API. Offers access to APIClient and ResourceClient instances.
Constant Summary collapse
- VERSION =
Updated on releases using semver.
"0.8.2"
Instance Attribute Summary collapse
-
#transport ⇒ Object
readonly
Returns the value of attribute transport.
Class Method Summary collapse
-
.autoconfig(namespace: nil, **options) ⇒ K8s::Client
Attempts to create a K8s::Client instance automatically using environment variables, existing configuration files or in cluster configuration.
- .config(config, namespace: nil, **options) ⇒ K8s::Client
-
.in_cluster_config(namespace: nil, **options) ⇒ K8s::Client
An K8s::Client instance from in-cluster config within a kube pod, using the kubernetes service envs and serviceaccount secrets.
Instance Method Summary collapse
- #api(api_version = 'v1') ⇒ APIClient
-
#api_groups ⇒ Array<String>
Cached /apis preferred group apiVersions.
-
#api_groups! ⇒ Array<String>
Force-update /apis cache.
- #apis(api_versions = nil, prefetch_resources: false, skip_missing: false) ⇒ Array<APIClient>
- #client_for_resource(resource, namespace: nil) ⇒ K8s::ResourceClient
- #create_resource(resource) ⇒ K8s::Resource
- #delete_resource(resource, **options) ⇒ K8s::Resource
- #get_resource(resource) ⇒ K8s::Resource
-
#get_resources(resources) ⇒ Array<K8s::Resource, nil>
Returns nils for any resources that do not exist.
-
#initialize(transport, namespace: nil) ⇒ Client
constructor
A new instance of Client.
-
#list_resources(resources = nil, **options) ⇒ Array<K8s::Resource>
Pipeline list requests for multiple resource types.
- #patch_resource(resource, attrs) ⇒ K8s::Client
- #resources(namespace: nil) ⇒ Array<K8s::ResourceClient>
- #update_resource(resource) ⇒ K8s::Resource
- #version ⇒ K8s::API::Version
Constructor Details
#initialize(transport, namespace: nil) ⇒ Client
Returns a new instance of Client.
91 92 93 94 95 96 97 |
# File 'lib/k8s/client.rb', line 91 def initialize(transport, namespace: nil) @transport = transport @namespace = namespace @api_clients = {} super() end |
Instance Attribute Details
#transport ⇒ Object (readonly)
Returns the value of attribute transport.
87 88 89 |
# File 'lib/k8s/client.rb', line 87 def transport @transport end |
Class Method Details
.autoconfig(namespace: nil, **options) ⇒ K8s::Client
Attempts to create a K8s::Client instance automatically using environment variables, existing configuration files or in cluster configuration.
Look-up order:
- KUBE_TOKEN, KUBE_CA, KUBE_SERVER environment variables
- KUBECONFIG environment variable
- $HOME/.kube/config file
- In cluster configuration
Will raise when no means of configuration is available
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/k8s/client.rb', line 69 def self.autoconfig(namespace: nil, **) if ENV.values_at('KUBE_TOKEN', 'KUBE_CA', 'KUBE_SERVER').none? { |v| v.nil? || v.empty? } configuration = K8s::Config.build(server: ENV['KUBE_SERVER'], ca: ENV['KUBE_CA'], auth_token: [:auth_token] || ENV['KUBE_TOKEN']) elsif !ENV['KUBECONFIG'].to_s.empty? configuration = K8s::Config.from_kubeconfig_env(ENV['KUBECONFIG']) elsif File.exist?(File.join(Dir.home, '.kube', 'config')) configuration = K8s::Config.load_file(File.join(Dir.home, '.kube', 'config')) end if configuration config(configuration, namespace: namespace, **) else in_cluster_config(namespace: namespace, **) end end |
.config(config, namespace: nil, **options) ⇒ K8s::Client
37 38 39 40 41 42 |
# File 'lib/k8s/client.rb', line 37 def self.config(config, namespace: nil, **) new( Transport.config(config, **), namespace: namespace ) end |
.in_cluster_config(namespace: nil, **options) ⇒ K8s::Client
An K8s::Client instance from in-cluster config within a kube pod, using the kubernetes service envs and serviceaccount secrets
51 52 53 |
# File 'lib/k8s/client.rb', line 51 def self.in_cluster_config(namespace: nil, **) new(Transport.in_cluster_config(**), namespace: namespace) end |
Instance Method Details
#api(api_version = 'v1') ⇒ APIClient
107 108 109 |
# File 'lib/k8s/client.rb', line 107 def api(api_version = 'v1') @api_clients[api_version] ||= APIClient.new(@transport, api_version) end |
#api_groups ⇒ Array<String>
Cached /apis preferred group apiVersions
130 131 132 |
# File 'lib/k8s/client.rb', line 130 def api_groups @api_groups || api_groups! end |
#api_groups! ⇒ Array<String>
Force-update /apis cache. Required if creating new CRDs/apiservices.
115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/k8s/client.rb', line 115 def api_groups! synchronize do @api_groups = @transport.get( '/apis', response_class: K8s::API::MetaV1::APIGroupList ).groups.flat_map{ |api_group| api_group.versions.map(&:groupVersion) } @api_clients.clear end @api_groups end |
#apis(api_versions = nil, prefetch_resources: false, skip_missing: false) ⇒ Array<APIClient>
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/k8s/client.rb', line 138 def apis(api_versions = nil, prefetch_resources: false, skip_missing: false) api_versions ||= ['v1'] + api_groups if prefetch_resources # api groups that are missing their api_resources api_paths = api_versions .uniq .reject{ |api_version| api(api_version).api_resources? } .map{ |api_version| APIClient.path(api_version) } # load into APIClient.api_resources= begin @transport.gets(*api_paths, response_class: K8s::API::MetaV1::APIResourceList, skip_missing: skip_missing).each do |api_resource_list| api(api_resource_list.groupVersion).api_resources = api_resource_list.resources if api_resource_list end rescue K8s::Error::NotFound, K8s::Error::ServiceUnavailable # rubocop:disable Lint/HandleExceptions # kubernetes api is in unstable state # because this is only performance optimization, better to skip prefetch and move on end end api_versions.map{ |api_version| api(api_version) } end |
#client_for_resource(resource, namespace: nil) ⇒ K8s::ResourceClient
201 202 203 |
# File 'lib/k8s/client.rb', line 201 def client_for_resource(resource, namespace: nil) api(resource.apiVersion).client_for_resource(resource, namespace: namespace) end |
#create_resource(resource) ⇒ K8s::Resource
207 208 209 |
# File 'lib/k8s/client.rb', line 207 def create_resource(resource) client_for_resource(resource).create_resource(resource) end |
#delete_resource(resource, **options) ⇒ K8s::Resource
255 256 257 |
# File 'lib/k8s/client.rb', line 255 def delete_resource(resource, **) client_for_resource(resource).delete_resource(resource, **) end |
#get_resource(resource) ⇒ K8s::Resource
213 214 215 |
# File 'lib/k8s/client.rb', line 213 def get_resource(resource) client_for_resource(resource).get_resource(resource) end |
#get_resources(resources) ⇒ Array<K8s::Resource, nil>
Returns nils for any resources that do not exist. This includes custom resources that were not yet defined.
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/k8s/client.rb', line 222 def get_resources(resources) # prefetch api resources, skip missing APIs resource_apis = apis(resources.map(&:apiVersion), prefetch_resources: true, skip_missing: true) # map each resource to excon request options, or nil if resource is not (yet) defined requests = resources.zip(resource_apis).map{ |resource, api_client| next nil unless api_client.api_resources? resource_client = api_client.client_for_resource(resource) { method: 'GET', path: resource_client.path(resource..name, namespace: resource..namespace), response_class: resource_client.resource_class } } # map non-nil requests to response objects, or nil for nil request options Util.compact_map(requests) { |reqs| @transport.requests(*reqs, skip_missing: true) } end |
#list_resources(resources = nil, **options) ⇒ Array<K8s::Resource>
Pipeline list requests for multiple resource types.
Returns flattened array with mixed resource kinds.
181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/k8s/client.rb', line 181 def list_resources(resources = nil, **) cached_clients = @api_clients.size.positive? resources ||= self.resources.select(&:list?) begin ResourceClient.list(resources, @transport, **) rescue K8s::Error::NotFound raise unless cached_clients cached_clients = false api_groups! retry end end |
#patch_resource(resource, attrs) ⇒ K8s::Client
262 263 264 |
# File 'lib/k8s/client.rb', line 262 def patch_resource(resource, attrs) client_for_resource(resource).json_patch(resource..name, attrs) end |
#resources(namespace: nil) ⇒ Array<K8s::ResourceClient>
164 165 166 167 168 169 170 171 172 |
# File 'lib/k8s/client.rb', line 164 def resources(namespace: nil) apis(prefetch_resources: true).map { |api| begin api.resources(namespace: namespace) rescue K8s::Error::ServiceUnavailable, K8s::Error::NotFound [] end }.flatten end |
#update_resource(resource) ⇒ K8s::Resource
247 248 249 |
# File 'lib/k8s/client.rb', line 247 def update_resource(resource) client_for_resource(resource).update_resource(resource) end |
#version ⇒ K8s::API::Version
101 102 103 |
# File 'lib/k8s/client.rb', line 101 def version @version ||= @transport.version end |