Module: Pvectl::ManifestSerializer
- Defined in:
- lib/pvectl/manifest_serializer.rb
Overview
Wraps ConfigSerializer output with a kubectl-like manifest envelope (apiVersion, kind, metadata, spec). Handles bidirectional conversion between YAML manifest files and internal config representations.
Constant Summary collapse
- API_VERSION =
"pvectl/v1"- KINDS =
{ vm: "VirtualMachine", container: "Container" }.freeze
- KINDS_REVERSE =
KINDS.invert.transform_keys(&:to_s).freeze
Class Method Summary collapse
-
.from_yaml(yaml_string) ⇒ Hash
Parses a YAML manifest string into type, metadata, and spec.
-
.to_yaml(nested_config, type:, metadata:) ⇒ String
Builds a YAML manifest string from nested config and metadata.
-
.validate(yaml_string) ⇒ Array<String>
Validates manifest structure (envelope only, not spec content).
Class Method Details
.from_yaml(yaml_string) ⇒ Hash
Parses a YAML manifest string into type, metadata, and spec.
41 42 43 44 45 46 47 48 49 50 |
# File 'lib/pvectl/manifest_serializer.rb', line 41 def from_yaml(yaml_string) parsed = YAML.safe_load(yaml_string) type = KINDS_REVERSE[parsed["kind"]] { type: type, metadata: (parsed["metadata"] || {}), spec: symbolize_keys_deep(parsed["spec"] || {}) } end |
.to_yaml(nested_config, type:, metadata:) ⇒ String
Builds a YAML manifest string from nested config and metadata.
26 27 28 29 30 31 32 33 34 35 |
# File 'lib/pvectl/manifest_serializer.rb', line 26 def to_yaml(nested_config, type:, metadata:) manifest = { "apiVersion" => API_VERSION, "kind" => KINDS.fetch(type), "metadata" => (), "spec" => stringify_keys_deep(nested_config) } YAML.dump(manifest) end |
.validate(yaml_string) ⇒ Array<String>
Validates manifest structure (envelope only, not spec content).
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/pvectl/manifest_serializer.rb', line 56 def validate(yaml_string) errors = [] begin parsed = YAML.safe_load(yaml_string) rescue Psych::SyntaxError => e return ["YAML syntax error: #{e.}"] end unless parsed.is_a?(Hash) return ["Invalid manifest: expected a YAML mapping"] end unless parsed["apiVersion"] errors << "Missing required field 'apiVersion'" end if parsed["apiVersion"] && parsed["apiVersion"] != API_VERSION errors << "Unsupported apiVersion '#{parsed["apiVersion"]}'. Expected: #{API_VERSION}" end errors << "Missing required field 'kind'" unless parsed["kind"] if parsed["kind"] && !KINDS_REVERSE.key?(parsed["kind"]) errors << "Unknown kind '#{parsed["kind"]}'. Valid: #{KINDS.values.join(', ')}" end = parsed["metadata"] if .nil? || !.is_a?(Hash) errors << "Missing required field 'metadata'" end errors end |