Class: Legate::CLI::AuthCredentialCommands

Inherits:
BaseCommand
  • Object
show all
Includes:
AuthCommandHelpers
Defined in:
lib/legate/cli/auth_commands.rb

Overview

Credential management subcommands

Instance Method Summary collapse

Methods included from AuthCommandHelpers

#auth_manager, #credential_type_description, #mask_sensitive_value, #print_header, #print_row, #scheme_type_description, #sensitive_field?

Methods inherited from BaseCommand

#tree

Instance Method Details

#create(name) ⇒ Object



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/legate/cli/auth_commands.rb', line 276

def create(name)
  cred_name = name.to_sym
  auth_type = options[:type].to_sym

  if auth_manager.get_credential(cred_name)
    puts ::CLI::UI.fmt("{{red:Credential already exists:}} #{name}")
    exit 1
  end

  attrs = { auth_type: auth_type }

  case auth_type
  when :api_key
    attrs[:api_key] = options[:api_key] || prompt_for('API Key')
  when :http_bearer
    attrs[:bearer_token] = options[:bearer_token] || prompt_for('Bearer Token')
  when :oauth2, :oidc
    attrs[:client_id] = options[:client_id] || prompt_for('Client ID')
    attrs[:client_secret] = options[:client_secret]
    attrs[:redirect_uri] = options[:redirect_uri] if options[:redirect_uri]
  when :service_account, :google_service_account
    attrs[:service_account_key] = if options[:service_account_key_file]
                                    File.read(options[:service_account_key_file])
                                  else
                                    options[:service_account_key] || prompt_for('Service Account Key JSON')
                                  end
  when :basic
    attrs[:username] = options[:username] || prompt_for('Username')
    attrs[:password] = options[:password] || prompt_for('Password')
  else
    puts ::CLI::UI.fmt("{{red:Unsupported credential type:}} #{auth_type}")
    exit 1
  end

  credential = Legate::Auth::Credential.new(**attrs)
  auth_manager.register_credential(credential, cred_name)
  puts ::CLI::UI.fmt("{{green:✓}} Credential '#{name}' created successfully")
rescue Legate::Auth::CredentialError => e
  puts ::CLI::UI.fmt("{{red:Invalid credential:}} #{e.message}")
  exit 1
end

#delete(name) ⇒ Object



320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/legate/cli/auth_commands.rb', line 320

def delete(name)
  cred_name = name.to_sym

  unless auth_manager.get_credential(cred_name)
    puts ::CLI::UI.fmt("{{red:Credential not found:}} #{name}")
    exit 1
  end

  # Check for dependent mappings
  url_mappings = auth_manager.instance_variable_get(:@url_mappings) || []
  dependent = url_mappings.select { |m| m[:credential_name] == cred_name }

  if dependent.any? && !options[:force]
    puts ::CLI::UI.fmt("{{red:Cannot delete}} - credential is used by #{dependent.size} URL mapping(s)")
    puts 'Use --force to delete anyway'
    exit 1
  end

  auth_manager.unregister_credential(cred_name)
  puts ::CLI::UI.fmt("{{green:✓}} Credential '#{name}' deleted")
end

#listObject



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/legate/cli/auth_commands.rb', line 215

def list
  credentials = auth_manager.instance_variable_get(:@credentials) || {}

  if credentials.empty?
    puts ::CLI::UI.fmt('{{yellow:No credentials registered.}}')
    return
  end

  print_header("Credentials (#{credentials.size})")
  puts

  credentials.each do |name, cred|
    puts ::CLI::UI.fmt("  {{bold:#{name}}} {{gray:(#{cred.auth_type})}}")

    # Show masked key info
    case cred.auth_type
    when :api_key
      puts "    API Key: #{mask_sensitive_value(cred[:api_key, resolve_env: false])}"
    when :http_bearer
      puts "    Token: #{mask_sensitive_value(cred[:bearer_token, resolve_env: false])}"
    when :oauth2, :oidc
      puts "    Client ID: #{cred[:client_id, resolve_env: false]}"
    when :service_account, :google_service_account
      puts '    Service Account Key: ********'
    end
    puts
  end
end

#show(name) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/legate/cli/auth_commands.rb', line 245

def show(name)
  credential = auth_manager.get_credential(name.to_sym)

  unless credential
    puts ::CLI::UI.fmt("{{red:Credential not found:}} #{name}")
    exit 1
  end

  print_header("Credential: #{name}")
  print_row('Type', credential_type_description(credential.auth_type))

  credential.to_h(resolve_env: false).each do |key, value|
    next if key == :auth_type

    display_value = sensitive_field?(key) ? mask_sensitive_value(value.to_s) : value
    print_row(key.to_s, display_value)
  end
end

#test(name) ⇒ Object



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/legate/cli/auth_commands.rb', line 344

def test(name)
  credential = auth_manager.get_credential(name.to_sym)

  unless credential
    puts ::CLI::UI.fmt("{{red:Credential not found:}} #{name}")
    exit 1
  end

  print_header("Testing credential: #{name}")
  puts

  # Basic validation
  begin
    credential.to_h(resolve_env: true)
    puts ::CLI::UI.fmt('  {{green:✓}} Basic validation passed')
  rescue Legate::Auth::EnvironmentVariableNotFoundError => e
    puts ::CLI::UI.fmt("  {{red:✗}} Environment variable not found: #{e.message}")
    exit 1
  end

  # Type-specific validation
  case credential.auth_type
  when :api_key
    api_key = credential[:api_key]
    if api_key && !api_key.empty?
      puts ::CLI::UI.fmt('  {{green:✓}} API key is present')
    else
      puts ::CLI::UI.fmt('  {{red:✗}} API key is empty')
    end
  when :oauth2, :oidc
    client_id = credential[:client_id]
    client_secret = credential[:client_secret]
    puts client_id ? ::CLI::UI.fmt('  {{green:✓}} Client ID is present') : ::CLI::UI.fmt('  {{red:✗}} Client ID missing')
    puts client_secret ? ::CLI::UI.fmt('  {{green:✓}} Client secret is present') : ::CLI::UI.fmt('  {{yellow:⚠}} Client secret not set')
  when :google_service_account
    begin
      key_data = credential[:service_account_key]
      parsed = JSON.parse(key_data)
      required = %w[type project_id private_key_id private_key client_email client_id]
      missing = required.reject { |f| parsed.key?(f) }
      if missing.empty?
        puts ::CLI::UI.fmt('  {{green:✓}} Service account key is valid JSON with all required fields')
      else
        puts ::CLI::UI.fmt("  {{red:✗}} Missing fields: #{missing.join(', ')}")
      end
    rescue JSON::ParserError
      puts ::CLI::UI.fmt('  {{red:✗}} Service account key is not valid JSON')
    end
  end

  puts
  puts ::CLI::UI.fmt('{{green:Test complete}}')
end