walheim 0.1.2 → 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.
@@ -1,20 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../namespaced_resource'
4
- require_relative '../sync'
5
- require_relative '../handler_registry'
3
+ require_relative "../namespaced_resource"
4
+ require_relative "../sync"
5
+ require_relative "../handler_registry"
6
6
 
7
7
  module Resources
8
8
  class Apps < Walheim::NamespacedResource
9
- def initialize(namespaces_dir: 'namespaces')
10
- super
11
- @syncer = Walheim::Sync.new(namespaces_dir: namespaces_dir)
9
+ def initialize(data_dir: Dir.pwd)
10
+ super(data_dir: data_dir)
11
+ # Sync needs the full path to namespaces directory
12
+ @namespaces_dir = File.join(data_dir, "namespaces")
13
+ @syncer = Walheim::Sync.new(namespaces_dir: @namespaces_dir)
12
14
  end
13
15
 
14
16
  def self.kind_info
15
17
  {
16
- plural: 'apps',
17
- singular: 'app',
18
+ plural: "apps",
19
+ singular: "app",
18
20
  aliases: %w[application applications]
19
21
  }
20
22
  end
@@ -31,11 +33,11 @@ module Resources
31
33
  {
32
34
  image: lambda { |manifest|
33
35
  # Extract first service's image from compose spec
34
- manifest.dig('spec', 'compose', 'services')&.values&.first&.dig('image') || 'N/A'
36
+ manifest.dig("spec", "compose", "services")&.values&.first&.dig("image") || "N/A"
35
37
  },
36
38
  status: lambda { |_manifest|
37
39
  # Could check if app is running, for now just show 'Configured'
38
- 'Configured'
40
+ "Configured"
39
41
  }
40
42
  }
41
43
  end
@@ -44,32 +46,47 @@ module Resources
44
46
  # Start with base operations
45
47
  ops = super
46
48
 
49
+ namespace_opt = { type: :string, aliases: [ :n ], desc: "Target namespace", required: true }
50
+
47
51
  # Add apps-specific operations
48
52
  ops.merge({
49
53
  import: {
50
- description: 'Import docker-compose as Walheim App',
51
- usage: ['import app {name} -n {namespace} -f {docker-compose.yml}']
54
+ description: "Import docker-compose as Walheim App",
55
+ usage: [ "import app {name} -n {namespace} -f {docker-compose.yml}" ],
56
+ options: {
57
+ namespace: namespace_opt,
58
+ file: { type: :string, aliases: [ :f ], desc: "docker-compose.yml path", required: true }
59
+ }
52
60
  },
53
61
  start: {
54
- description: 'Compile, sync, and start app on host',
55
- usage: ['start app {name} -n {namespace}']
62
+ description: "Compile, sync, and start app on host",
63
+ usage: [ "start app {name} -n {namespace}" ],
64
+ options: { namespace: namespace_opt }
56
65
  },
57
66
  pause: {
58
- description: 'Stop app containers (keep files)',
59
- usage: ['pause app {name} -n {namespace}']
67
+ description: "Stop app containers (keep files)",
68
+ usage: [ "pause app {name} -n {namespace}" ],
69
+ options: { namespace: namespace_opt }
60
70
  },
61
71
  stop: {
62
- description: 'Stop app and remove files from host',
63
- usage: ['stop app {name} -n {namespace}']
72
+ description: "Stop app and remove files from host",
73
+ usage: [ "stop app {name} -n {namespace}" ],
74
+ options: { namespace: namespace_opt }
64
75
  },
65
76
  logs: {
66
- description: 'View logs from remote containers',
77
+ description: "View logs from remote containers",
67
78
  usage: [
68
- 'logs app {name} -n {namespace}',
69
- 'logs app {name} -n {namespace} --follow',
70
- 'logs app {name} -n {namespace} --tail 100',
71
- 'logs app {name} -n {namespace} --timestamps'
72
- ]
79
+ "logs app {name} -n {namespace}",
80
+ "logs app {name} -n {namespace} --follow",
81
+ "logs app {name} -n {namespace} --tail 100",
82
+ "logs app {name} -n {namespace} --timestamps"
83
+ ],
84
+ options: {
85
+ namespace: namespace_opt,
86
+ follow: { type: :boolean, desc: "Follow log output" },
87
+ tail: { type: :numeric, desc: "Number of lines from end" },
88
+ timestamps: { type: :boolean, desc: "Show timestamps" }
89
+ }
73
90
  }
74
91
  })
