class << self
Definitions
attr_accessor :schema_version
Set a default Kubernetes version for bare lookups like Kube::Schema["Deployment"]. When nil, the DEFAULT_VERSION is used.
attr_reader :custom_schemas
Custom schemas registered via Kube::Schema.register.
Keys are kind strings, values are schema:, defaults: hashes.
def register(kind, schema:, api_version:)
Register a standalone JSON Schema for a custom resource kind.
This lets users add CRD schemas from any source — for example, the datreeio/CRDs-catalog, operator repos, or their own CRDs. Registered kinds take precedence over built-in definitions.
a JSON string, or a file path to a .json file
Example: Register from a local file
Kube::Schema.register("Certificate",
schema: "schemas/cert-manager.io/certificate_v1.json",
api_version: "cert-manager.io/v1"
)
Example: Register from Chart#crds
chart.crds.each do |crd|
s = crd.to_json_schema
Kube::Schema.register(s[:kind], schema: s[:schema], api_version: s[:api_version])
end
Signature
Implementation
def register(kind, schema:, api_version:)
require "json"
require "json_schemer"
parsed = case schema
when Hash
schema
when String, Pathname
path = schema.to_s
if File.exist?(path)
JSON.parse(File.read(path))
else
JSON.parse(path)
end
else
raise ArgumentError,
"schema must be a Hash, a JSON string, or a file path — got #{schema.class}"
end
@custom_schemas[kind] = {
schema: JSONSchemer.schema(parsed),
defaults: { "apiVersion" => api_version, "kind" => kind }.freeze
}
# Invalidate cached resource classes on all instances so the
# new registration takes effect immediately.
@instances.each_value { |inst| inst.send(:clear_resource_cache!) }
kind
end
def reset_custom_schemas!
Remove all custom schema registrations. Useful for test teardown or resetting state.
Implementation
def reset_custom_schemas!
@custom_schemas.clear
@instances.each_value { |inst| inst.send(:clear_resource_cache!) }
end
def [](key)
Kube::Schema["1.34"] => cached Instance (supports ["Deployment"] chaining) Kube::Schema["Deployment"] => Resource via the default version
Implementation
def [](key)
if key.start_with?("v") && Gem::Version.correct?(key.sub("v", ""))
raise Kube::IncorrectVersionFormat,
"\nDon't preface the version with a \"v\"." \
"\nUse Kube::Schema[\"#{key.sub("v", "")}\"] instead."
end
if Gem::Version.correct?(key)
if has_version?(key)
@instances[key] ||= Instance.new(key)
else
raise Kube::UnknownVersionError.new(
"\n#{key} is an unknown version..." +
"\nAvailable: #{schema_versions.join(", ")}"
)
end
else
version = schema_version || DEFAULT_VERSION
@instances[version] ||= Instance.new(version)
@instances[version][key]
end
end
def parse(hash)
Build a typed Resource from a raw hash.
Looks up the "kind" key in the hash and resolves it to the correct Resource subclass via the schema registry. The hash may use string or symbol keys.
Kube::Schema.parse("kind" => "Deployment", "apiVersion" => "apps/v1")
Kube::Schema.parse(kind: "Pod", apiVersion: "v1", metadata: name: "web" )
Implementation
def parse(hash)
raise ArgumentError, "Expected a Hash, got #{hash.class}" unless hash.is_a?(Hash)
kind = hash["kind"] || hash[:kind]
raise ArgumentError, "Hash must contain a \"kind\" key" if kind.nil?
resource_class = self[kind]
resource_class.new(hash)
end
def schema_versions
Available Kubernetes versions, read from the local schemas directory.
Implementation
def schema_versions
@schema_versions ||=
Dir.glob(File.join(SCHEMAS_DIR, "v*.json")).map do |file_path|
File.basename(file_path, ".json").sub(/\Av/, "")
end.sort_by { Gem::Version.new(_1) }
end
def latest_version
The latest Kubernetes version available in the schemas directory.
Implementation
def latest_version
schema_versions.last
end