walheim 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/walheim/cli/base_command.rb +35 -40
- data/lib/walheim/cli/helpers.rb +17 -17
- data/lib/walheim/cli/legacy_context.rb +54 -54
- data/lib/walheim/cli/resource_command.rb +11 -9
- data/lib/walheim/cli.rb +20 -19
- data/lib/walheim/cluster_resource.rb +5 -5
- data/lib/walheim/config.rb +36 -34
- data/lib/walheim/handler_registry.rb +2 -3
- data/lib/walheim/namespaced_resource.rb +28 -19
- data/lib/walheim/resource.rb +11 -11
- data/lib/walheim/resources/apps.rb +118 -116
- data/lib/walheim/resources/configmaps.rb +7 -7
- data/lib/walheim/resources/namespaces.rb +27 -27
- data/lib/walheim/resources/secrets.rb +9 -9
- data/lib/walheim/sync.rb +5 -5
- data/lib/walheim/version.rb +1 -1
- data/lib/walheim.rb +12 -12
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5b943785b380c1a8fcd220c0f9c4716a6e9fe5d255b31e7b874115f0b0c8734a
|
|
4
|
+
data.tar.gz: a5d62f283a0da1189b07129512a0f7698b3c4811f653f5735576139fa76c4f0f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3b01e7611db7c3f589c3c0043ed8762f1fac6768c884f177c045a188ff16440b0f5ac4184b31ad681febdf2b79d7db247856c191fd9bb074cdfe4884bc4521aa
|
|
7
|
+
data.tar.gz: 5374cfd930d9ddb54117209f2ac9eefa1436dbc293db46d2ef8f1307dd91b6bba72b82ce918ef8511569720d9992662fa59c0103e2bdf0bc0544db021a72f71d
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "helpers"
|
|
4
4
|
|
|
5
5
|
module Walheim
|
|
6
6
|
module BaseCommand
|
|
@@ -9,8 +9,8 @@ module Walheim
|
|
|
9
9
|
handler_info = Walheim::HandlerRegistry.get(kind)
|
|
10
10
|
unless handler_info
|
|
11
11
|
warn "Error: unknown kind '#{kind}'"
|
|
12
|
-
warn
|
|
13
|
-
warn
|
|
12
|
+
warn ""
|
|
13
|
+
warn "Available kinds:"
|
|
14
14
|
Walheim::HandlerRegistry.all_visible.each { |h| warn " #{h[:name]}" }
|
|
15
15
|
exit 1
|
|
16
16
|
end
|
|
@@ -28,16 +28,12 @@ module Walheim
|
|
|
28
28
|
handler = handler_info[:handler].new(data_dir: data_dir)
|
|
29
29
|
|
|
30
30
|
# 5. Validate namespace requirements
|
|
31
|
-
if handler.is_a?(Walheim::NamespacedResource)
|
|
32
|
-
validate_namespace_options!(operation, kind, name, options)
|
|
33
|
-
end
|
|
31
|
+
validate_namespace_options!(operation, kind, name, options) if handler.is_a?(Walheim::NamespacedResource)
|
|
34
32
|
|
|
35
33
|
# 6. Dispatch to handler
|
|
36
34
|
dispatch_to_handler(handler, operation, name, options, handler_info)
|
|
37
35
|
end
|
|
38
36
|
|
|
39
|
-
private
|
|
40
|
-
|
|
41
37
|
def self.resolve_data_dir(options, parent_options)
|
|
42
38
|
# Merge options
|
|
43
39
|
all_options = parent_options.merge(options)
|
|
@@ -51,49 +47,50 @@ module Walheim
|
|
|
51
47
|
if context_name
|
|
52
48
|
config.data_dir(context_name)
|
|
53
49
|
elsif all_options[:data_dir]
|
|
54
|
-
warn
|
|
50
|
+
warn "Warning: --data-dir is deprecated. Use contexts."
|
|
55
51
|
all_options[:data_dir]
|
|
56
52
|
else
|
|
57
|
-
warn
|
|
58
|
-
warn
|
|
59
|
-
warn
|
|
60
|
-
warn
|
|
53
|
+
warn "Error: No Walheim configuration found."
|
|
54
|
+
warn ""
|
|
55
|
+
warn "Create your first context:"
|
|
56
|
+
warn " whctl context new <name> --data-dir <path>"
|
|
61
57
|
exit 1
|
|
62
58
|
end
|
|
63
59
|
rescue Walheim::Config::ConfigError, Walheim::Config::ValidationError
|
|
64
60
|
if all_options[:data_dir]
|
|
65
|
-
warn
|
|
61
|
+
warn "Warning: --data-dir is deprecated."
|
|
66
62
|
all_options[:data_dir]
|
|
67
63
|
else
|
|
68
|
-
warn
|
|
69
|
-
warn
|
|
70
|
-
warn
|
|
71
|
-
warn
|
|
64
|
+
warn "Error: No Walheim configuration found."
|
|
65
|
+
warn ""
|
|
66
|
+
warn "Create your first context:"
|
|
67
|
+
warn " whctl context new <name> --data-dir <path>"
|
|
72
68
|
exit 1
|
|
73
69
|
end
|
|
74
70
|
end
|
|
75
71
|
end
|
|
76
72
|
|
|
77
|
-
def self.validate_namespace_options!(operation, kind,
|
|
73
|
+
def self.validate_namespace_options!(operation, kind, _name, options)
|
|
78
74
|
# Operations that require namespace or --all
|
|
79
|
-
requires_namespace = [
|
|
75
|
+
requires_namespace = %i[get apply delete start pause stop logs import]
|
|
80
76
|
return unless requires_namespace.include?(operation)
|
|
81
77
|
|
|
82
78
|
# get can use --all
|
|
83
79
|
if operation == :get
|
|
84
80
|
return if options[:all] || options[:namespace]
|
|
85
|
-
|
|
81
|
+
|
|
82
|
+
warn "Error: either -n {namespace} or --all/-A flag is required"
|
|
86
83
|
warn "Usage: whctl get #{kind} -n {namespace}"
|
|
87
84
|
warn "Usage: whctl get #{kind} --all"
|
|
88
85
|
exit 1
|
|
89
86
|
end
|
|
90
87
|
|
|
91
88
|
# Other operations require namespace
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
return if options[:namespace]
|
|
90
|
+
|
|
91
|
+
warn "Error: -n {namespace} is required"
|
|
92
|
+
warn "Usage: whctl #{operation} #{kind} {name} -n {namespace}"
|
|
93
|
+
exit 1
|
|
97
94
|
end
|
|
98
95
|
|
|
99
96
|
def self.dispatch_to_handler(handler, operation, name, options, handler_info)
|
|
@@ -131,45 +128,43 @@ module Walheim
|
|
|
131
128
|
Walheim::Helpers.print_cluster_resources_table(result, handler_info[:name])
|
|
132
129
|
else
|
|
133
130
|
result = if options[:all]
|
|
134
|
-
|
|
131
|
+
handler.get(namespace: nil, name: nil)
|
|
135
132
|
else
|
|
136
|
-
|
|
133
|
+
handler.get(namespace: options[:namespace], name: name)
|
|
137
134
|
end
|
|
138
135
|
Walheim::Helpers.print_resources_table(result, options[:all], handler_info[:name])
|
|
139
136
|
end
|
|
140
137
|
end
|
|
141
138
|
|
|
142
|
-
def self.dispatch_apply(handler, name, options,
|
|
139
|
+
def self.dispatch_apply(handler, name, options, _handler_info)
|
|
143
140
|
# Extract from manifest if -f provided
|
|
144
141
|
if options[:file]
|
|
145
142
|
manifest_data = Walheim::Helpers.read_yaml_input(options[:file])
|
|
146
143
|
|
|
147
144
|
if handler.is_a?(Walheim::NamespacedResource)
|
|
148
|
-
namespace = manifest_data[
|
|
149
|
-
name = manifest_data[
|
|
145
|
+
namespace = manifest_data["metadata"]["namespace"]
|
|
146
|
+
name = manifest_data["metadata"]["name"]
|
|
150
147
|
|
|
151
148
|
unless namespace && name
|
|
152
|
-
warn
|
|
149
|
+
warn "Error: Manifest must contain metadata.namespace and metadata.name"
|
|
153
150
|
exit 1
|
|
154
151
|
end
|
|
155
152
|
|
|
156
153
|
handler.apply(namespace: namespace, name: name, manifest_source: options[:file])
|
|
157
154
|
else
|
|
158
155
|
# Cluster resource
|
|
159
|
-
name = manifest_data[
|
|
156
|
+
name = manifest_data["metadata"]["name"]
|
|
160
157
|
unless name
|
|
161
|
-
warn
|
|
158
|
+
warn "Error: Manifest must contain metadata.name"
|
|
162
159
|
exit 1
|
|
163
160
|
end
|
|
164
161
|
handler.apply(name: name, manifest_source: options[:file])
|
|
165
162
|
end
|
|
166
|
-
|
|
163
|
+
elsif handler.is_a?(Walheim::NamespacedResource)
|
|
167
164
|
# Apply from existing manifest in data dir
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
handler.apply(name: name)
|
|
172
|
-
end
|
|
165
|
+
handler.apply(namespace: options[:namespace], name: name)
|
|
166
|
+
else
|
|
167
|
+
handler.apply(name: name)
|
|
173
168
|
end
|
|
174
169
|
end
|
|
175
170
|
end
|
data/lib/walheim/cli/helpers.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "terminal-table"
|
|
4
|
+
require "yaml"
|
|
5
5
|
|
|
6
6
|
module Walheim
|
|
7
7
|
module Helpers
|
|
@@ -22,31 +22,31 @@ module Walheim
|
|
|
22
22
|
summary_fields = result.first[:summary].keys
|
|
23
23
|
|
|
24
24
|
# Build header row
|
|
25
|
-
if all_namespaces
|
|
26
|
-
|
|
25
|
+
headers = if all_namespaces
|
|
26
|
+
%w[NAMESPACE NAME] + summary_fields.map(&:to_s).map(&:upcase)
|
|
27
27
|
else
|
|
28
|
-
|
|
28
|
+
[ "NAME" ] + summary_fields.map(&:to_s).map(&:upcase)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Build data rows
|
|
32
32
|
rows = result.map do |resource|
|
|
33
33
|
row = if all_namespaces
|
|
34
|
-
|
|
34
|
+
[ resource[:namespace], resource[:name] ]
|
|
35
35
|
else
|
|
36
|
-
|
|
36
|
+
[ resource[:name] ]
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
# Add summary field values
|
|
40
|
-
summary_values = summary_fields.map { |field| resource[:summary][field] ||
|
|
40
|
+
summary_values = summary_fields.map { |field| resource[:summary][field] || "N/A" }
|
|
41
41
|
row + summary_values
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
all_rows = [headers] + rows
|
|
44
|
+
all_rows = [ headers ] + rows
|
|
45
45
|
|
|
46
46
|
table = Terminal::Table.new do |t|
|
|
47
47
|
t.rows = all_rows
|
|
48
48
|
t.style = {
|
|
49
|
-
border_x:
|
|
49
|
+
border_x: "", border_y: "", border_i: "",
|
|
50
50
|
padding_left: 0, padding_right: 3,
|
|
51
51
|
border_top: false, border_bottom: false,
|
|
52
52
|
all_separators: false
|
|
@@ -73,23 +73,23 @@ module Walheim
|
|
|
73
73
|
summary_fields = result.first[:summary].keys
|
|
74
74
|
|
|
75
75
|
# Build header row (no NAMESPACE column for cluster resources)
|
|
76
|
-
headers = [
|
|
76
|
+
headers = [ "NAME" ] + summary_fields.map(&:to_s).map(&:upcase)
|
|
77
77
|
|
|
78
78
|
# Build data rows
|
|
79
79
|
rows = result.map do |resource|
|
|
80
|
-
row = [resource[:name]]
|
|
80
|
+
row = [ resource[:name] ]
|
|
81
81
|
|
|
82
82
|
# Add summary field values
|
|
83
|
-
summary_values = summary_fields.map { |field| resource[:summary][field] ||
|
|
83
|
+
summary_values = summary_fields.map { |field| resource[:summary][field] || "N/A" }
|
|
84
84
|
row + summary_values
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
-
all_rows = [headers] + rows
|
|
87
|
+
all_rows = [ headers ] + rows
|
|
88
88
|
|
|
89
89
|
table = Terminal::Table.new do |t|
|
|
90
90
|
t.rows = all_rows
|
|
91
91
|
t.style = {
|
|
92
|
-
border_x:
|
|
92
|
+
border_x: "", border_y: "", border_i: "",
|
|
93
93
|
padding_left: 0, padding_right: 3,
|
|
94
94
|
border_top: false, border_bottom: false,
|
|
95
95
|
all_separators: false
|
|
@@ -101,9 +101,9 @@ module Walheim
|
|
|
101
101
|
|
|
102
102
|
# Read YAML from file or stdin
|
|
103
103
|
def self.read_yaml_input(file_path)
|
|
104
|
-
if file_path ==
|
|
104
|
+
if file_path == "-"
|
|
105
105
|
# Read from stdin
|
|
106
|
-
YAML.
|
|
106
|
+
YAML.safe_load($stdin.read)
|
|
107
107
|
else
|
|
108
108
|
# Read from file
|
|
109
109
|
YAML.load_file(file_path)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "optparse"
|
|
4
|
+
require "terminal-table"
|
|
5
5
|
|
|
6
6
|
module Walheim
|
|
7
7
|
module LegacyContext
|
|
@@ -9,12 +9,12 @@ module Walheim
|
|
|
9
9
|
options = {}
|
|
10
10
|
|
|
11
11
|
# Remove 'context' from argv since it's already been identified
|
|
12
|
-
argv.shift if argv[0] ==
|
|
12
|
+
argv.shift if argv[0] == "context"
|
|
13
13
|
|
|
14
14
|
# Parse global flags
|
|
15
15
|
global_parser = OptionParser.new do |opts|
|
|
16
|
-
opts.on(
|
|
17
|
-
opts.on(
|
|
16
|
+
opts.on("--whconfig PATH", "Alternate config file path") { |v| options[:whconfig] = v }
|
|
17
|
+
opts.on("-d DIR", "--data-dir DIR", "Data directory") { |v| options[:data_dir] = v }
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# Parse global flags (use parse! to consume all flags)
|
|
@@ -30,17 +30,17 @@ module Walheim
|
|
|
30
30
|
context_name = argv[1]
|
|
31
31
|
|
|
32
32
|
case subcommand
|
|
33
|
-
when
|
|
33
|
+
when "new"
|
|
34
34
|
# whctl context new {name} --data-dir {path}
|
|
35
35
|
unless context_name
|
|
36
|
-
warn
|
|
37
|
-
warn
|
|
36
|
+
warn "Error: context name is required"
|
|
37
|
+
warn "Usage: whctl context new {name} --data-dir {path}"
|
|
38
38
|
exit 1
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
unless options[:data_dir]
|
|
42
|
-
warn
|
|
43
|
-
warn
|
|
42
|
+
warn "Error: --data-dir flag is required"
|
|
43
|
+
warn "Usage: whctl context new {name} --data-dir {path}"
|
|
44
44
|
exit 1
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -48,19 +48,19 @@ module Walheim
|
|
|
48
48
|
expanded_data_dir = File.expand_path(options[:data_dir])
|
|
49
49
|
unless Dir.exist?(expanded_data_dir)
|
|
50
50
|
warn "Error: data directory '#{expanded_data_dir}' does not exist"
|
|
51
|
-
warn
|
|
52
|
-
warn
|
|
51
|
+
warn ""
|
|
52
|
+
warn "Please create the directory first or provide a valid path"
|
|
53
53
|
exit 1
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# Check for namespaces subdirectory
|
|
57
|
-
namespaces_path = File.join(expanded_data_dir,
|
|
57
|
+
namespaces_path = File.join(expanded_data_dir, "namespaces")
|
|
58
58
|
unless Dir.exist?(namespaces_path)
|
|
59
59
|
warn "Warning: data directory does not contain 'namespaces' subdirectory"
|
|
60
60
|
warn "Expected path: #{namespaces_path}"
|
|
61
|
-
warn
|
|
62
|
-
warn
|
|
63
|
-
warn
|
|
61
|
+
warn ""
|
|
62
|
+
warn "This directory should contain your homelab configuration."
|
|
63
|
+
warn "Creating namespaces directory..."
|
|
64
64
|
Dir.mkdir(namespaces_path)
|
|
65
65
|
end
|
|
66
66
|
|
|
@@ -81,34 +81,34 @@ module Walheim
|
|
|
81
81
|
exit 1
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
when
|
|
84
|
+
when "list"
|
|
85
85
|
# whctl context list
|
|
86
86
|
config = Walheim::Config.new(config_path: options[:whconfig])
|
|
87
87
|
|
|
88
88
|
unless Walheim::Config.exists?(config_path: options[:whconfig])
|
|
89
|
-
warn
|
|
90
|
-
warn
|
|
91
|
-
warn
|
|
92
|
-
warn
|
|
89
|
+
warn "No Walheim configuration found."
|
|
90
|
+
warn ""
|
|
91
|
+
warn "Create your first context:"
|
|
92
|
+
warn " whctl context new <name> --data-dir <path>"
|
|
93
93
|
exit 1
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
contexts = config.list_contexts
|
|
97
97
|
if contexts.empty?
|
|
98
|
-
puts
|
|
98
|
+
puts "No contexts configured."
|
|
99
99
|
exit 0
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
rows = contexts.map do |ctx|
|
|
103
|
-
active_marker = ctx[
|
|
104
|
-
[active_marker, ctx[
|
|
103
|
+
active_marker = ctx["active"] ? "*" : ""
|
|
104
|
+
[ active_marker, ctx["name"], ctx["dataDir"] ]
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
table = Terminal::Table.new do |t|
|
|
108
|
-
t.headings = [
|
|
108
|
+
t.headings = [ "CURRENT", "NAME", "DATA DIRECTORY" ]
|
|
109
109
|
t.rows = rows
|
|
110
110
|
t.style = {
|
|
111
|
-
border_x:
|
|
111
|
+
border_x: "", border_y: "", border_i: "",
|
|
112
112
|
padding_left: 0, padding_right: 3,
|
|
113
113
|
border_top: false, border_bottom: false,
|
|
114
114
|
all_separators: false
|
|
@@ -117,11 +117,11 @@ module Walheim
|
|
|
117
117
|
|
|
118
118
|
puts table
|
|
119
119
|
|
|
120
|
-
when
|
|
120
|
+
when "use"
|
|
121
121
|
# whctl context use {name}
|
|
122
122
|
unless context_name
|
|
123
|
-
warn
|
|
124
|
-
warn
|
|
123
|
+
warn "Error: context name is required"
|
|
124
|
+
warn "Usage: whctl context use {name}"
|
|
125
125
|
exit 1
|
|
126
126
|
end
|
|
127
127
|
|
|
@@ -136,15 +136,15 @@ module Walheim
|
|
|
136
136
|
exit 1
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
-
when
|
|
139
|
+
when "current"
|
|
140
140
|
# whctl context current
|
|
141
141
|
config = Walheim::Config.new(config_path: options[:whconfig])
|
|
142
142
|
|
|
143
143
|
unless Walheim::Config.exists?(config_path: options[:whconfig])
|
|
144
|
-
warn
|
|
145
|
-
warn
|
|
146
|
-
warn
|
|
147
|
-
warn
|
|
144
|
+
warn "No Walheim configuration found."
|
|
145
|
+
warn ""
|
|
146
|
+
warn "Create your first context:"
|
|
147
|
+
warn " whctl context new <name> --data-dir <path>"
|
|
148
148
|
exit 1
|
|
149
149
|
end
|
|
150
150
|
|
|
@@ -152,22 +152,22 @@ module Walheim
|
|
|
152
152
|
puts "Current context: #{config.current_context}"
|
|
153
153
|
puts "Data directory: #{config.data_dir}"
|
|
154
154
|
else
|
|
155
|
-
puts
|
|
156
|
-
puts
|
|
157
|
-
puts
|
|
155
|
+
puts "No active context selected."
|
|
156
|
+
puts ""
|
|
157
|
+
puts "Available contexts:"
|
|
158
158
|
config.list_contexts.each do |ctx|
|
|
159
159
|
puts " - #{ctx['name']}"
|
|
160
160
|
end
|
|
161
|
-
puts
|
|
162
|
-
puts
|
|
163
|
-
puts
|
|
161
|
+
puts ""
|
|
162
|
+
puts "Select a context:"
|
|
163
|
+
puts " whctl context use <context-name>"
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
-
when
|
|
166
|
+
when "delete"
|
|
167
167
|
# whctl context delete {name}
|
|
168
168
|
unless context_name
|
|
169
|
-
warn
|
|
170
|
-
warn
|
|
169
|
+
warn "Error: context name is required"
|
|
170
|
+
warn "Usage: whctl context delete {name}"
|
|
171
171
|
exit 1
|
|
172
172
|
end
|
|
173
173
|
|
|
@@ -180,10 +180,10 @@ module Walheim
|
|
|
180
180
|
|
|
181
181
|
# Show warning if this was the active context
|
|
182
182
|
unless config.current_context
|
|
183
|
-
puts
|
|
184
|
-
puts
|
|
185
|
-
puts
|
|
186
|
-
puts
|
|
183
|
+
puts ""
|
|
184
|
+
puts "Note: This was your active context."
|
|
185
|
+
puts "Select a new context with:"
|
|
186
|
+
puts " whctl context use <context-name>"
|
|
187
187
|
end
|
|
188
188
|
rescue Walheim::Config::ConfigError => e
|
|
189
189
|
warn "Error: #{e.message}"
|
|
@@ -192,13 +192,13 @@ module Walheim
|
|
|
192
192
|
|
|
193
193
|
else
|
|
194
194
|
warn "Error: unknown context subcommand '#{subcommand}'"
|
|
195
|
-
warn
|
|
196
|
-
warn
|
|
197
|
-
warn
|
|
198
|
-
warn
|
|
199
|
-
warn
|
|
200
|
-
warn
|
|
201
|
-
warn
|
|
195
|
+
warn ""
|
|
196
|
+
warn "Available context commands:"
|
|
197
|
+
warn " whctl context new {name} --data-dir {path}"
|
|
198
|
+
warn " whctl context list"
|
|
199
|
+
warn " whctl context use {name}"
|
|
200
|
+
warn " whctl context current"
|
|
201
|
+
warn " whctl context delete {name}"
|
|
202
202
|
exit 1
|
|
203
203
|
end
|
|
204
204
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "base_command"
|
|
4
4
|
|
|
5
5
|
module Walheim
|
|
6
6
|
module ResourceCommand
|
|
@@ -10,7 +10,7 @@ module Walheim
|
|
|
10
10
|
return if handlers.empty?
|
|
11
11
|
|
|
12
12
|
# Build command description
|
|
13
|
-
descriptions = handlers.map { |h| h[:name] }.join(
|
|
13
|
+
descriptions = handlers.map { |h| h[:name] }.join(", ")
|
|
14
14
|
desc_text = "#{operation.to_s.capitalize} resources (#{descriptions})"
|
|
15
15
|
|
|
16
16
|
# Define Thor command
|
|
@@ -21,12 +21,10 @@ module Walheim
|
|
|
21
21
|
all_options = {}
|
|
22
22
|
handlers.each do |handler_info|
|
|
23
23
|
handler_class = handler_info[:handler]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end
|
|
29
|
-
end
|
|
24
|
+
next unless handler_class.respond_to?(:operation_info)
|
|
25
|
+
|
|
26
|
+
op_metadata = handler_class.operation_info[operation]
|
|
27
|
+
all_options.merge!(op_metadata[:options]) if op_metadata && op_metadata[:options]
|
|
30
28
|
end
|
|
31
29
|
|
|
32
30
|
# Register options with Thor
|
|
@@ -43,7 +41,11 @@ module Walheim
|
|
|
43
41
|
kind: kind,
|
|
44
42
|
name: name,
|
|
45
43
|
options: options,
|
|
46
|
-
parent_options: self.class.class_options.transform_keys(&:to_sym).transform_values
|
|
44
|
+
parent_options: self.class.class_options.transform_keys(&:to_sym).transform_values do |v|
|
|
45
|
+
options[v.name]
|
|
46
|
+
rescue StandardError
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
47
49
|
)
|
|
48
50
|
end
|
|
49
51
|
end
|
data/lib/walheim/cli.rb
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
3
|
+
require "thor"
|
|
4
|
+
require_relative "cli/helpers"
|
|
5
|
+
require_relative "cli/base_command"
|
|
6
|
+
require_relative "cli/resource_command"
|
|
7
7
|
|
|
8
8
|
module Walheim
|
|
9
9
|
class CLI < Thor
|
|
10
10
|
# Global flags
|
|
11
11
|
class_option :context,
|
|
12
12
|
type: :string,
|
|
13
|
-
desc:
|
|
13
|
+
desc: "Override active context"
|
|
14
14
|
|
|
15
15
|
class_option :whconfig,
|
|
16
16
|
type: :string,
|
|
17
|
-
desc:
|
|
17
|
+
desc: "Alternate config file path"
|
|
18
18
|
|
|
19
19
|
class_option :data_dir,
|
|
20
20
|
type: :string,
|
|
21
|
-
aliases: [:d],
|
|
22
|
-
desc:
|
|
21
|
+
aliases: [ :d ],
|
|
22
|
+
desc: "Data directory (deprecated: use contexts)"
|
|
23
23
|
|
|
24
24
|
# Dynamically register operations
|
|
25
25
|
def self.register_operations
|
|
@@ -29,7 +29,7 @@ module Walheim
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Version command
|
|
32
|
-
desc
|
|
32
|
+
desc "version", "Show version"
|
|
33
33
|
def version
|
|
34
34
|
puts "whctl version #{Walheim::VERSION}"
|
|
35
35
|
end
|
|
@@ -42,19 +42,20 @@ module Walheim
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Group commands by category
|
|
45
|
-
shell.say
|
|
46
|
-
shell.say
|
|
47
|
-
shell.say
|
|
48
|
-
shell.say
|
|
49
|
-
shell.say
|
|
50
|
-
shell.say
|
|
51
|
-
shell.say
|
|
52
|
-
shell.say
|
|
53
|
-
shell.say
|
|
45
|
+
shell.say "Usage: whctl [global flags] <command> [arguments]"
|
|
46
|
+
shell.say ""
|
|
47
|
+
shell.say "Global flags:"
|
|
48
|
+
shell.say " --context CONTEXT Override active context for this command"
|
|
49
|
+
shell.say " --whconfig PATH Use alternate config file (default: ~/.walheim/config)"
|
|
50
|
+
shell.say " -d, --data-dir DIR Data directory containing namespaces (deprecated: use contexts)"
|
|
51
|
+
shell.say ""
|
|
52
|
+
shell.say "Available commands:"
|
|
53
|
+
shell.say ""
|
|
54
54
|
|
|
55
55
|
# Print commands
|
|
56
56
|
list.each do |command|
|
|
57
|
-
next if command[0] ==
|
|
57
|
+
next if command[0] == "help"
|
|
58
|
+
|
|
58
59
|
shell.say " #{command[0].ljust(30)} #{command[1]}"
|
|
59
60
|
end
|
|
60
61
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "resource"
|
|
4
4
|
|
|
5
5
|
module Walheim
|
|
6
6
|
# ClusterResource represents resources that are cluster-scoped (not namespaced)
|
|
@@ -69,9 +69,9 @@ module Walheim
|
|
|
69
69
|
# Apply operation - create or update
|
|
70
70
|
def apply(name:, manifest_source: nil)
|
|
71
71
|
manifest_data = if manifest_source
|
|
72
|
-
|
|
72
|
+
File.read(manifest_source)
|
|
73
73
|
else
|
|
74
|
-
|
|
74
|
+
read_manifest_from_db(name)
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
if resource_exists?(name)
|
|
@@ -91,7 +91,7 @@ module Walheim
|
|
|
91
91
|
|
|
92
92
|
manifest_path = File.join(resource_dir(name), manifest_filename)
|
|
93
93
|
manifest_content = File.read(manifest_path)
|
|
94
|
-
manifest_data = YAML.
|
|
94
|
+
manifest_data = YAML.safe_load(manifest_content)
|
|
95
95
|
|
|
96
96
|
# Compute summary fields
|
|
97
97
|
summary = {}
|
|
@@ -123,7 +123,7 @@ module Walheim
|
|
|
123
123
|
def find_resource_names
|
|
124
124
|
base_dir = File.join(@data_dir, self.class.kind_info[:plural])
|
|
125
125
|
Dir.entries(base_dir)
|
|
126
|
-
.select { |entry| File.directory?(File.join(base_dir, entry)) && !entry.start_with?(
|
|
126
|
+
.select { |entry| File.directory?(File.join(base_dir, entry)) && !entry.start_with?(".") }
|
|
127
127
|
.select { |entry| File.exist?(File.join(base_dir, entry, manifest_filename)) }
|
|
128
128
|
.sort
|
|
129
129
|
end
|