Skip to content

Commit cf982c3

Browse files
authored
Updates to testsuite according to cnf-testsuite/kubectl_client#17 (#31)
* Update kubectl_client version to v1.0.8 Signed-off-by: Rafal Lal <rafal.lal@tietoevry.com>
1 parent ebfc47a commit cf982c3

File tree

4 files changed

+96
-82
lines changed

4 files changed

+96
-82
lines changed

cluster_tools.cr

Lines changed: 87 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ module ClusterTools
3535
end
3636

3737
def self.ensure_namespace_exists!
38-
namespaces = KubectlClient::Get.namespaces()
38+
namespaces = KubectlClient::Get.resource("namespaces")
3939
namespace_array = namespaces["items"].as_a
4040

4141
Log.debug { "ClusterTools ensure_namespace_exists namespace_array: #{namespace_array}" }
@@ -68,72 +68,59 @@ module ClusterTools
6868

6969
KubectlClient::Delete.file("cluster_tools.yml", namespace: self.namespace!)
7070
#todo make this work with cluster-tools-host-namespace
71-
KubectlClient::Get.resource_wait_for_uninstall("Daemonset", "cluster-tools", namespace: self.namespace!)
71+
KubectlClient::Wait.resource_wait_for_uninstall("Daemonset", "cluster-tools", namespace: self.namespace!)
7272
end
7373

74-
def self.exec(cli : String)
74+
def self.exec(cli : String) : KubectlClient::CMDResult
7575
# todo change to get all pods, schedulable nodes is slow
7676
pods = KubectlClient::Get.pods_by_nodes(KubectlClient::Get.schedulable_nodes_list)
77-
pods = KubectlClient::Get.pods_by_label(pods, "name", "cluster-tools")
77+
pods = KubectlClient::Get.pods_by_labels(pods, {"name" => "cluster-tools"})
7878

7979
cluster_tools_pod_name = pods[0].dig?("metadata", "name") if pods[0]?
8080
Log.info { "cluster_tools_pod_name: #{cluster_tools_pod_name}"}
8181

82-
cmd = "#{cluster_tools_pod_name} -- #{cli}"
83-
KubectlClient.exec(cmd, namespace: self.namespace!)
82+
KubectlClient::Utils.exec(cluster_tools_pod_name, cli, namespace: self.namespace!)
8483
end
8584

85+
def self.exec_by_node(cli : String, node_name : String) : KubectlClient::CMDResult?
86+
Log.info { "exec_by_node: Called with String" }
8687

87-
def self.exec_by_node_construct_cli(cli : String, node : JSON::Any)
88-
pods = KubectlClient::Get.pods_by_nodes([node])
89-
# pods = KubectlClient::Get.pods_by_label(pods, "name", "cluster-tools-k8s")
90-
pods = KubectlClient::Get.pods_by_label(pods, "name", "cluster-tools")
91-
92-
cluster_tools_pod_name = pods[0].dig?("metadata", "name") if pods[0]?
93-
Log.debug { "cluster_tools_pod_name: #{cluster_tools_pod_name}"}
88+
nodes = KubectlClient::Get.resource("nodes")["items"].as_a
9489

95-
full_cli = "#{cluster_tools_pod_name} -- #{cli}"
96-
Log.debug { "ClusterTools exec full cli: #{full_cli}" }
97-
return full_cli
98-
end
90+
node : JSON::Any | Nil
91+
node = nodes.find{ |n| n.dig?("metadata", "name") == node_name }
9992

100-
def self.exec_by_node(cli : String, nodeName : String)
101-
Log.info { "exec_by_node: Called with String" }
93+
return self.exec_by_node(cli, node) if node
10294

103-
nodes = KubectlClient::Get.nodes["items"].as_a
95+
Log.error { "exec_by_node failed, '#{node_name}' not matched to any existing nodes" }
96+
nil
97+
end
98+
99+
private def self.get_cluster_tools_pod_on_node(node : JSON::Any)
100+
pods = KubectlClient::Get.pods_by_nodes([node])
101+
pods = KubectlClient::Get.pods_by_labels(pods, {"name" => "cluster-tools"})
104102

