class Krane::ClusterResourceDiscovery
Public Class Methods
new(task_config:, namespace_tags: [])
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 8 def initialize(task_config:, namespace_tags: []) @task_config = task_config @namespace_tags = namespace_tags @api_path_cache = {} end
Public Instance Methods
crds()
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 14 def crds @crds ||= fetch_crds.map do |cr_def| CustomResourceDefinition.new(namespace: namespace, context: context, logger: logger, definition: cr_def, statsd_tags: @namespace_tags) end end
fetch_mutating_webhook_configurations()
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 40 def fetch_mutating_webhook_configurations command = %w(get mutatingwebhookconfigurations) raw_json, err, st = kubectl.run(*command, output: "json", attempts: 5, use_namespace: false) if st.success? JSON.parse(raw_json)["items"].map do |definition| Krane::MutatingWebhookConfiguration.new(namespace: namespace, context: context, logger: logger, definition: definition, statsd_tags: @namespace_tags) end else raise FatalKubeAPIError, "Error retrieving mutatingwebhookconfigurations: #{err}" end end
fetch_resources(namespaced: false)
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 30 def fetch_resources(namespaced: false) responses = Concurrent::Hash.new Krane::Concurrency.split_across_threads(api_paths) do |path| responses[path] = fetch_api_path(path)["resources"] || [] end responses.flat_map do |path, resources| resources.map { |r| resource_hash(path, namespaced, r) } end.compact.uniq { |r| "#{r['apigroup']}/#{r['kind']}" } end
prunable_resources(namespaced:)
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 21 def prunable_resources(namespaced:) black_list = %w(Namespace Node ControllerRevision) fetch_resources(namespaced: namespaced).map do |resource| next unless resource["verbs"].one? { |v| v == "delete" } next if black_list.include?(resource["kind"]) [resource["apigroup"], resource["version"], resource["kind"]].compact.join("/") end.compact end
Private Instance Methods
api_paths()
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 66 def api_paths @api_path_cache["/"] ||= begin raw_json, err, st = kubectl.run("get", "--raw", base_api_path, attempts: 5, use_namespace: false) paths = if st.success? JSON.parse(raw_json)["paths"] else raise FatalKubeAPIError, "Error retrieving raw path /: #{err}" end paths.select { |path| %r{^\/api.*\/v.*$}.match(path) } end end
base_api_path()
click to toggle source
During discovery, the api paths may not actually be at the root, so we must programatically find it.
# File lib/krane/cluster_resource_discovery.rb, line 56 def base_api_path @base_api_path ||= begin raw_response, err, st = kubectl.run("config", "view", "--minify", "--output", "jsonpath={.clusters[*].cluster.server}", attempts: 5, use_namespace: false) raise FatalKubeAPIError, "Error retrieving cluster url: #{err}" unless st.success? URI(raw_response).path.blank? ? "/" : URI(raw_response).path end end
fetch_api_path(path)
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 78 def fetch_api_path(path) @api_path_cache[path] ||= begin raw_json, err, st = kubectl.run("get", "--raw", path, attempts: 2, use_namespace: false) if st.success? JSON.parse(raw_json) else logger.warn("Error retrieving api path: #{err}") {} end end end
fetch_crds()
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 104 def fetch_crds raw_json, err, st = kubectl.run("get", "CustomResourceDefinition", output: "json", attempts: 5, use_namespace: false) if st.success? JSON.parse(raw_json)["items"] else raise FatalKubeAPIError, "Error retrieving CustomResourceDefinition: #{err}" end end
kubectl()
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 114 def kubectl @kubectl ||= Kubectl.new(task_config: @task_config, log_failure_by_default: true) end
resource_hash(path, namespaced, blob)
click to toggle source
# File lib/krane/cluster_resource_discovery.rb, line 90 def resource_hash(path, namespaced, blob) return unless blob["namespaced"] == namespaced # skip sub-resources return if blob["name"].include?("/") path_regex = %r{(/apis?/)(?<group>[^/]*)/?(?<version>v.+)} match = path.match(path_regex) { "verbs" => blob["verbs"], "kind" => blob["kind"], "apigroup" => match[:group], "version" => match[:version], } end