k8s-ruby 0.10.5 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.relaxed.yml +23 -2
- data/.rubocop.yml +1 -1
- data/Dockerfile +6 -2
- data/README.md +17 -4
- data/docker-compose.yaml +27 -10
- data/k8s-ruby.gemspec +15 -13
- data/lib/k8s/api/metav1/api_resource.rb +2 -2
- data/lib/k8s/api/metav1/object.rb +2 -2
- data/lib/k8s/api.rb +1 -1
- data/lib/k8s/client.rb +1 -1
- data/lib/k8s/config.rb +6 -6
- data/lib/k8s/resource.rb +6 -9
- data/lib/k8s/ruby/version.rb +1 -1
- data/lib/k8s/stack.rb +4 -3
- data/lib/k8s/transport.rb +18 -11
- metadata +53 -23
- data/bin/k8s-client +0 -337
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 462575bda9c48588eb7d9d9d1ffda32c973ebdbf0b3d9113a7b8a2fdd94b781f
|
4
|
+
data.tar.gz: 2a593329f6040478517bc2895d1cf4929a19f728fd97ceb696e538dfb0de161e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ca53f957316cfc8b8fa38988e5637e85e110c8772601c6ad591a711486393d7ed530bfd86b6840bd8156bab9bf4299f5547963e825a5b1ee4c5835d95d8c0ae
|
7
|
+
data.tar.gz: b5ad610fadaa524f603e90b5c027bd6f17dc9005dc70785467a5ef50e59ae73aebf4c1962f0202f8221b070927c480286725baab366cfa888d7b1a9a76036b39
|
data/.gitignore
CHANGED
data/.rubocop.relaxed.yml
CHANGED
@@ -152,7 +152,7 @@ Metrics/ModuleLength:
|
|
152
152
|
Metrics/CyclomaticComplexity:
|
153
153
|
Enabled: false
|
154
154
|
|
155
|
-
|
155
|
+
Layout/LineLength:
|
156
156
|
Enabled: false
|
157
157
|
|
158
158
|
Metrics/MethodLength:
|
@@ -167,10 +167,31 @@ Metrics/PerceivedComplexity:
|
|
167
167
|
Naming/VariableName: # disabled because camelCased params are used in kube api/yamls
|
168
168
|
Enabled: false
|
169
169
|
|
170
|
-
Naming/
|
170
|
+
Naming/MethodParameterName: # disabled because camelCased params are used in kube api/yamls
|
171
171
|
Enabled: false
|
172
172
|
|
173
173
|
Naming/FileName:
|
174
174
|
Enabled: true
|
175
175
|
Exclude:
|
176
176
|
- lib/k8s-ruby.rb # ignored because gem name is k8s-ruby, so 'require k8s-ruby' and gem 'k8s-ruby' in Gemfile work
|
177
|
+
|
178
|
+
Layout/SpaceAroundMethodCallOperator:
|
179
|
+
Enabled: true
|
180
|
+
|
181
|
+
Lint/RaiseException:
|
182
|
+
Enabled: true
|
183
|
+
|
184
|
+
Lint/StructNewOverride:
|
185
|
+
Enabled: true
|
186
|
+
|
187
|
+
Style/ExponentialNotation:
|
188
|
+
Enabled: true
|
189
|
+
|
190
|
+
Style/HashEachMethods:
|
191
|
+
Enabled: true
|
192
|
+
|
193
|
+
Style/HashTransformKeys:
|
194
|
+
Enabled: true
|
195
|
+
|
196
|
+
Style/HashTransformValues:
|
197
|
+
Enabled: true
|
data/.rubocop.yml
CHANGED
data/Dockerfile
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
|
1
|
+
ARG BASE_IMAGE=ruby:2.7
|
2
|
+
FROM ${BASE_IMAGE}
|
2
3
|
|
3
4
|
WORKDIR /app
|
4
5
|
|
5
6
|
COPY Gemfile *.gemspec ./
|
6
|
-
COPY lib/k8s/
|
7
|
+
COPY lib/k8s/ruby/version.rb ./lib/k8s/ruby/
|
8
|
+
|
9
|
+
RUN gem install bundler:2.3.5
|
7
10
|
RUN bundle install
|
11
|
+
RUN bundle update --bundler
|
8
12
|
|
9
13
|
COPY . .
|
10
14
|
|
data/README.md
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
# K8s::Client provided by k8s-ruby
|
2
2
|
|
3
|
-
Ruby client library for the Kubernetes (1.9+) API
|
3
|
+
Ruby client library for the Kubernetes (1.9+) API.
|
4
|
+
|
5
|
+
The `k8s-ruby` project is a fork of
|
6
|
+
[kontena/k8s-client](https://github.com/kontena/k8s-client).
|
7
|
+
|
8
|
+
Unfortunately the company
|
9
|
+
[Kontena.io went bankcrupt](https://blog.kontena.io/farewell/) at
|
10
|
+
the end of the year 2019. They had created many wonderful Ruby projects which we
|
11
|
+
are grateful.
|
12
|
+
|
13
|
+
The `k8s-ruby` library is a community effort to keep `k8s-client`
|
14
|
+
maintained without any dependencies to the former Kontena.io organization.
|
15
|
+
The library was renamed in order to publish it to Rubygems without conflicting
|
16
|
+
with `k8s-client`.
|
4
17
|
|
5
18
|
## Highlights
|
6
19
|
|
@@ -162,7 +175,7 @@ pods = client.api('v1').resource('pods', namespace: 'default').delete_collection
|
|
162
175
|
|
163
176
|
#### Programmatically defined resources
|
164
177
|
```ruby
|
165
|
-
service = K8s::Resource.new(
|
178
|
+
service = K8s::Resource.new({
|
166
179
|
apiVersion: 'v1',
|
167
180
|
kind: 'Service',
|
168
181
|
metadata: {
|
@@ -176,7 +189,7 @@ service = K8s::Resource.new(
|
|
176
189
|
],
|
177
190
|
selector: {'app' => 'test'},
|
178
191
|
},
|
179
|
-
)
|
192
|
+
})
|
180
193
|
|
181
194
|
logger.info "Create service=#{service.metadata.name} in namespace=#{service.metadata.namespace}"
|
182
195
|
|
@@ -211,4 +224,4 @@ end
|
|
211
224
|
|
212
225
|
## Contributing
|
213
226
|
|
214
|
-
Bug reports and pull requests are welcome on GitHub at [
|
227
|
+
Bug reports and pull requests are welcome on GitHub at [k8s-ruby/k8s-ruby](https://github.com/k8s-ruby/k8s-ruby).
|
data/docker-compose.yaml
CHANGED
@@ -1,10 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
services:
|
2
|
+
rspec-2.6:
|
3
|
+
build:
|
4
|
+
context: .
|
5
|
+
args:
|
6
|
+
BASE_IMAGE: ruby:2.6
|
7
|
+
volumes:
|
8
|
+
- .:/app
|
9
|
+
entrypoint: bundle exec rspec
|
10
|
+
|
11
|
+
rspec-2.7:
|
12
|
+
build:
|
13
|
+
context: .
|
14
|
+
args:
|
15
|
+
BASE_IMAGE: ruby:2.7
|
16
|
+
volumes:
|
17
|
+
- .:/app
|
18
|
+
entrypoint: bundle exec rspec
|
19
|
+
|
20
|
+
rspec-3.0:
|
21
|
+
build:
|
22
|
+
context: .
|
23
|
+
args:
|
24
|
+
BASE_IMAGE: ruby:3.0
|
25
|
+
volumes:
|
26
|
+
- .:/app
|
27
|
+
entrypoint: bundle exec rspec
|
data/k8s-ruby.gemspec
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
lib = File.expand_path("
|
2
|
+
lib = File.expand_path("lib", __dir__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require "k8s/ruby/version"
|
5
5
|
|
@@ -11,30 +11,32 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.license = "Apache-2.0"
|
12
12
|
|
13
13
|
spec.summary = "Kubernetes client library for Ruby"
|
14
|
-
spec.homepage = "https://github.com/
|
14
|
+
spec.homepage = "https://github.com/k8s-ruby/k8s-ruby"
|
15
15
|
|
16
16
|
# Specify which files should be added to the gem when it is released.
|
17
17
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
-
spec.files = Dir.chdir(File.expand_path(
|
18
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
19
19
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
20
|
end
|
21
21
|
spec.bindir = "bin"
|
22
22
|
spec.executables = []
|
23
23
|
spec.require_paths = ["lib"]
|
24
|
-
spec.required_ruby_version =
|
24
|
+
spec.required_ruby_version = [">= 2.4", "< 3.1"]
|
25
25
|
|
26
26
|
spec.add_runtime_dependency "excon", "~> 0.71"
|
27
|
-
spec.add_runtime_dependency "dry-struct", "~>
|
28
|
-
spec.add_runtime_dependency "dry-types", "~>
|
29
|
-
spec.add_runtime_dependency "
|
30
|
-
spec.add_runtime_dependency
|
31
|
-
spec.add_runtime_dependency
|
32
|
-
spec.add_runtime_dependency
|
33
|
-
spec.add_runtime_dependency "
|
27
|
+
spec.add_runtime_dependency "dry-struct", "~> 1.3.0"
|
28
|
+
spec.add_runtime_dependency "dry-types", "~> 1.4.0"
|
29
|
+
spec.add_runtime_dependency "dry-configurable", "~> 0.13.0"
|
30
|
+
spec.add_runtime_dependency "recursive-open-struct", "~> 1.1.3"
|
31
|
+
spec.add_runtime_dependency "hashdiff", "~> 1.0.0"
|
32
|
+
spec.add_runtime_dependency "jsonpath", "~> 0.9.5"
|
33
|
+
spec.add_runtime_dependency "yajl-ruby", "~> 1.4.0"
|
34
|
+
spec.add_runtime_dependency "yaml-safe_load_stream2", "~> 0.1.1"
|
34
35
|
|
35
36
|
spec.add_development_dependency "bundler", ">= 1.17", "< 3.0"
|
36
|
-
spec.add_development_dependency "rake", "
|
37
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
37
38
|
spec.add_development_dependency "rspec", "~> 3.7"
|
38
39
|
spec.add_development_dependency "webmock", "~> 3.6.2"
|
39
|
-
spec.add_development_dependency "rubocop", "~> 0.
|
40
|
+
spec.add_development_dependency "rubocop", "~> 0.82"
|
41
|
+
spec.add_development_dependency "byebug", "~> 11.1"
|
40
42
|
end
|
@@ -12,8 +12,8 @@ module K8s
|
|
12
12
|
attribute :version, Types::Strict::String.optional.default(nil)
|
13
13
|
attribute :kind, Types::Strict::String
|
14
14
|
attribute :verbs, Types::Strict::Array.of(Types::Strict::String)
|
15
|
-
attribute :shortNames, Types::Strict::Array.of(Types::Strict::String).optional.default(proc { [] })
|
16
|
-
attribute :categories, Types::Strict::Array.of(Types::Strict::String).optional.default(proc { [] })
|
15
|
+
attribute :shortNames, Types::Strict::Array.of(Types::Strict::String).optional.default(proc { [] }, shared: true)
|
16
|
+
attribute :categories, Types::Strict::Array.of(Types::Strict::String).optional.default(proc { [] }, shared: true)
|
17
17
|
end
|
18
18
|
|
19
19
|
# @see https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#APIResourceList
|
@@ -38,9 +38,9 @@ module K8s
|
|
38
38
|
attribute :deletionGracePeriodSeconds, Types::Strict::Integer.optional.default(nil)
|
39
39
|
attribute :labels, Types::Strict::Hash.map(Types::Strict::String, Types::Strict::String).optional.default(nil)
|
40
40
|
attribute :annotations, Types::Strict::Hash.map(Types::Strict::String, Types::Strict::String).optional.default(nil)
|
41
|
-
attribute :ownerReferences, Types::Strict::Array.of(OwnerReference).optional.default([])
|
41
|
+
attribute :ownerReferences, Types::Strict::Array.of(OwnerReference).optional.default([], shared: true)
|
42
42
|
attribute :initializers, Initializers.optional.default(nil)
|
43
|
-
attribute :finalizers, Types::Strict::Array.of(Types::Strict::String).optional.default([])
|
43
|
+
attribute :finalizers, Types::Strict::Array.of(Types::Strict::String).optional.default([], shared: true)
|
44
44
|
attribute :clusterName, Types::Strict::String.optional.default(nil)
|
45
45
|
end
|
46
46
|
|
data/lib/k8s/api.rb
CHANGED
data/lib/k8s/client.rb
CHANGED
@@ -167,7 +167,7 @@ module K8s
|
|
167
167
|
@transport.gets(*api_paths, response_class: K8s::API::MetaV1::APIResourceList, skip_missing: skip_missing).each do |api_resource_list|
|
168
168
|
api(api_resource_list.groupVersion).api_resources = api_resource_list.resources if api_resource_list
|
169
169
|
end
|
170
|
-
rescue K8s::Error::NotFound, K8s::Error::ServiceUnavailable
|
170
|
+
rescue K8s::Error::NotFound, K8s::Error::ServiceUnavailable
|
171
171
|
# kubernetes api is in unstable state
|
172
172
|
# because this is only performance optimization, better to skip prefetch and move on
|
173
173
|
end
|
data/lib/k8s/config.rb
CHANGED
@@ -25,7 +25,7 @@ module K8s
|
|
25
25
|
class Config < ConfigStruct
|
26
26
|
# Common dry-types for config
|
27
27
|
class Types
|
28
|
-
include Dry::Types
|
28
|
+
include Dry::Types()
|
29
29
|
end
|
30
30
|
|
31
31
|
# structured cluster
|
@@ -99,12 +99,12 @@ module K8s
|
|
99
99
|
|
100
100
|
attribute :kind, Types::Strict::String.optional.default(nil)
|
101
101
|
attribute :apiVersion, Types::Strict::String.optional.default(nil)
|
102
|
-
attribute :preferences, Types::Strict::Hash.optional.default(proc { {} })
|
103
|
-
attribute :clusters, Types::Strict::Array.of(NamedCluster).optional.default(proc { [] })
|
104
|
-
attribute :users, Types::Strict::Array.of(NamedUser).optional.default(proc { [] })
|
105
|
-
attribute :contexts, Types::Strict::Array.of(NamedContext).optional.default(proc { [] })
|
102
|
+
attribute :preferences, Types::Strict::Hash.optional.default(proc { {} }, shared: true)
|
103
|
+
attribute :clusters, Types::Strict::Array.of(NamedCluster).optional.default(proc { [] }, shared: true)
|
104
|
+
attribute :users, Types::Strict::Array.of(NamedUser).optional.default(proc { [] }, shared: true)
|
105
|
+
attribute :contexts, Types::Strict::Array.of(NamedContext).optional.default(proc { [] }, shared: true)
|
106
106
|
attribute :current_context, Types::Strict::String.optional.default(nil)
|
107
|
-
attribute :extensions, Types::Strict::Array.optional.default(proc { [] })
|
107
|
+
attribute :extensions, Types::Strict::Array.optional.default(proc { [] }, shared: true)
|
108
108
|
|
109
109
|
# Loads a configuration from a YAML file
|
110
110
|
#
|
data/lib/k8s/resource.rb
CHANGED
@@ -40,19 +40,16 @@ module K8s
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# @param hash [Hash]
|
43
|
-
# @param recurse_over_arrays [Boolean]
|
44
43
|
# @param options [Hash] see RecursiveOpenStruct#initialize
|
45
|
-
def initialize(hash,
|
46
|
-
|
47
|
-
|
48
|
-
**options
|
49
|
-
)
|
44
|
+
def initialize(hash, options = {})
|
45
|
+
options_with_defaults = { recurse_over_arrays: true }.merge(options)
|
46
|
+
super(hash, options_with_defaults)
|
50
47
|
end
|
51
48
|
|
52
|
-
# @param
|
49
|
+
# @param args [Array] see Hash#to_json
|
53
50
|
# @return [String]
|
54
|
-
def to_json(**options)
|
55
|
-
to_hash.to_json(**options)
|
51
|
+
def to_json(*args, **options)
|
52
|
+
to_hash.to_json(*args, **options)
|
56
53
|
end
|
57
54
|
|
58
55
|
# @param other [K8s::Resource]
|
data/lib/k8s/ruby/version.rb
CHANGED
data/lib/k8s/stack.rb
CHANGED
@@ -94,7 +94,7 @@ module K8s
|
|
94
94
|
|
95
95
|
# @param client [K8s::Client]
|
96
96
|
# @return [Array<K8s::Resource>]
|
97
|
-
def apply(client, prune: true)
|
97
|
+
def apply(client, prune: true, patch: true)
|
98
98
|
server_resources = client.get_resources(resources)
|
99
99
|
|
100
100
|
resources.zip(server_resources).map do |resource, server_resource|
|
@@ -104,10 +104,11 @@ module K8s
|
|
104
104
|
elsif server_resource.metadata.annotations&.dig(@checksum_annotation) != resource.checksum
|
105
105
|
logger.info "Update resource #{resource.apiVersion}:#{resource.kind}/#{resource.metadata.name} in namespace #{resource.metadata.namespace} with checksum=#{resource.checksum}"
|
106
106
|
r = prepare_resource(resource)
|
107
|
-
if server_resource.can_patch?(@last_config_annotation)
|
107
|
+
if patch && server_resource.can_patch?(@last_config_annotation)
|
108
|
+
# Patch: apply changes to specific fields only
|
108
109
|
keep_resource! client.patch_resource(server_resource, server_resource.merge_patch_ops(r.to_hash, @last_config_annotation))
|
109
110
|
else
|
110
|
-
#
|
111
|
+
# Replace (PUT): replace complete object
|
111
112
|
keep_resource! client.update_resource(server_resource.merge(prepare_resource(resource)))
|
112
113
|
end
|
113
114
|
else
|
data/lib/k8s/transport.rb
CHANGED
@@ -94,12 +94,16 @@ module K8s
|
|
94
94
|
# @param auth_provider [K8s::Config::UserAuthProvider]
|
95
95
|
# @return [String]
|
96
96
|
def self.token_from_auth_provider(auth_provider)
|
97
|
-
|
98
|
-
|
99
|
-
json_path = JsonPath.new(auth_provider['token-key'][1...-1])
|
100
|
-
json_path.first(auth_data)
|
97
|
+
if auth_provider['id-token']
|
98
|
+
json_path = auth_provider['id-token']
|
101
99
|
else
|
102
|
-
auth_data
|
100
|
+
auth_data = `#{auth_provider['cmd-path']} #{auth_provider['cmd-args']}`.strip
|
101
|
+
if auth_provider['token-key']
|
102
|
+
json_path = JsonPath.new(auth_provider['token-key'][1...-1])
|
103
|
+
json_path.first(auth_data)
|
104
|
+
else
|
105
|
+
auth_data
|
106
|
+
end
|
103
107
|
end
|
104
108
|
end
|
105
109
|
|
@@ -133,8 +137,14 @@ module K8s
|
|
133
137
|
port = ENV['KUBERNETES_SERVICE_PORT_HTTPS'].to_s
|
134
138
|
raise(K8s::Error::Configuration, "in_cluster_config failed: KUBERNETES_SERVICE_PORT_HTTPS environment not set") if port.empty?
|
135
139
|
|
140
|
+
host_with_ipv6_brackets_if_needed = if host.include? "::"
|
141
|
+
"[#{host}]"
|
142
|
+
else
|
143
|
+
host
|
144
|
+
end
|
145
|
+
|
136
146
|
new(
|
137
|
-
"https://#{
|
147
|
+
"https://#{host_with_ipv6_brackets_if_needed}:#{port}",
|
138
148
|
ssl_verify_peer: options.key?(:ssl_verify_peer) ? options.delete(:ssl_verify_peer) : true,
|
139
149
|
ssl_ca_file: options.delete(:ssl_ca_file) || File.join((ENV['TELEPRESENCE_ROOT'] || '/'), 'var/run/secrets/kubernetes.io/serviceaccount/ca.crt'),
|
140
150
|
auth_token: options.delete(:auth_token) || File.read(File.join((ENV['TELEPRESENCE_ROOT'] || '/'), 'var/run/secrets/kubernetes.io/serviceaccount/token')),
|
@@ -360,11 +370,8 @@ module K8s
|
|
360
370
|
# @param options [Hash] @see #request
|
361
371
|
# @return [Array<response_class, Hash, NilClass>]
|
362
372
|
def get(*path, **options)
|
363
|
-
|
364
|
-
|
365
|
-
path: self.path(*path),
|
366
|
-
**options
|
367
|
-
)
|
373
|
+
options = options.merge({ method: 'GET', path: self.path(*path) })
|
374
|
+
request(**options)
|
368
375
|
end
|
369
376
|
|
370
377
|
# @param paths [Array<String>]
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: k8s-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- rdx.net
|
8
8
|
- Kontena, Inc.
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-01-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: excon
|
@@ -31,16 +31,30 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
34
|
+
version: 1.3.0
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
41
|
+
version: 1.3.0
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: dry-types
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 1.4.0
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.4.0
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: dry-configurable
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
45
59
|
requirements:
|
46
60
|
- - "~>"
|
@@ -59,14 +73,14 @@ dependencies:
|
|
59
73
|
requirements:
|
60
74
|
- - "~>"
|
61
75
|
- !ruby/object:Gem::Version
|
62
|
-
version: 1.1.
|
76
|
+
version: 1.1.3
|
63
77
|
type: :runtime
|
64
78
|
prerelease: false
|
65
79
|
version_requirements: !ruby/object:Gem::Requirement
|
66
80
|
requirements:
|
67
81
|
- - "~>"
|
68
82
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.1.
|
83
|
+
version: 1.1.3
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
85
|
name: hashdiff
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -110,19 +124,19 @@ dependencies:
|
|
110
124
|
- !ruby/object:Gem::Version
|
111
125
|
version: 1.4.0
|
112
126
|
- !ruby/object:Gem::Dependency
|
113
|
-
name: yaml-
|
127
|
+
name: yaml-safe_load_stream2
|
114
128
|
requirement: !ruby/object:Gem::Requirement
|
115
129
|
requirements:
|
116
130
|
- - "~>"
|
117
131
|
- !ruby/object:Gem::Version
|
118
|
-
version:
|
132
|
+
version: 0.1.1
|
119
133
|
type: :runtime
|
120
134
|
prerelease: false
|
121
135
|
version_requirements: !ruby/object:Gem::Requirement
|
122
136
|
requirements:
|
123
137
|
- - "~>"
|
124
138
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
139
|
+
version: 0.1.1
|
126
140
|
- !ruby/object:Gem::Dependency
|
127
141
|
name: bundler
|
128
142
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,16 +161,16 @@ dependencies:
|
|
147
161
|
name: rake
|
148
162
|
requirement: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
|
-
- - "
|
164
|
+
- - ">="
|
151
165
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
166
|
+
version: 12.3.3
|
153
167
|
type: :development
|
154
168
|
prerelease: false
|
155
169
|
version_requirements: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
|
-
- - "
|
171
|
+
- - ">="
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version:
|
173
|
+
version: 12.3.3
|
160
174
|
- !ruby/object:Gem::Dependency
|
161
175
|
name: rspec
|
162
176
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,15 +205,29 @@ dependencies:
|
|
191
205
|
requirements:
|
192
206
|
- - "~>"
|
193
207
|
- !ruby/object:Gem::Version
|
194
|
-
version: '0.
|
208
|
+
version: '0.82'
|
195
209
|
type: :development
|
196
210
|
prerelease: false
|
197
211
|
version_requirements: !ruby/object:Gem::Requirement
|
198
212
|
requirements:
|
199
213
|
- - "~>"
|
200
214
|
- !ruby/object:Gem::Version
|
201
|
-
version: '0.
|
202
|
-
|
215
|
+
version: '0.82'
|
216
|
+
- !ruby/object:Gem::Dependency
|
217
|
+
name: byebug
|
218
|
+
requirement: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '11.1'
|
223
|
+
type: :development
|
224
|
+
prerelease: false
|
225
|
+
version_requirements: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - "~>"
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '11.1'
|
230
|
+
description:
|
203
231
|
email:
|
204
232
|
- firstname.lastname@rdx.net
|
205
233
|
executables: []
|
@@ -215,7 +243,6 @@ files:
|
|
215
243
|
- LICENSE
|
216
244
|
- README.md
|
217
245
|
- Rakefile
|
218
|
-
- bin/k8s-client
|
219
246
|
- docker-compose.yaml
|
220
247
|
- k8s-ruby.gemspec
|
221
248
|
- lib/k8s-ruby.rb
|
@@ -239,27 +266,30 @@ files:
|
|
239
266
|
- lib/k8s/stack.rb
|
240
267
|
- lib/k8s/transport.rb
|
241
268
|
- lib/k8s/util.rb
|
242
|
-
homepage: https://github.com/
|
269
|
+
homepage: https://github.com/k8s-ruby/k8s-ruby
|
243
270
|
licenses:
|
244
271
|
- Apache-2.0
|
245
272
|
metadata: {}
|
246
|
-
post_install_message:
|
273
|
+
post_install_message:
|
247
274
|
rdoc_options: []
|
248
275
|
require_paths:
|
249
276
|
- lib
|
250
277
|
required_ruby_version: !ruby/object:Gem::Requirement
|
251
278
|
requirements:
|
252
|
-
- - "
|
279
|
+
- - ">="
|
253
280
|
- !ruby/object:Gem::Version
|
254
281
|
version: '2.4'
|
282
|
+
- - "<"
|
283
|
+
- !ruby/object:Gem::Version
|
284
|
+
version: '3.1'
|
255
285
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
256
286
|
requirements:
|
257
287
|
- - ">="
|
258
288
|
- !ruby/object:Gem::Version
|
259
289
|
version: '0'
|
260
290
|
requirements: []
|
261
|
-
rubygems_version: 3.
|
262
|
-
signing_key:
|
291
|
+
rubygems_version: 3.2.3
|
292
|
+
signing_key:
|
263
293
|
specification_version: 4
|
264
294
|
summary: Kubernetes client library for Ruby
|
265
295
|
test_files: []
|
data/bin/k8s-client
DELETED
@@ -1,337 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require 'optparse'
|
5
|
-
require 'uri'
|
6
|
-
require 'k8s-ruby'
|
7
|
-
|
8
|
-
Options = Struct.new(
|
9
|
-
:in_cluster_config,
|
10
|
-
:config,
|
11
|
-
:server,
|
12
|
-
:insecure_skip_tls_verify,
|
13
|
-
:prefetch_resources,
|
14
|
-
:list_resource_kinds,
|
15
|
-
:namespace,
|
16
|
-
:all_namespaces,
|
17
|
-
:label_selector,
|
18
|
-
:pipeline_list,
|
19
|
-
:list_resources,
|
20
|
-
:list_pods,
|
21
|
-
:update_node,
|
22
|
-
:node_unschedulable,
|
23
|
-
:delete_pod,
|
24
|
-
:delete_pods,
|
25
|
-
:create_service,
|
26
|
-
:service_type,
|
27
|
-
:service_port,
|
28
|
-
:resources,
|
29
|
-
:create_resources,
|
30
|
-
:update_resources,
|
31
|
-
:delete_resources,
|
32
|
-
:stack_name,
|
33
|
-
:stack,
|
34
|
-
:prune_stack,
|
35
|
-
:delete_stack,
|
36
|
-
:api,
|
37
|
-
:list_api_resources,
|
38
|
-
:patch_deployment,
|
39
|
-
:replicas,
|
40
|
-
:version
|
41
|
-
)
|
42
|
-
|
43
|
-
options = Options.new
|
44
|
-
options.create_resources = []
|
45
|
-
options.update_resources = []
|
46
|
-
options.delete_resources = []
|
47
|
-
|
48
|
-
logger = Logger.new(STDERR)
|
49
|
-
|
50
|
-
opt_parser = OptionParser.new do |parser|
|
51
|
-
parser.on('--debug-api') do
|
52
|
-
K8s::Logging.debug!
|
53
|
-
K8s::Transport.debug!
|
54
|
-
end
|
55
|
-
parser.on('--debug') do
|
56
|
-
K8s::Logging.debug!
|
57
|
-
K8s::Transport.verbose!
|
58
|
-
end
|
59
|
-
parser.on('--verbose') do
|
60
|
-
K8s::Logging.verbose!
|
61
|
-
K8s::Transport.quiet!
|
62
|
-
end
|
63
|
-
parser.on('--quiet') do
|
64
|
-
K8s::Logging.quiet!
|
65
|
-
K8s::Transport.quiet!
|
66
|
-
end
|
67
|
-
parser.on('--version') do
|
68
|
-
options.version = true
|
69
|
-
end
|
70
|
-
parser.on('--in-cluster-config') do
|
71
|
-
options.in_cluster_config = true
|
72
|
-
end
|
73
|
-
parser.on('--kubeconfig=PATH') do |path|
|
74
|
-
options.config = K8s::Config.load_file(path)
|
75
|
-
end
|
76
|
-
parser.on('--server=SERVER') do |server|
|
77
|
-
options.server = server
|
78
|
-
end
|
79
|
-
parser.on('--insecure-skip-tls-verify', TrueClass) do |bool|
|
80
|
-
options.insecure_skip_tls_verify = bool
|
81
|
-
end
|
82
|
-
parser.on('--prefetch-resources', TrueClass) do |bool|
|
83
|
-
options.prefetch_resources = bool
|
84
|
-
end
|
85
|
-
parser.on('--list-resource-kinds', TrueClass) do |_bool|
|
86
|
-
options.list_resource_kinds = true
|
87
|
-
end
|
88
|
-
parser.on('-n', '--namespace=NAMESPACE') do |namespace|
|
89
|
-
options.namespace = namespace
|
90
|
-
end
|
91
|
-
parser.on('--all-namespaces') do
|
92
|
-
options.all_namespaces = true
|
93
|
-
end
|
94
|
-
parser.on('-l', '--label-selector=LABEL=VALUE') do |selector|
|
95
|
-
options.label_selector = selector
|
96
|
-
end
|
97
|
-
parser.on('--pipeline-list') do
|
98
|
-
options.pipeline_list = true
|
99
|
-
end
|
100
|
-
parser.on('--list-resources') do
|
101
|
-
options.list_resources = true
|
102
|
-
end
|
103
|
-
parser.on('--list-pods') do
|
104
|
-
options.list_pods = true
|
105
|
-
end
|
106
|
-
parser.on('--update-node=NODE') do |node|
|
107
|
-
options.update_node = node
|
108
|
-
end
|
109
|
-
parser.on('--node-unschedulable=BOOL', TrueClass) do |bool|
|
110
|
-
options.node_unschedulable = bool
|
111
|
-
end
|
112
|
-
parser.on('--delete-pod=POD') do |pod|
|
113
|
-
options.delete_pod = pod
|
114
|
-
end
|
115
|
-
parser.on('--delete-pods') do
|
116
|
-
options.delete_pods = true
|
117
|
-
end
|
118
|
-
parser.on('--create-service=SERVICE') do |service|
|
119
|
-
options.create_service = service
|
120
|
-
end
|
121
|
-
parser.on('--service-type=SERVICE-TYPE') do |type|
|
122
|
-
options.service_type = type
|
123
|
-
end
|
124
|
-
parser.on('--service-port=PORT', Integer) do |port|
|
125
|
-
options.service_port = port
|
126
|
-
end
|
127
|
-
parser.on('--resource-file=path') do |path|
|
128
|
-
options.resources = K8s::Resource.from_files(path)
|
129
|
-
end
|
130
|
-
parser.on('--create') do
|
131
|
-
options.create_resources = options.resources
|
132
|
-
end
|
133
|
-
parser.on('--update') do
|
134
|
-
options.update_resources = options.resources
|
135
|
-
end
|
136
|
-
parser.on('--delete') do
|
137
|
-
options.delete_resources = options.resources
|
138
|
-
end
|
139
|
-
parser.on('--stack-name=NAME') do |name|
|
140
|
-
options.stack_name = name
|
141
|
-
end
|
142
|
-
parser.on('--stack=PATH') do |path|
|
143
|
-
options.stack = K8s::Stack.load(options.stack_name || File.basename(path, ".*"), path)
|
144
|
-
end
|
145
|
-
parser.on('--prune-stack', TrueClass) do |flag|
|
146
|
-
options.prune_stack = flag
|
147
|
-
end
|
148
|
-
parser.on('--delete-stack') do
|
149
|
-
options.delete_stack = options.stack
|
150
|
-
end
|
151
|
-
parser.on('--api=API') do |api|
|
152
|
-
options.api = api
|
153
|
-
end
|
154
|
-
parser.on('--list-api-resources') do
|
155
|
-
options.list_api_resources = options.api
|
156
|
-
end
|
157
|
-
parser.on('--patch-deployment=NAME') do |name|
|
158
|
-
options.patch_deployment = name
|
159
|
-
end
|
160
|
-
parser.on('--replicas=COUNT', Integer) do |count|
|
161
|
-
options.replicas = count
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
opt_parser.parse!
|
166
|
-
|
167
|
-
if options.config
|
168
|
-
overrides = {}
|
169
|
-
overrides[:ssl_verify_peer] = false if options.insecure_skip_tls_verify
|
170
|
-
|
171
|
-
client = K8s::Client.config(options.config,
|
172
|
-
server: options.server,
|
173
|
-
**overrides)
|
174
|
-
elsif options.in_cluster_config
|
175
|
-
client = K8s::Client.in_cluster_config
|
176
|
-
else
|
177
|
-
client = K8s.client(options.server,
|
178
|
-
ssl_verify_peer: !options.insecure_skip_tls_verify)
|
179
|
-
end
|
180
|
-
|
181
|
-
if options.version
|
182
|
-
logger.info client.version
|
183
|
-
else
|
184
|
-
logger.info "Kube server version: #{client.version.gitVersion}"
|
185
|
-
end
|
186
|
-
|
187
|
-
if options.prefetch_resources
|
188
|
-
client.apis(prefetch_resources: true)
|
189
|
-
end
|
190
|
-
|
191
|
-
if options.list_resource_kinds
|
192
|
-
client.resources.sort_by(&:kind).each do |resource_client|
|
193
|
-
next if resource_client.subresource?
|
194
|
-
|
195
|
-
puts "#{resource_client.kind} => #{resource_client.api_version} #{resource_client.name}"
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
namespace = if options.all_namespaces
|
200
|
-
nil # all
|
201
|
-
elsif options.namespace
|
202
|
-
options.namespace
|
203
|
-
elsif options.config && ns = options.config.context.namespace
|
204
|
-
ns
|
205
|
-
end
|
206
|
-
|
207
|
-
if options.list_api_resources
|
208
|
-
logger.info "List resource types for api=#{options.list_api_resources}..."
|
209
|
-
|
210
|
-
client.api(options.list_api_resources).resources do |api_resource|
|
211
|
-
logger.info "api=#{api_resource.api_version} resource=#{api_resource.resource} subresource=#{api_resource.subresource}"
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
if options.pipeline_list
|
216
|
-
objects = client.list_resources(namespace: namespace, labelSelector: options.label_selector)
|
217
|
-
objects.each do |object|
|
218
|
-
logger.info "api=#{object.apiVersion} kind=#{object.kind} namespace=#{object.metadata.namespace} name=#{object.metadata.name}"
|
219
|
-
end
|
220
|
-
elsif options.list_resources
|
221
|
-
client.apis(prefetch_resources: true).each do |api|
|
222
|
-
logger.info "api=#{api.api_version}"
|
223
|
-
|
224
|
-
resources = api.resources.select(&:list?)
|
225
|
-
|
226
|
-
resources.each do |resource|
|
227
|
-
logger.info "api=#{api.api_version} resource=#{resource.name}"
|
228
|
-
|
229
|
-
objects = resource.list(labelSelector: options.label_selector)
|
230
|
-
objects.each do |object|
|
231
|
-
logger.info "api=#{object.apiVersion} kind=#{object.kind} namespace=#{object.metadata.namespace} name=#{object.metadata.name}"
|
232
|
-
end
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
if options.list_pods
|
238
|
-
client.api('v1').resource('pods', namespace: namespace).list(labelSelector: options.label_selector).each do |pod|
|
239
|
-
puts "namespace=#{pod.metadata.namespace} pod: #{pod.metadata.name} node=#{pod.spec.nodeName}"
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
if options.update_node
|
244
|
-
node = client.api('v1').resource('nodes').get(options.update_node)
|
245
|
-
|
246
|
-
puts "Update node=#{node.metadata.name}..."
|
247
|
-
|
248
|
-
if !options.node_unschedulable.nil?
|
249
|
-
puts "Set node=#{node.metadata.name} unschedulable: #{node.spec.unschedulable} => #{options.node_unschedulable}"
|
250
|
-
|
251
|
-
node[:spec][:unschedulable] = options.node_unschedulable
|
252
|
-
end
|
253
|
-
|
254
|
-
client.api('v1').resource('nodes').update_resource(node)
|
255
|
-
end
|
256
|
-
|
257
|
-
if options.delete_pod
|
258
|
-
logger.info "Delete pod=#{options.delete_pod} in namespace=#{namespace}"
|
259
|
-
|
260
|
-
pod = client.api('v1').resource('pods', namespace: namespace).delete(options.delete_pod)
|
261
|
-
|
262
|
-
logger.debug { pod.metadata }
|
263
|
-
end
|
264
|
-
|
265
|
-
if options.delete_pods
|
266
|
-
logger.info "Delete pods with labelSelector=#{options.label_selector} in namespace=#{namespace}"
|
267
|
-
|
268
|
-
pods = client.api('v1').resource('pods', namespace: namespace).delete_collection(labelSelector: options.label_selector)
|
269
|
-
|
270
|
-
pods.each do |pod_instance|
|
271
|
-
logger.info "Deleted pod=#{pod_instance.metadata.name} in namespace=#{pod_instance.metadata.namespace} on node=#{pod_instance.spec.nodeName}"
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
if options.create_service
|
276
|
-
service = K8s::Resource.new(
|
277
|
-
apiVersion: 'v1',
|
278
|
-
kind: 'Service',
|
279
|
-
metadata: {
|
280
|
-
namespace: namespace,
|
281
|
-
name: options.create_service
|
282
|
-
},
|
283
|
-
spec: {
|
284
|
-
type: options.service_type,
|
285
|
-
ports: [
|
286
|
-
{ port: options.service_port }
|
287
|
-
],
|
288
|
-
selector: Hash[options.label_selector.split('=', 2)]
|
289
|
-
}
|
290
|
-
)
|
291
|
-
|
292
|
-
logger.info "Create service=#{service.metadata.name} in namespace=#{service.metadata.namespace}"
|
293
|
-
|
294
|
-
service = client.api('v1').resource('services').create_resource(service)
|
295
|
-
|
296
|
-
logger.debug { service }
|
297
|
-
end
|
298
|
-
|
299
|
-
options.create_resources.each do |resource|
|
300
|
-
resource = client.create_resource(resource)
|
301
|
-
|
302
|
-
logger.info "Created #{resource.apiVersion} resource #{resource.kind} #{resource.metadata.name} in namespace #{resource.metadata.namespace}:\n#{JSON.pretty_generate(resource)}"
|
303
|
-
end
|
304
|
-
|
305
|
-
options.update_resources.each do |resource|
|
306
|
-
resource = client.update_resource(resource)
|
307
|
-
|
308
|
-
logger.info "Updated #{resource.apiVersion} resource #{resource.kind} #{resource.metadata.name} in namespace #{resource.metadata.namespace}:\n#{JSON.pretty_generate(resource)}"
|
309
|
-
end
|
310
|
-
|
311
|
-
options.delete_resources.each do |resource|
|
312
|
-
begin
|
313
|
-
resource = client.delete_resource(resource)
|
314
|
-
|
315
|
-
logger.info "Deleted #{resource.apiVersion} resource #{resource.kind} #{resource.metadata.name} in namespace #{resource.metadata.namespace}:\n#{JSON.pretty_generate(resource)}"
|
316
|
-
rescue K8s::Error::NotFound => e
|
317
|
-
logger.info "Skip #{resource.apiVersion} resource #{resource.kind} #{resource.metadata.name} in namespace #{resource.metadata.namespace}: #{e}"
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
if stack = options.delete_stack
|
322
|
-
logger.info "Delete stack #{stack.name}..."
|
323
|
-
|
324
|
-
stack.delete(client)
|
325
|
-
|
326
|
-
elsif options.stack
|
327
|
-
logger.info "Apply stack #{options.stack.name}..."
|
328
|
-
|
329
|
-
options.stack.apply(client, prune: options.prune_stack)
|
330
|
-
end
|
331
|
-
|
332
|
-
if name = options.patch_deployment
|
333
|
-
client.api('apps/v1').resource('deployments', namespace: namespace).merge_patch(
|
334
|
-
name,
|
335
|
-
spec: { replicas: options.replicas }
|
336
|
-
)
|
337
|
-
end
|