105-
node : JSON::Any | Nil
106-
node = nodes.find{ |n| n.dig?("metadata", "name") == nodeName }
103+
cluster_tools_pod_name = pods[0].dig?("metadata", "name") if pods[0]?
104+
Log.debug { "cluster_tools_pod_name: #{cluster_tools_pod_name}"}
107105

108-
if node
109-
self.exec_by_node(cli, node)
110-
else
111-
""
112-
end
106+
cluster_tools_pod_name
113107
end
114-
115108

116-
def self.exec_by_node(cli : String, node : JSON::Any)
109+
def self.exec_by_node(cli : String, node : JSON::Any) : KubectlClient::CMDResult
117110
Log.info { "exec_by_node: Called with JSON" }
118-
# todo change to get all pods, schedulable nodes is slow
119-
120-
# pods_by_nodes internally use KubectlClient::Get.pods which uses --all-namespaces option.
121-
# So they do not have to be passed the namespace to perform operations.
122-
full_cli = exec_by_node_construct_cli(cli, node)
123-
exec = KubectlClient.exec(full_cli, namespace: self.namespace)
111+
# 'pods_by_nodes' fetches pods from all namespaces so they
112+
# do not have to be passed the namespace to perform operations.
113+
pod_name = get_cluster_tools_pod_on_node(node)
114+
exec = KubectlClient::Utils.exec(pod_name, cli, namespace: self.namespace)
124115
Log.debug { "ClusterTools exec: #{exec}" }
125116
exec
126117
end
127118

128-
def self.exec_by_node_bg(cli : String, node : JSON::Any)
129-
# todo change to get all pods, schedulable nodes is slow
130-
131-
# pods_by_nodes internally use KubectlClient::Get.pods which uses --all-namespaces option.
132-
# So they do not have to be passed the namespace to perform operations.
133-
134-
full_cli = exec_by_node_construct_cli(cli, node)
135-
Log.debug { "ClusterTools exec full cli: #{full_cli}" }
136-
exec = KubectlClient.exec_bg(full_cli, namespace: self.namespace)
119+
def self.exec_by_node_bg(cli : String, node : JSON::Any) : KubectlClient::BackgroundCMDResult
120+
# 'pods_by_nodes' fetches pods from all namespaces so they
121+
# do not have to be passed the namespace to perform operations.
122+
pod_name = get_cluster_tools_pod_on_node(node)
123+
exec = KubectlClient::Utils.exec_bg(pod_name, cli, namespace: self.namespace)
137124
Log.debug { "ClusterTools exec: #{exec}" }
138125
exec
139126
end
@@ -152,13 +139,13 @@ module ClusterTools
152139
Log.info {"node_pid_by_container_id container_id: #{container_id}" }
153140
short_container_id = parse_container_id(container_id)
154141
inspect = ClusterTools.exec_by_node("crictl inspect #{short_container_id}", node)
155-
Log.debug {"node_pid_by_container_id inspect: #{inspect[:output]}" }
156-
if inspect[:status].success?
157-
pid = "#{JSON.parse(inspect[:output]).dig?("info", "pid")}"
158-
else
142+
unless inspect[:status].success?
159143
Log.error {"container_id not found for: #{container_id}" }
160-
pid = nil
144+
return nil
161145
end
146+
147+
Log.debug {"node_pid_by_container_id inspect: #{inspect[:output]}" }
148+
pid = "#{JSON.parse(inspect[:output]).dig?("info", "pid")}"
162149
Log.info {"node_pid_by_container_id pid: #{pid}" }
163150
pid
164151
end
@@ -168,7 +155,7 @@ module ClusterTools
168155
case kind
169156
when "deployment","statefulset","pod","replicaset", "daemonset"
170157
resource_yaml = KubectlClient::Get.resource(resource[:kind], resource[:name], resource[:namespace])
171-
pods = KubectlClient::Get.pods_by_resource(resource_yaml, resource[:namespace])
158+
pods = KubectlClient::Get.pods_by_resource_labels(resource_yaml, resource[:namespace])
172159
pid_log_names = [] of String
173160
pod_resp = pods.map do |pod|
174161
pod_name = pod.dig("metadata", "name")
@@ -211,10 +198,17 @@ module ClusterTools
211198
node_name = node.dig("metadata", "name").as_s
212199
Log.info { "node name : #{node_name}" }
213200
if only_container_pids
214-
pids = KernelIntrospection::K8s::Node.pids_by_container(container_id, node)
215-
else
216-
pids = KernelIntrospection::K8s::Node.pids(node)
217-
end
201+
pids = KernelIntrospection::K8s::Node.pids_by_container(container_id, node)
202+
else
203+
pids = KernelIntrospection::K8s::Node.pids(node)
204+
end
205+
206+
if pids.empty?
207+
Log.info { "pids empty #{pids}" }
208+
false
209+
next
210+
end
211+
218212
Log.info { "parsed pids: #{pids}" }
219213
proc_statuses = KernelIntrospection::K8s::Node.all_statuses_by_pids(pids, node)
220214