75
92
  end
@@ -86,14 +103,14 @@ module Resources
86
103
 
87
104
  # Convert docker-compose to Walheim App manifest
88
105
  app_manifest = {
89
- 'apiVersion' => 'walheim/v1alpha1',
90
- 'kind' => 'App',
91
- 'metadata' => {
92
- 'name' => name,
93
- 'namespace' => namespace
106
+ "apiVersion" => "walheim/v1alpha1",
107
+ "kind" => "App",
108
+ "metadata" => {
109
+ "name" => name,
110
+ "namespace" => namespace
94
111
  },
95
- 'spec' => {
96
- 'compose' => compose_manifest
112
+ "spec" => {
113
+ "compose" => compose_manifest
97
114
  }
98
115
  }
99
116
 
@@ -114,7 +131,7 @@ module Resources
114
131
  generate_compose_file(namespace, name, app_manifest)
115
132
 
116
133
  # Sync files to remote
117
- result = @syncer.sync(namespace: namespace, kind: 'apps', name: name)
134
+ result = @syncer.sync(namespace: namespace, kind: "apps", name: name)
118
135
 
119
136
  # Run docker compose up
120
137
  remote_host = result[:username] ? "#{result[:username]}@#{result[:hostname]}" : result[:hostname]
@@ -123,7 +140,7 @@ module Resources
123
140
  compose_result = system(ssh_command)
124
141
 
125
142
  unless compose_result
126
- warn 'Error: docker compose up failed'
143
+ warn "Error: docker compose up failed"
127
144
  exit 1
128
145
  end
129
146
 
@@ -133,8 +150,8 @@ module Resources
133
150
  def pause(namespace:, name:)
134
151
  # Get namespace config
135
152
  namespace_config = load_namespace_config(namespace)
136
- username = namespace_config['username']
137
- hostname = namespace_config['hostname']
153
+ username = namespace_config["username"]
154
+ hostname = namespace_config["hostname"]
138
155
 
139
156
  remote_host = username ? "#{username}@#{hostname}" : hostname
140
157
  remote_dir = "/data/walheim/apps/#{name}"
@@ -153,7 +170,7 @@ module Resources
153
170
  result = system(ssh_command)
154
171
 
155
172
  unless result
156
- warn 'Error: docker compose down failed'
173
+ warn "Error: docker compose down failed"
157
174
  exit 1
158
175
  end
159
176
 
@@ -166,8 +183,8 @@ module Resources
166
183
 
167
184
  # Then remove files from remote
168
185
  namespace_config = load_namespace_config(namespace)
169
- username = namespace_config['username']
170
- hostname = namespace_config['hostname']
186
+ username = namespace_config["username"]
187
+ hostname = namespace_config["hostname"]
171
188
 
172
189
  remote_host = username ? "#{username}@#{hostname}" : hostname
173
190
  remote_dir = "/data/walheim/apps/#{name}"
@@ -177,7 +194,7 @@ module Resources
177
194
  result = system(ssh_command)
178
195
 
179
196
  unless result
180
- warn 'Error: failed to remove remote files'
197
+ warn "Error: failed to remove remote files"
181
198
  exit 1
182
199
  end
183
200
 
@@ -187,8 +204,8 @@ module Resources
187
204
  def logs(namespace:, name:, follow: false, tail: nil, timestamps: false)
188
205
  # Get namespace config
189
206
  namespace_config = load_namespace_config(namespace)
190
- username = namespace_config['username']
191
- hostname = namespace_config['hostname']
207
+ username = namespace_config["username"]
208
+ hostname = namespace_config["hostname"]
192
209
 
193
210
  remote_host = username ? "#{username}@#{hostname}" : hostname
194
211
  remote_dir = "/data/walheim/apps/#{name}"
@@ -203,10 +220,10 @@ module Resources
203
220
  end
204
221
 
205
222
  # Build docker compose logs command with options
206
- logs_cmd = 'docker compose logs'
207
- logs_cmd += ' --follow' if follow
223
+ logs_cmd = "docker compose logs"
224
+ logs_cmd += " --follow" if follow
208
225
  logs_cmd += " --tail #{tail}" if tail
209
- logs_cmd += ' --timestamps' if timestamps
226
+ logs_cmd += " --timestamps" if timestamps
210
227
 
211
228
  # Execute logs command (this will stream output to terminal)
212
229
  ssh_command = "ssh #{remote_host} 'cd #{remote_dir} && #{logs_cmd}'"
@@ -219,12 +236,12 @@ module Resources
219
236
  private
220
237
 
221
238
  def load_app_manifest(namespace, name)
222
- app_dir = File.join(@namespaces_dir, namespace, 'apps', name)
223
- app_yaml_path = File.join(app_dir, '.app.yaml')
239
+ app_dir = File.join(@namespaces_dir, namespace, "apps", name)
240
+ app_yaml_path = File.join(app_dir, ".app.yaml")
224
241
 
225
242
  unless File.exist?(app_yaml_path)
226
243
  warn "Error: No app manifest found at #{app_yaml_path}"
227
- warn 'Use \'whctl import\' to convert docker-compose.yml to Walheim App format'
244
+ warn "Use 'whctl import' to convert docker-compose.yml to Walheim App format"
228
245
  exit 1
229
246
  end
230
247
 
@@ -234,58 +251,58 @@ module Resources
234
251
  validate_k8s_manifest(manifest, namespace, name)
235
252
 
236
253
  {
237
- metadata: manifest['metadata'],
238
- env_from: manifest['spec']['envFrom'] || [],
239
- env: manifest['spec']['env'] || [],
240
- compose: manifest['spec']['compose']
254
+ metadata: manifest["metadata"],
255
+ env_from: manifest["spec"]["envFrom"] || [],
256
+ env: manifest["spec"]["env"] || [],
257
+ compose: manifest["spec"]["compose"]
241
258
  }
242
259
  end
243
260
 
244
261
  def validate_k8s_manifest(manifest, namespace, name)
245
262
  # Check required top-level fields
246
- unless manifest['apiVersion'] == 'walheim/v1alpha1'
263
+ unless manifest["apiVersion"] == "walheim/v1alpha1"
247
264
  warn "Error: apiVersion must be 'walheim/v1alpha1', got '#{manifest['apiVersion']}'"
248
265
  exit 1
249
266
  end
250
267
 
251
- unless manifest['kind'] == 'App'
268
+ unless manifest["kind"] == "App"
252
269
  warn "Error: kind must be 'App', got '#{manifest['kind']}'"
253
270
  exit 1
254
271
  end
255
272
 
256
- unless manifest['metadata']
257
- warn 'Error: metadata is required'
273
+ unless manifest["metadata"]
274
+ warn "Error: metadata is required"
258
275
  exit 1
259
276
  end
260
277
 
261
- unless manifest['spec']
262
- warn 'Error: spec is required'
278
+ unless manifest["spec"]
279
+ warn "Error: spec is required"
263
280
  exit 1
264
281
  end
265
282
 
266
283
  # Check metadata fields
267
- metadata_name = manifest['metadata']['name']
284
+ metadata_name = manifest["metadata"]["name"]
268
285
  unless metadata_name == name
269
286
  warn "Error: metadata.name '#{metadata_name}' must match directory name '#{name}'"
270
287
  exit 1
271
288
  end
272
289
 
273
- metadata_namespace = manifest['metadata']['namespace']
290
+ metadata_namespace = manifest["metadata"]["namespace"]
274
291
  unless metadata_namespace == namespace
275
292
  warn "Error: metadata.namespace '#{metadata_namespace}' must match parent namespace '#{namespace}'"
276
293
  exit 1
277
294
  end
278
295
 
279
296
  # Check spec.compose exists
280
- return if manifest['spec']['compose']
297
+ return if manifest["spec"]["compose"]
281
298
 
282
- warn 'Error: spec.compose is required'
299
+ warn "Error: spec.compose is required"
283
300
  exit 1
284
301
  end
285
302
 
286
303
  def generate_compose_file(namespace, name, app_manifest)
287
- app_dir = File.join(@namespaces_dir, namespace, 'apps', name)
288
- compose_path = File.join(app_dir, 'docker-compose.yml')
304
+ app_dir = File.join(@namespaces_dir, namespace, "apps", name)
305
+ compose_path = File.join(app_dir, "docker-compose.yml")
289
306
 
290
307
  # Start with base compose content
291
308
  compose_content = deep_copy(app_manifest[:compose])
@@ -295,13 +312,13 @@ module Resources
295
312
 
296
313
  # Process envFrom and inject into compose (lower precedence)
297
314
  unless app_manifest[:env_from].empty?
298
- puts 'Processing envFrom...'
315
+ puts "Processing envFrom..."
299
316
  compose_content = inject_env_from(compose_content, app_manifest[:env_from], namespace)
300
317
  end
301
318
 
302
319
  # Process env and inject into compose (higher precedence)
303
320
  unless app_manifest[:env].empty?
304
- puts 'Processing env...'
321
+ puts "Processing env..."
305
322
  compose_content = inject_env(compose_content, app_manifest[:env])
306
323
  end
307
324
 
@@ -312,27 +329,29 @@ module Resources
312
329
 
313
330
  def inject_walheim_labels(compose, namespace, name)
314
331
  # Process each service and inject Walheim metadata labels
315
- compose['services']&.each do |service_name, service_config|
316
- service_config['labels'] ||= []
332
+ compose["services"]&.each_value do |service_config|
333
+ service_config["labels"] ||= []
317
334
 
318
335
  # Define Walheim metadata labels (stable labels only to avoid unnecessary restarts)
319
336
  walheim_labels = [
320
- 'walheim.managed=true',
337
+ "walheim.managed=true",
321
338
  "walheim.namespace=#{namespace}",
322
339
  "walheim.app=#{name}"
323
340
  ]
324
341
 
325
342
  # Inject labels (handle both array and hash formats)
326
- if service_config['labels'].is_a?(Array)
343
+ if service_config["labels"].is_a?(Array)
327
344
  # Remove any existing walheim.* labels first to avoid duplicates
328
- service_config['labels'].reject! { |label| label.to_s.start_with?('walheim.managed=', 'walheim.namespace=', 'walheim.app=') }
345
+ service_config["labels"].reject! do |label|
346
+ label.to_s.start_with?("walheim.managed=", "walheim.namespace=", "walheim.app=")
347
+ end
329
348
  # Add new labels
330
- service_config['labels'].concat(walheim_labels)
349
+ service_config["labels"].concat(walheim_labels)
331
350
  else
332
351
  # Hash format
333
- service_config['labels']['walheim.managed'] = 'true'
334
- service_config['labels']['walheim.namespace'] = namespace
335
- service_config['labels']['walheim.app'] = name
352
+ service_config["labels"]["walheim.managed"] = "true"
353
+ service_config["labels"]["walheim.namespace"] = namespace
354
+ service_config["labels"]["walheim.app"] = name
336
355
  end
337
356
  end
338
357
 
@@ -343,13 +362,13 @@ module Resources
343
362
  return compose if env_from_list.empty?
344
363
 
345
364
  # Process each service
346
- compose['services']&.each do |service_name, service_config|
347
- service_config['environment'] ||= {}
348
- service_config['labels'] ||= []
365
+ compose["services"]&.each do |service_name, service_config|
366
+ service_config["environment"] ||= {}
367
+ service_config["labels"] ||= []
349
368
 
350
369
  # Convert array-style to hash if needed
351
- if service_config['environment'].is_a?(Array)
352
- service_config['environment'] = array_env_to_hash(service_config['environment'])
370
+ if service_config["environment"].is_a?(Array)
371
+ service_config["environment"] = array_env_to_hash(service_config["environment"])
353
372
  end
354
373
 
355
374
  # Track total injected for this service
@@ -358,27 +377,27 @@ module Resources
358
377
  # Inject from each envFrom source
359
378
  env_from_list.each do |source|
360
379
  # Check if this service should receive injections from this source
361
- service_names = source['serviceNames']
380
+ service_names = source["serviceNames"]
362
381
  next if service_names && !service_names.empty? && !service_names.include?(service_name)
363
382
 
364
- if source['secretRef']
365
- secret_name = source['secretRef']['name']
366
- injected_keys = inject_from_secret(service_config['environment'], secret_name, namespace)
383
+ if source["secretRef"]
384
+ secret_name = source["secretRef"]["name"]
385
+ injected_keys = inject_from_secret(service_config["environment"], secret_name, namespace)
367
386
 
368
387
  # Add tracking label if any keys were injected
369
388
  if injected_keys.any?
370
- add_tracking_label(service_config['labels'], "walheim.injected-env.secret.#{secret_name}", injected_keys)
389
+ add_tracking_label(service_config["labels"], "walheim.injected-env.secret.#{secret_name}", injected_keys)
371
390
  puts " #{service_name}: Injected #{injected_keys.size} variable(s) from secret #{secret_name}: #{injected_keys.join(', ')}"
372
391
  end
373
392
 
374
393
  total_injected += injected_keys.size
375
- elsif source['configMapRef']
376
- configmap_name = source['configMapRef']['name']
377
- injected_keys = inject_from_configmap(service_config['environment'], configmap_name, namespace)
394
+ elsif source["configMapRef"]
395
+ configmap_name = source["configMapRef"]["name"]
396
+ injected_keys = inject_from_configmap(service_config["environment"], configmap_name, namespace)
378
397
 
379
398
  # Add tracking label if any keys were injected
380
399
  if injected_keys.any?
381
- add_tracking_label(service_config['labels'], "walheim.injected-env.configmap.#{configmap_name}",
400
+ add_tracking_label(service_config["labels"], "walheim.injected-env.configmap.#{configmap_name}",
382
401
  injected_keys)
383
402
  puts " #{service_name}: Injected #{injected_keys.size} variable(s) from configmap #{configmap_name}: #{injected_keys.join(', ')}"
384
403
  end
@@ -394,8 +413,8 @@ module Resources
394
413
  def array_env_to_hash(env_array)
395
414
  env_hash = {}
396
415
  env_array.each do |env_line|
397
- if env_line.include?('=')
398
- key, value = env_line.split('=', 2)
416
+ if env_line.include?("=")
417
+ key, value = env_line.split("=", 2)
399
418
  env_hash[key] = value
400
419
  elsif env_line.is_a?(Hash)
401
420
  env_hash.merge!(env_line)
@@ -435,7 +454,7 @@ module Resources
435
454
  end
436
455
 
437
456
  def add_tracking_label(labels, label_key, injected_keys)
438
- label_value = injected_keys.join(',')
457
+ label_value = injected_keys.join(",")
439
458
 
440
459
  # Add label (handle both array and hash formats)
441
460
  if labels.is_a?(Array)
@@ -449,13 +468,13 @@ module Resources
449
468
  return compose if env_list.empty?
450
469
 
451
470
  # Process each service
452
- compose['services']&.each do |service_name, service_config|
453
- service_config['environment'] ||= {}
454
- service_config['labels'] ||= []
471
+ compose["services"]&.each do |service_name, service_config|
472
+ service_config["environment"] ||= {}
473
+ service_config["labels"] ||= []
455
474
 
456
475
  # Convert array-style to hash if needed
457
- if service_config['environment'].is_a?(Array)
458
- service_config['environment'] = array_env_to_hash(service_config['environment'])
476
+ if service_config["environment"].is_a?(Array)
477
+ service_config["environment"] = array_env_to_hash(service_config["environment"])
459
478
  end
460
479
 
461
480
  # Track which keys were set by spec.env
@@ -464,23 +483,23 @@ module Resources
464
483
  # Process each env entry
465
484
  env_list.each do |env_entry|
466
485
  # Check if this service should receive this env var
467
- service_names = env_entry['serviceNames']
486
+ service_names = env_entry["serviceNames"]
468
487
  next if service_names && !service_names.empty? && !service_names.include?(service_name)
469
488
 
470
- var_name = env_entry['name']
471
- var_value = env_entry['value']
489
+ var_name = env_entry["name"]
490
+ var_value = env_entry["value"]
472
491
 
473
492
  # Perform variable substitution using current environment
474
- substituted_value = substitute_variables(var_value, service_config['environment'])
493
+ substituted_value = substitute_variables(var_value, service_config["environment"])
475
494
 
476
495
  # Always overwrite (highest precedence)
477
- service_config['environment'][var_name] = substituted_value
496
+ service_config["environment"][var_name] = substituted_value
478
497
  injected_keys << var_name
479
498
  end
480
499
 
481
500
  # Add tracking label if any keys were set
482
501
  if injected_keys.any?
483
- add_tracking_label(service_config['labels'], 'walheim.injected-env.override', injected_keys)
502
+ add_tracking_label(service_config["labels"], "walheim.injected-env.override", injected_keys)
484
503
  puts " #{service_name}: Set #{injected_keys.size} variable(s) from spec.env: #{injected_keys.join(', ')}"
485
504
  end
486
505
  end
@@ -498,9 +517,9 @@ module Resources
498
517
  end
499
518
 
500
519
  def load_configmap_data(namespace, configmap_name)
501
- require 'base64'
520
+ require "base64"
502
521
 
503
- configmap_path = File.join(@namespaces_dir, namespace, 'configmaps', configmap_name, 'configmap.yaml')
522
+ configmap_path = File.join(@namespaces_dir, namespace, "configmaps", configmap_name, "configmap.yaml")
504
523
 
505
524
  unless File.exist?(configmap_path)
506
525
  warn "Error: configmap '#{configmap_name}' not found at #{configmap_path}"
@@ -510,7 +529,7 @@ module Resources
510
529
  configmap = YAML.load_file(configmap_path)
511
530
 
512
531
  # Extract data (plaintext only for configmaps)
513
- configmap['data'] || {}
532
+ configmap["data"] || {}
514
533
  end
515
534
 
516
535
  def deep_copy(obj)
@@ -518,18 +537,18 @@ module Resources
518
537
  end
519
538
 
520
539
  def manifest_filename
521
- '.app.yaml'
540
+ ".app.yaml"
522
541
  end
523
542
 
524
543
  def validate_manifest(manifest, namespace, name)
525
- manifest_hash = YAML.load(manifest)
526
- validate_k8s_manifest(manifest_hash, namespace, name) if manifest_hash['kind'] == 'App'
544
+ manifest_hash = YAML.safe_load(manifest)
545
+ validate_k8s_manifest(manifest_hash, namespace, name) if manifest_hash["kind"] == "App"
527
546
  end
528
547
 
529
548
  def load_secret_data(namespace, secret_name)
530
- require 'base64'
549
+ require "base64"
531
550
 
532
- secret_path = File.join(@namespaces_dir, namespace, 'secrets', secret_name, 'secret.yaml')
551
+ secret_path = File.join(@namespaces_dir, namespace, "secrets", secret_name, "secret.yaml")
533
552
 
534
553
  unless File.exist?(secret_path)
535
554
  warn "Error: secret '#{secret_name}' not found at #{secret_path}"
@@ -539,8 +558,8 @@ module Resources
539
558
  secret = YAML.load_file(secret_path)
540
559
 
541
560
  # Extract data (base64-encoded) and stringData (plaintext)
542
- data = secret['data'] || {}
543
- string_data = secret['stringData'] || {}
561
+ data = secret["data"] || {}
562
+ string_data = secret["stringData"] || {}
544
563
 
545
564
  # Decode base64 data
546
565
  decoded_data = {}
@@ -553,7 +572,7 @@ module Resources
553
572
  end
554
573
 
555
574
  def load_namespace_config(namespace)
556
- config_path = File.join(@namespaces_dir, namespace, '.namespace.yaml')
575
+ config_path = File.join(@namespaces_dir, namespace, ".namespace.yaml")
557
576
 
558
577
  unless File.exist?(config_path)
559
578
  warn "Error: namespace config '#{config_path}' not found"
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../namespaced_resource'
4
- require_relative '../handler_registry'
3
+ require_relative "../namespaced_resource"
4
+ require_relative "../handler_registry"
5
5
 
6
6
  module Resources
7
7
  class ConfigMaps < Walheim::NamespacedResource
8
8
  def self.kind_info
9
9
  {
10
- plural: 'configmaps',
11
- singular: 'configmap',
12
- aliases: ['cm'] # Abbreviation
10
+ plural: "configmaps",
11
+ singular: "configmap",
12
+ aliases: [ "cm" ] # Abbreviation
13
13
  }
14
14
  end
15
15
 
@@ -24,7 +24,7 @@ module Resources
24
24
  def self.summary_fields
25
25
  {
26
26
  keys: lambda { |manifest|
27
- (manifest['data'] || {}).keys.join(', ')
27
+ (manifest["data"] || {}).keys.join(", ")
28
28
  }
29
29
  }
30
30
  end
@@ -32,7 +32,7 @@ module Resources
32
32
  private
33
33
 
34
34
  def manifest_filename
35
- 'configmap.yaml'
35
+ "configmap.yaml"
36
36
  end
37
37
  end
38
38
  end