@@ -237,8 +231,7 @@ module ClusterTools
237231

238232
def self.wait_for_cluster_tools
239233
Log.info { "ClusterTools wait_for_cluster_tools" }
240-
KubectlClient::Get.resource_wait_for_install("Daemonset", "cluster-tools", namespace: self.namespace!, wait_count: 300)
241-
# KubectlClient::Get.resource_wait_for_install("Daemonset", "cluster-tools-k8s", namespace: self.namespace)
234+
KubectlClient::Wait.resource_wait_for_install("Daemonset", "cluster-tools", namespace: self.namespace!, wait_count: 300)
242235
end
243236

244237
# https://windsock.io/explaining-docker-image-ids/
@@ -264,33 +257,56 @@ module ClusterTools
264257
JSON.parse(%({}))
265258
end
266259

267-
def self.local_match_by_image_name(image_names : Array(String), nodes=KubectlClient::Get.nodes["items"].as_a )
260+
def self.local_match_by_image_name(image_names : Array(String), nodes=KubectlClient::Get.resource("nodes")["items"].as_a )
268261
image_names.map{|x| local_match_by_image_name(x, nodes)}.flatten.find{|m|m[:found]==true}
269262
end
270-
def self.local_match_by_image_name(image_name, nodes=KubectlClient::Get.nodes["items"].as_a )
263+
def self.local_match_by_image_name(image_name, nodes=KubectlClient::Get.resource("nodes")["items"].as_a )
271264
Log.info { "local_match_by_image_name image_name: #{image_name}" }
272265
nodes = KubectlClient::Get.nodes["items"].as_a
273266
local_match_by_image_name(image_name, nodes)
274267
end
275268

269+
# TODO (rafal-lal): add spec for it
276270
def self.local_match_by_image_name(image_name, nodes : Array(JSON::Any))
277271
Log.info { "local_match_by_image_name image_name: #{image_name}" }
278272

279273
match = Hash{:found => false, :digest => "", :release_name => ""}
280-
#todo get name of pod and match against one pod instead of getting all pods and matching them
281-
tag = KubectlClient::Get.container_tag_from_image_by_nodes(image_name, nodes)
274+
# Group all imageIDs on passed 'nodes' into array.
275+
# If 'image_name' matches the name with tag, save its first occurence.
276+
# node.status.images is in following format:
277+
# {
278+
# "names": [
279+
# "registry.k8s.io/kube-state-metrics/kube-state-metrics@sha256:37d84129932.......",
280+
# "registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.14.0"
281+
# ],
282+
# "sizeBytes": 51212837
283+
# }
284+
tag = ""
285+
imageIDs = [] of String
286+
nodes.each do |node|
287+
begin
288+
images = node.dig("status", "images").as_a.each do |image|
289+
image.dig("names").as_a.each do |name|
290+
if name.as_s.includes?("sha256")
291+
imageIDs << name.as_s
292+
else
293+
next unless name.as_s.includes?(image_name)
294+
tag = DockerClient.parse_image(name.as_s)["tag"] if tag.empty?
295+
end
296+
end
297+
end
298+
rescue
299+
next
300+
end
301+
end
282302

283-
if tag
303+
if !tag.empty?
284304
Log.info { "container tag: #{tag}" }
285-
286-
pods = KubectlClient::Get.pods_by_nodes(nodes)
287-
288-
#todo container_digests_by_pod (use pod from previous image search) --- performance enhancement
289-
imageids = KubectlClient::Get.container_digests_by_nodes(nodes)
290-
resp = ClusterTools.official_content_digest_by_image_name(image_name + ":" + tag )
305+
306+
resp = ClusterTools.official_content_digest_by_image_name(image_name + ":" + tag)
291307
sha_list = [{"name" => image_name, "manifest_digest" => resp["Digest"].as_s}]
292308
Log.info { "jaeger_pods sha_list : #{sha_list}"}
293-
match = DockerClient::K8s.local_digest_match(sha_list, imageids)
309+
match = DockerClient::K8s.local_digest_match(sha_list, imageIDs)
294310
Log.info { "local_match_by_image_name match : #{match}"}
295311
else
296312
Log.info { "local_match_by_image_name tag: #{tag} match : #{match}"}
@@ -299,14 +315,14 @@ module ClusterTools
299315
Log.info { "local_match_by_image_name match: #{match}" }
300316
match
301317
end
302-
318+
303319
def self.pod_name()
304-
KubectlClient::Get.pod_status("cluster-tools", namespace: self.namespace!).split(",")[0]
320+
KubectlClient::Get.match_pods_by_prefix("cluster-tools", namespace: self.namespace!).first?
305321
end
306322

307323
def self.pod_by_node(node)
308324
resource = KubectlClient::Get.resource("Daemonset", "cluster-tools", namespace: self.namespace!)
309-
pods = KubectlClient::Get.pods_by_resource(resource, namespace: self.namespace!)
325+
pods = KubectlClient::Get.pods_by_resource_labels(resource, namespace: self.namespace!)
310326
cluster_pod = pods.find do |pod|
311327
pod.dig("spec", "nodeName") == node
312328
end

shard.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ shards:
66

77
kubectl_client:
88
git: https://github.com/cnf-testsuite/kubectl_client.git
9-
version: 1.0.1
9+
version: 1.0.8
1010

1111
popcorn:
1212
git: https://github.com/icyleaf/popcorn.git

shard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ crystal: '>= 1.0.0'
1515
dependencies:
1616
kubectl_client:
1717
github: cnf-testsuite/kubectl_client
18-
version: '~> 1.0.0'
18+
version: '~> 1.0.8'
1919
docker_client:
2020
github: cnf-testsuite/docker_client
2121
version: '~> 1.0.0'

spec/cluster_tools_spec.cr

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,29 @@ require "../cluster_tools.cr"
55
describe "ClusterTools" do
66
before_all do
77
begin
8-
is_namespace_created = KubectlClient::Create.namespace(ClusterTools.namespace)
9-
(is_namespace_created).should be_true
8+
KubectlClient::Apply.namespace(ClusterTools.namespace)
109
Log.info { "#{ClusterTools.namespace} namespace created" }
11-
rescue e : KubectlClient::Create::AlreadyExistsError
10+
rescue e : KubectlClient::ShellCMD::AlreadyExistsError
1211
Log.info { "#{ClusterTools.namespace} namespace already exists on the Kubernetes cluster" }
1312
end
1413
end
1514
after_all do
1615
ClusterTools.uninstall
1716
end
17+
1818
describe "pre install" do
1919
it "ensure_namespace_exists!" do
2020
(ClusterTools.ensure_namespace_exists!).should be_true
2121

22-
KubectlClient::Delete.command("namespace #{ClusterTools.namespace}")
22+
KubectlClient::Delete.resource("namespace", "#{ClusterTools.namespace}")
2323

2424
expect_raises(ClusterTools::NamespaceDoesNotExistException, "ClusterTools Namespace #{ClusterTools.namespace} does not exist") do
2525
ClusterTools.ensure_namespace_exists!
2626
end
2727
end
2828

2929
it "install" do
30-
KubectlClient::Create.namespace(ClusterTools.namespace)
30+
KubectlClient::Apply.namespace(ClusterTools.namespace)
3131

3232
(ClusterTools.install).should be_true
3333

@@ -39,14 +39,12 @@ describe "ClusterTools" do
3939
before_all do
4040
ClusterTools.install
4141
end
42-
it "ensure_namespace_exists!", do
42+
it "ensure_namespace_exists!" do
4343
(ClusterTools.ensure_namespace_exists!).should be_true
4444
end
4545

46-
it "pod_name", do
46+
it "pod_name" do
4747
(/cluster-tools/ =~ ClusterTools.pod_name).should_not be_nil
4848
end
4949
end
50-
5150
end
52-

0 commit comments

Comments
 (0)