Top Level Namespace

Defined Under Namespace

Modules: Commander, HashInit, MrMurano, Net Classes: CompletionContext, DeviceEnableCmd, ElementCmd, ExchangeCmd, Hash, HashDiggable, InitCmd, LogsCmd, OptionParser, OrderedHash, ServiceCmd, ServiceConsolidator, StatusCmd, TruthyFalsey

Constant Summary collapse

'No service links found'
MSG_BUSINESSES_NONE_FOUND =
'No businesses found'
MSG_SOLUTIONS_NONE_FOUND =
'No solutions found'
OptParse =
OptionParser

Instance Method Summary collapse

Instance Method Details

#any_application_pickers!(options) ⇒ Object



216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/MrMurano/commands/solution_picker.rb', line 216

def any_application_pickers!(options)
  num_ways = 0
  num_ways += 1 unless options.application_id.to_s.empty?
  num_ways += 1 unless options.application_name.to_s.empty?
  num_ways += 1 unless options.application.to_s.empty?
  #if num_ways > 1
  #  MrMurano::Verbose.error(
  #    'Please specify only one of: --application, --application-id, or --application-name'
  #  )
  #  exit 1
  #end
  num_ways > 0
end

#any_business_pickers?(options) ⇒ Boolean

Returns:

  • (Boolean)


140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/MrMurano/commands/business.rb', line 140

def any_business_pickers?(options)
  num_ways = 0
  num_ways += 1 unless options.business_id.to_s.empty?
  num_ways += 1 unless options.business_name.to_s.empty?
  num_ways += 1 unless options.business.to_s.empty?
  #if num_ways > 1
  #  MrMurano::Verbose.error(
  #    'Please specify only one of: --business, --business-id, or --business-name'
  #  )
  #  exit 1
  #end
  num_ways > 0
end

#any_product_pickers!(options) ⇒ Object



230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/MrMurano/commands/solution_picker.rb', line 230

def any_product_pickers!(options)
  num_ways = 0
  num_ways += 1 unless options.product_id.to_s.empty?
  num_ways += 1 unless options.product_name.to_s.empty?
  num_ways += 1 unless options.product.to_s.empty?
  #if num_ways > 1
  #  MrMurano::Verbose.error(
  #    'Please specify only one of: --product, --product-id, or --product-name'
  #  )
  #  exit 1
  #end
  num_ways > 0
end

#any_solution_pickers!(options) ⇒ Object



212
213
214
# File 'lib/MrMurano/commands/solution_picker.rb', line 212

def any_solution_pickers!(options)
  any_application_pickers!(options) || any_product_pickers!(options)
end

#args_opts_parse_token(args, options) ⇒ Object



65
66
67
# File 'lib/MrMurano/commands/token.rb', line 65

def args_opts_parse_token(args, options)
  args_opts_parse_token_maybe(args, options, must: false)
end

#args_opts_parse_token!(args, options) ⇒ Object



69
70
71
# File 'lib/MrMurano/commands/token.rb', line 69

def args_opts_parse_token!(args, options)
  args_opts_parse_token_maybe(args, options, must: true)
end

#args_opts_parse_token_maybe(args, options, must: false) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/MrMurano/commands/token.rb', line 32

def args_opts_parse_token_maybe(args, options, must: false)
  n_specified = 0
  token = args.shift
  n_specified += 1 unless token.nil?
  if options.value
    token = options.value
    n_specified += 1
  end
  if options.from_env
    token = ENV['MURANO_TOKEN']
    if token.to_s.empty?
      MrMurano::Verbose.error(%(--from-env specified but MURANO_TOKEN is empty))
      exit 1
    end
    n_specified += 1
  end
  if n_specified > 1
    MrMurano::Verbose.error(%(Please specify only one token, --token, or --from-env))
    exit 1
  end
  token = nil if token.to_s.empty?
  if must && token.nil?
    MrMurano::Verbose.error(%(Please specify a token!))
    unless ENV['MURANO_TOKEN'].to_s.empty?
      MrMurano::Verbose.warning(
        %(If you want to use MURANO_TOKEN, specify --from-env)
      )
    end
    exit 1
  end
  token
end

#args_parse_and_cfg_set(args, cfg_key) ⇒ Object



15
16
17
18
19
# File 'lib/MrMurano/commands/token.rb', line 15

def args_parse_and_cfg_set(args, cfg_key)
  value = args.shift
  value = $cfg[cfg_key] if value.to_s.empty?
  $cfg[cfg_key] = value
end

#args_parse_user_host_pair(args) ⇒ Object



21
22
23
24
25
# File 'lib/MrMurano/commands/token.rb', line 21

def args_parse_user_host_pair(args)
  username = args_parse_and_cfg_set(args, 'user.name')
  host = args_parse_and_cfg_set(args, 'net.host')
  [username, host]
end

#args_sole_token_maybe(args) ⇒ Object



27
28
29
30
# File 'lib/MrMurano/commands/token.rb', line 27

def args_sole_token_maybe(args)
  return unless args.length == 1
  args.shift if MrMurano::HttpAuthed.instance.token_looks_legit(args[0])
end

#argv_push_option(switch) ⇒ Object



38
39
40
41
42
# File 'lib/MrMurano/Commander-Entry.rb', line 38

def argv_push_option(switch)
  # Put the --switch before the -- positional argument delimiter, if any.
  i_positional = ARGV.index('--') || -1
  ARGV.insert(i_positional, switch)
end

#business_find_or_ask!(acc, options) ⇒ Object

*** Business actions helpers




365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/MrMurano/commands/business.rb', line 365

def business_find_or_ask!(acc, options)
  #any_business_pickers?(options)

  match_bid = options.business_id
  match_name = options.business_name
  match_fuzzy = options.business

  if !match_bid.to_s.empty? || !match_name.to_s.empty? || !match_fuzzy.to_s.empty?
    biz = business_locate!(acc, match_bid, match_name, match_fuzzy)
  elsif !options.find_only
    ask_user = options.refresh
    biz = business_from_config unless ask_user
    biz = businesses_ask_which(acc) if biz.nil?
  end
  biz
end

#business_from_configObject



401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
# File 'lib/MrMurano/commands/business.rb', line 401

def business_from_config
  # By default, creating a new Business object loads its ID from the config.
  biz = MrMurano::Business.new
  unless biz.bid.empty?
    # Verify that the business exists.
    MrMurano::Verbose.whirly_start('Verifying Business...')
    biz.overview
    MrMurano::Verbose.whirly_stop
    if biz.valid?
      say("Found Business #{biz.pretty_name_and_id}")
    else
      biz_bid = MrMurano::Verbose.fancy_ticks(biz.bid)
      say("Could not find Business #{biz_bid} referenced in the config")
    end
    puts('')
  end
  biz if biz.valid?
end

#business_locate!(acc, match_bid, match_name, match_fuzzy) ⇒ Object



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/MrMurano/commands/business.rb', line 382

def business_locate!(acc, match_bid, match_name, match_fuzzy)
  biz = nil
  bizes = acc.businesses(bid: match_bid, name: match_name, fuzzy: match_fuzzy)
  if bizes.count == 1
    biz = bizes.first
    say("Found business #{biz.pretty_name_and_id}")
    puts('')
  elsif bizes.count > 1
    acc.error('More than one matching business was found. Please be more specific.')
    exit(1)
  else
    acc.error('No matching business was found. Please try again.')
    #say('Please visit Exosite.com to view your account and to create a business:')
    #say("  #{MrMurano::SIGN_UP_URL}")
    exit(1)
  end
  biz
end

#businesses_ask_which(acc) ⇒ Object



420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/MrMurano/commands/business.rb', line 420

def businesses_ask_which(acc)
  biz = nil
  bizes = acc.businesses

  if bizes.count == 1
    biz = bizes.first
    say("This user has one business. Using #{biz.pretty_name_and_id}")
  elsif bizes.count.zero?
    MrMurano::Verbose.warning('This user has not created any businesses.')
    say('Please log on to exosite.com to create a free account. Visit:')
    say("  #{MrMurano::SIGN_UP_URL}")
    exit 3
  else
    choose do |menu|
      menu.prompt = 'Please select the Business to use:'
      menu.flow = :columns_across
      menu.list_option = list_option_override(bizes)
      bizes.sort_by(&:name).each do |choice|
        menu.choice(choice.name) do
          biz = choice
        end
      end
    end
  end
  puts('')
  biz
end

#cmd_add_solntype_pickers(cmd, exclude_all: false) ⇒ Object

*** For some commands: let user restrict to specific solution –type.




21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/MrMurano/commands/solution_picker.rb', line 21

def cmd_add_solntype_pickers(cmd, exclude_all: false)
  # 2017-07-26 (landonb): HA! The --type option can get masked by aliases.
  # For instance, if the option is required ("--type TYPE"), then
  #   murano domain --type product
  # fails, because the "domain product" alias steals the --type argument,
  # so the parser exits, complaining that --type is missing an argument!
  # This, however, works:
  #   murano domain --type=product
  # as does
  #   murano domain -t product
  # To work around this, make the argument optional ("--type [TYPE]") and
  # then do some extra processing later to check for this special case.
  allowed_types = MrMurano::Business::ALLOWED_TYPES.dup
  allowed_types += [:all] unless exclude_all
  allowed_types.map!(&:to_s).sort!
  default = exclude_all && 'application' || 'all'
  cmd.option(
    '--type [TYPE]',
    allowed_types,
    %(Apply to solution(s) of type [#{allowed_types.join('|')}] (default: #{default}))
  )
end

#cmd_business_find_and_output(args, options) ⇒ Object



448
449
450
451
452
453
454
455
456
457
# File 'lib/MrMurano/commands/business.rb', line 448

def cmd_business_find_and_output(args, options)
  cmd_verify_args_and_id_or_name!(args, options)
  acc = MrMurano::Account.new
  bizz = cmd_business_find_businesses(acc, args, options)
  if bizz.empty? && !options.idonly
    MrMurano::Verbose.error(MSG_BUSINESSES_NONE_FOUND)
    exit 0
  end
  cmd_business_output_businesses(acc, bizz, options)
end

#cmd_business_find_businesses(acc, args, options) ⇒ Object



459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
# File 'lib/MrMurano/commands/business.rb', line 459

def cmd_business_find_businesses(acc, args, options)
  bid = []
  name = []
  fuzzy = []

  if args.any?
    flattened = args.map { |cell| cell.split(',') }.flatten
    if options.id
      bid += flattened
    elsif options.name
      name += flattened
    else
      fuzzy += flattened
    end
  end

  if any_business_pickers?(options)
    if options.business_id
      bid += [options.business_id]
    elsif options.business_name
      name += [options.business_name]
    elsif options.business
      fuzzy += [options.business]
    end
  end

  MrMurano::Verbose.whirly_start 'Looking for businesses...'
  bizz = acc.businesses(
    bid: bid,
    name: name,
    fuzzy: fuzzy,
    detailed: options.detailed,
    networks: options.network
  )
  MrMurano::Verbose.whirly_stop

  bizz
end

#cmd_business_header_and_bizz(bizz, options) ⇒ Object



498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
# File 'lib/MrMurano/commands/business.rb', line 498

def cmd_business_header_and_bizz(bizz, options)
  if options.idonly
    headers = %i[bizid]
    bizz = bizz.map(&:bizid)
  elsif options.brief
    #headers = %i[bizid role name]
    #bizz = bizz.map { |biz| [biz.bizid, biz.role, biz.name] }
    headers = %i[bizid name]
    bizz = bizz.map { |biz| [biz.bizid, biz.name] }
  else
    # 2017-08-16: There are only 3 keys: bizid, role, and name.
    headers = (bizz[0] && bizz[0].meta.keys) || []
    headers.sort_by! do |hdr|
      case hdr
      when :bizid
        0
      when :name
        1
      when :tier
        2
      when :contact
        3
      when :email
        4
      when :role
        5
      when :network_relationship
        6
      when :network_name
        7
      else
        8
      end
    end
    bizz = bizz.map { |biz| headers.map { |key| biz.meta[key] } }
  end
  [headers, bizz]
end

#cmd_business_members_header(members) ⇒ Object



556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
# File 'lib/MrMurano/commands/business.rb', line 556

def cmd_business_members_header(members)
  # (lb): Skip: :membership, which is just the bizid and role
  #   regurgitated (and it's also deprecated).
  culled = members.dup.each { |member| member.delete(:membership) }

  # Sort by role, then email.
  culled.sort_by! { |member| [member[:role], member[:email]] }

  headers = (culled[0] && culled[0].keys) || []
  headers.sort_by! do |hdr|
    case hdr
    when :role
      0
    when :email
      1
    when :name
      2
    when :pending
      3
    else
      4
    end
  end
  culled = culled.map { |member| headers.map { |key| member[key] } }

  [headers, culled]
end

#cmd_business_output_businesses(acc, bizz, options) ⇒ Object



537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
# File 'lib/MrMurano/commands/business.rb', line 537

def cmd_business_output_businesses(acc, bizz, options)
  headers, bizz = cmd_business_header_and_bizz(bizz, options)
  io = File.open(options.output, 'w') if options.output
  acc.outf(bizz, io) do |dd, ios|
    if options.idonly
      ios.puts dd.join(' ')
    else
      acc.tabularize(
        {
          headers: headers.map(&:to_s),
          rows: dd,
        },
        ios,
      )
    end
  end
  io.close unless io.nil?
end

#cmd_business_output_members(acc, members, options) ⇒ Object



584
585
586
587
588
589
590
591
592
593
594
595
596
597
# File 'lib/MrMurano/commands/business.rb', line 584

def cmd_business_output_members(acc, members, options)
  headers, members = cmd_business_members_header(members)
  io = File.open(options.output, 'w') if options.output
  acc.outf(members, io) do |dd, ios|
    acc.tabularize(
      {
        headers: headers.map(&:to_s),
        rows: dd,
      },
      ios,
    )
  end
  io.close unless io.nil?
end

#cmd_defaults_id_and_name(options) ⇒ Object



120
121
122
123
124
# File 'lib/MrMurano/commands/business.rb', line 120

def cmd_defaults_id_and_name(options)
  return if options.id.nil? || options.name.nil?
  MrMurano::Verbose.error('Please specify only --id or --name but not both')
  exit 1
end

#cmd_defaults_solntype_pickers(options, default = :all) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/MrMurano/commands/solution_picker.rb', line 44

def cmd_defaults_solntype_pickers(options, default=:all)
  cmd_defaults_type_kludge(options)

  if options.type.to_s.empty?
    options.type = default.to_sym
  else
    options.type = options.type.to_sym
  end
end

#cmd_defaults_syncable_pickers(options) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/MrMurano/commands/status.rb', line 32

def cmd_defaults_syncable_pickers(options)
  # Weird. The options is a Commander::Command::Options object, but
  # options.class says nil! Also, you cannot index properties or
  # even options.send('opt'). But we can just twiddle the raw table.
  table = options.__hash__
  MrMurano::SyncRoot.instance.each_alias_sym do |pseudo, pseudo_sym, name, name_sym|
    unless table[pseudo_sym].nil?
      if table[name_sym].nil?
        table[name_sym] = table[pseudo_sym]
      elsif table[name_sym] != table[pseudo_sym]
        MrMurano::Verbose.warning("Ignoring --#{pseudo} because --#{name} also specified")
      end
    end
  end
end

#cmd_defaults_type_kludge(options) ⇒ Object



54
55
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
# File 'lib/MrMurano/commands/solution_picker.rb', line 54

def cmd_defaults_type_kludge(options)
  # KLUDGE/2017-07-26: Work around rb-commander peculiarity.
  # The alias_command steals the --type parameter, e.g.,
  #   murano domain --type product
  # is interpreted using the "domain product" alias,
  # so the command that's parsed is actually
  #   murano domain --type product --type
  # and the latter --type wins [which is something that [lb]
  # really dislikes about rb-commander, is that it does not
  # support more than one of the same options, taking only the
  # last one's argument].
  next_posit = 1
  ARGV.each do |arg|
    if arg.casecmp('--type').zero?
      if ARGV.length == next_posit
        MrMurano::Verbose.error('missing argument: --type')
        exit 1
      else
        # NOTE: Commander treats arguments case sensitively, but not --options.
        possible_type = ARGV[next_posit].to_sym
        if MrMurano::Business::ALLOWED_TYPES.include?(possible_type)
          options.type = possible_type
        else
          MrMurano::Verbose.error("unrecognized --type: #{possible_type}")
          exit 1
        end
        break
      end
    end
    next_posit += 1
  end
  return unless options.type == true
  MrMurano::Verbose.error('missing argument: --type')
  exit 1
end

#cmd_option_application_pickers(cmd) ⇒ Object

*** For murano init: specify –business, –application, and/or –product.




200
201
202
203
204
# File 'lib/MrMurano/commands/solution_picker.rb', line 200

def cmd_option_application_pickers(cmd)
  cmd.option('--application-id ID', String, %(ID of Application to use))
  cmd.option('--application-name NAME', String, %(Name of Application to use))
  cmd.option('--application APPLICATION', String, %(Name or ID of Application to use))
end

#cmd_option_business_pickers(c) ⇒ Object



134
135
136
137
138
# File 'lib/MrMurano/commands/business.rb', line 134

def cmd_option_business_pickers(c)
  c.option('--business-id ID', String, %(ID of Murano Business to use))
  c.option('--business-name NAME', String, %(Name of Murano Business to use))
  c.option('--business BUSINESS', String, %(Name or ID of Murano Business to use))
end

#cmd_option_product_pickers(cmd) ⇒ Object



206
207
208
209
210
# File 'lib/MrMurano/commands/solution_picker.rb', line 206

def cmd_option_product_pickers(cmd)
  cmd.option('--product-id ID', String, %(ID of Product to use))
  cmd.option('--product-name NAME', String, %(Name of Product to use))
  cmd.option('--product PRODUCT', String, %(Name or ID of Product to use))
end

#cmd_option_syncable_pickers(cmd) ⇒ Object

Load options to control which things to sync



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/MrMurano/commands/status.rb', line 15

def cmd_option_syncable_pickers(cmd)
  MrMurano::SyncRoot.instance.each_option do |short, long, desc|
    cmd.option short, long, Inflecto.pluralize(desc)
  end
  MrMurano::SyncRoot.instance.each_alias_opt do |long, desc|
    cmd.option long, Inflecto.pluralize(desc)
  end

  cmd.option(
    '--[no-]nesting',
    %(Disable support for arranging Lua modules hierarchically)
  ) do |nestation|
    # This is only called if user specifies switch.
    $cfg['modules.no-nesting'] = !nestation
  end
end

#cmd_option_token_options(c) ⇒ Object



73
74
75
76
77
# File 'lib/MrMurano/commands/token.rb', line 73

def cmd_option_token_options(c)
  # We cannot use --token, because it's already a global_option.
  c.option '--value TOKEN', String, %(The token to use)
  c.option '--from-env', %(Use token in MURANO_TOKEN)
end

#cmd_options_add_id_and_name(c) ⇒ Object



115
116
117
118
# File 'lib/MrMurano/commands/business.rb', line 115

def cmd_options_add_id_and_name(c)
  c.option '--id', 'Specified argument is an ID'
  c.option '--name', 'Specified argument is a name'
end

#cmd_solution_del_get_names_and_ids!(biz, args, options) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/MrMurano/commands/solution.rb', line 145

def cmd_solution_del_get_names_and_ids!(biz, args, options)
  nmorids = []
  if args.count.zero?
    if any_solution_pickers!(options)
      exit_cmd_not_recursive!(options)
    elsif !options.recursive
      MrMurano::Verbose.error(
        'Please specify the name or ID of the solution to delete, or use --recursive.'
      )
      exit 1
    end
  else
    exit_cmd_not_recursive!(options)
  end
  solz = must_fetch_solutions!(options, args, biz)
  solz.each do |sol|
    nmorids += [
      [sol.api_id, "#{MrMurano::Verbose.fancy_ticks(sol.name)} <#{sol.api_id}>", sol],
    ]
  end
  nmorids
end

#cmd_solution_find_add_options(c) ⇒ Object

*** List and Find solutions.




287
288
289
290
291
292
# File 'lib/MrMurano/commands/solution.rb', line 287

def cmd_solution_find_add_options(c)
  c.option '--idonly', 'Only return the ids'
  c.option '--[no-]brief', 'Show fewer fields: only Solution ID and domain'
  c.option '--[no-]all', 'Find all Solutions in Business, not just Project'
  c.option '-o', '--output FILE', %(Download to file instead of STDOUT)
end

#cmd_solution_find_and_output(args, options) ⇒ Object



376
377
378
379
380
381
382
383
384
385
386
# File 'lib/MrMurano/commands/solution.rb', line 376

def cmd_solution_find_and_output(args, options)
  cmd_verify_args_and_id_or_name!(args, options)
  biz = MrMurano::Business.new
  biz.must_business_id!
  solz = cmd_solution_find_solutions(biz, args, options)
  if solz.empty? && !options.idonly
    MrMurano::Verbose.error(MSG_SOLUTIONS_NONE_FOUND)
    exit 0
  end
  cmd_solution_output_solutions(biz, solz, options)
end

#cmd_solution_find_solutions(biz, args, options) ⇒ Object



388
389
390
# File 'lib/MrMurano/commands/solution.rb', line 388

def cmd_solution_find_solutions(biz, args, options)
  must_fetch_solutions!(options, args, biz, exitnonzero: true)
end

#cmd_solution_output_solutions(biz, solz, options) ⇒ Object



392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
# File 'lib/MrMurano/commands/solution.rb', line 392

def cmd_solution_output_solutions(biz, solz, options)
  if options.idonly
    headers = %i[api_id]
    solz = solz.map { |row| [row.api_id] }
  elsif options.brief
    #headers = %i[api_id domain]
    #solz = solz.map { |row| [row.api_id, row.domain] }
    headers = %i[api_id sid domain name]
    solz = solz.map { |row| [row.api_id, row.sid, row.domain, row.name] }
  else
    headers = (solz.first && solz.first.meta || {}).keys
    #headers.delete(:sid) if headers.include?(:api_id) && headers.include?(:sid)
    headers.sort_by! do |hdr|
      case hdr
      when :bizid
        0
      when :type
        1
      when :api_id
        2
      when :sid
        3
      when :domain
        4
      when :name
        5
      else
        6
      end
    end
    solz = solz.map { |row| headers.map { |hdr| row.meta[hdr] } }
  end

  io = File.open(options.output, 'w') if options.output
  biz.outf(solz, io) do |dd, ios|
    if options.idonly
      ios.puts(dd.join(' '))
    else
      biz.tabularize(
        {
          headers: headers.map(&:to_s),
          rows: dd,
        },
        ios,
      )
    end
  end
  io.close unless io.nil?
end

#cmd_table_output_add_options(c) ⇒ Object

*** Common business command options




105
106
107
108
109
110
111
112
113
# File 'lib/MrMurano/commands/business.rb', line 105

def cmd_table_output_add_options(c)
  # MAYBE/2017-08-15: Rename to --id-only.
  c.option '--idonly', 'Only return the IDs'
  c.option '--[no-]brief', 'Show fewer fields: show only IDs and names'
  c.option '--network', 'Fetch and show Business Network details'
  c.option '--detailed', 'Fetch and show all Business information'
  # MAYBE/2017-08-17: Move -o option to globals.rb and apply to all commands.
  c.option '-o', '--output FILE', 'Download to file instead of STDOUT'
end

#cmd_verify_args_and_id_or_name!(args, options) ⇒ Object



126
127
128
129
130
131
132
# File 'lib/MrMurano/commands/business.rb', line 126

def cmd_verify_args_and_id_or_name!(args, options)
  return unless args.none? && (options.id || options.name)
  MrMurano::Verbose.error(
    'The --id and --name options only apply when specifying a business name or ID.'
  )
  exit 1
end

#elevate_hash(hsh) ⇒ Hash

Take a hash or something (a Commander::Command::Options) and return a hash

Parameters:

  • hsh (Hash, Commander::Command::Options)

    Thing we want to be a Hash

Returns:

  • (Hash)

    an actual Hash with default value of false



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/MrMurano/hash.rb', line 156

def elevate_hash(hsh)
  # Commander::Command::Options stripped all of the methods from parent
  # objects. I have not nice thoughts about that.
  begin
    hsh = hsh.__hash__
  # rubocop:disable Lint/HandleExceptions: Do not suppress exceptions.
  rescue NoMethodError
    # swallow this.
  end
  # build a hash where the default is 'false' instead of 'nil'
  Hash.new(false).merge(Hash.transform_keys_to_symbols(hsh))
  # 2017-09-07: Note that after elevate_hash, the Hash returns
  #   false on unknown keys. This is because of the parameter to
  #   new: Hash.new(false). Unknown keys would return nil before,
  #   but after, they return false. E.g.,
  #
  #   (byeebug) options
  #   {:delete=>false, :create=>true, :update=>false}
  #   (byeebug) options[:fff]
  #   false
  #   (byeebug) options[:fff] = nil
  #   nil
  #   (byeebug) options[:fff]
  #   nil
  #   (byeebug) options[:fffd]
  #   false
  #   (byeebug) options
  #   {:delete=>false, :create=>true, :update=>false, :fff=>nil}
end

#ensure_array(item) ⇒ Object

Array-ify the given item, if not already an array.

NOTE/2017-08-15: This fcn. is not hash-related, but this file is the

closest we've got to a generic utility method dumping ground.


191
192
193
194
195
196
197
198
199
# File 'lib/MrMurano/hash.rb', line 191

def ensure_array(item)
  if item.nil?
    []
  elsif !item.is_a?(Array)
    [item]
  else
    item
  end
end

#exit_cmd_not_recursive!(options) ⇒ Object



168
169
170
171
172
173
174
# File 'lib/MrMurano/commands/solution.rb', line 168

def exit_cmd_not_recursive!(options)
  return unless options.recursive
  MrMurano::Verbose.error(
    'The --recursive option does not apply when specifing solution IDs or names.'
  )
  exit 1
end

#get_soln_searches(sol_type, options) ⇒ Object



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/MrMurano/commands/solution_picker.rb', line 348

def get_soln_searches(sol_type, options)
  sol_type = sol_type.to_sym
  sol_srchs = []
  # E.g., :application_id
  if options["#{sol_type}_id".to_sym]
    app_ids = options["#{sol_type}_id".to_sym].split(',')
    app_ids.each { |api_id| sol_srchs += [[sol_type, :api_id, api_id]] }
  end
  # E.g., :application_name
  if options["#{sol_type}_name".to_sym]
    app_names = options["#{sol_type}_name".to_sym].split(',')
    app_names.each { |name| sol_srchs += [[sol_type, :name, name]] }
  end
  # E.g., :application
  if options[sol_type]
    app_finds = options[sol_type].split(',')
    app_finds.each { |term| sol_srchs += [[sol_type, :term, term]] }
  end
  sol_srchs
end

#get_two_solutions!(sol_a_id = nil, sol_b_id = nil, **options) ⇒ Object

For more on the ** doublesplat, and the **_ starsnake, see:

https://flushentitypacket.github.io/ruby/2015/03/31/ruby-keyword-arguments-the-double-splat-and-starsnake.html

“Basically, _ is Ruby’s variable name for storing values you don’t need.” Ruby 2.0 and above. I don’t think we support 1.x…



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/MrMurano/commands/solution_picker.rb', line 299

def get_two_solutions!(sol_a_id=nil, sol_b_id=nil, **options)
  app_srchs = []
  prd_srchs = []

  #app_srchs += [[:application, :api_id, sol_a_id]] unless sol_a_id.to_s.empty?
  #prd_srchs += [[:product, :api_id, sol_b_id]] unless sol_b_id.to_s.empty?
  app_srchs += [[nil, :api_id, sol_a_id]] unless sol_a_id.to_s.empty?
  prd_srchs += [[nil, :api_id, sol_b_id]] unless sol_b_id.to_s.empty?

  app_srchs += get_soln_searches(:application, options)
  prd_srchs += get_soln_searches(:product, options)

  if app_srchs.length.zero? && prd_srchs.length < 2
    # TEST/2017-08-16: Clear application.id and test.
    app_srchs = [[:application, :api_id, $cfg['application.id']]]
  end
  if prd_srchs.length.zero? && app_srchs.length < 2
    # TEST/2017-08-16: Clear product.id and test.
    prd_srchs = [[:product, :api_id, $cfg['product.id']]]
  end

  sol_srchs = app_srchs + prd_srchs

  if sol_srchs.length > 2
    MrMurano::Verbose.error('too many solutions specified: specify 2 solutions')
    exit 1
  end

  biz = MrMurano::Business.new
  solz = []
  sol_srchs.each do |type, desc, value|
    sol_opts = {}
    case desc
    when :api_id
      sol_opts[:match_api_id] = value
    when :name
      sol_opts[:match_name] = value
    when :term
      sol_opts[:match_fuzzy] = value
    else
      raise false
    end
    sol = solution_find_or_create(**sol_opts, biz: biz, type: type)
    solz += [sol]
  end

  solz
end


149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
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
243
244
# File 'lib/MrMurano/commands/link.rb', line 149

def link_solutions(sol_a, sol_b, options)
  warn_on_conflict = options[:warn_on_conflict] || false
  verbose = options[:verbose] || false

  if sol_a.nil? || sol_a.api_id.to_s.empty? || sol_b.nil? || sol_b.api_id.to_s.empty?
    msg = 'Missing Solution(s) (Applications or Products): Nothing to link'
    if warn_on_conflict
      sercfg.warning msg
    else
      say(msg)
    end
    return
  end

  if sol_a.is_a?(MrMurano::Product) && sol_b.is_a?(MrMurano::Application)
    # If the order is backwards, Murano will return
    #   Net::HTTPFailedDependency/424 "No such Service XXX"
    tmp = sol_a
    sol_a = sol_b
    sol_b = tmp
    # MAYBE/2017-08-16: Are there plans for linking other types of things?
    #   What about Application to Application, or Product to Product?
  end

  # Get services for solution to which being linked (application),
  # and look for linkee (product) service.
  sercfg = MrMurano::ServiceConfig.new(sol_a.api_id)
  MrMurano::Verbose.whirly_msg 'Fetching services...'
  scfgs = sercfg.search(sol_b.api_id)
  svc_cfg_exists = scfgs.any?
  MrMurano::Verbose.whirly_stop

  # Create the service configuration.
  unless svc_cfg_exists
    MrMurano::Verbose.whirly_msg 'Linking solutions...'
    # Call Murano.
    _ret = sercfg.create(sol_b.api_id, sol_b.name) do |request, http|
      response = http.request(request)
      MrMurano::Verbose.whirly_stop
      if response.is_a?(Net::HTTPSuccess)
        say("Linked #{sol_b.quoted_name} to #{sol_a.quoted_name}")
      elsif response.is_a?(Net::HTTPConflict)
        svc_cfg_exists = true
      else
        resp_msg = MrMurano::Verbose.fancy_ticks(Rainbow(response.message).underline)
        MrMurano::Verbose.error("Unable to link solutions: #{resp_msg}")
        sercfg.showHttpError(request, response)
      end
    end
  end
  if svc_cfg_exists
    msg = 'Solutions already linked'
    if warn_on_conflict
      sercfg.warning msg
    else
      say(msg)
    end
  end
  puts '' if verbose

  # Get event handlers for application, and look for product event handler.
  MrMurano::Verbose.whirly_msg 'Fetching handlers...'
  evthlr = MrMurano::EventHandlerSolnApp.new(sol_a.api_id)
  hdlrs = evthlr.search(sol_b.api_id)
  evt_hlr_exists = hdlrs.any?
  MrMurano::Verbose.whirly_stop

  # Create the event handler, using a simple script,
  # like the web UI does (yeti yeti spaghetti).
  unless evt_hlr_exists
    MrMurano::Verbose.whirly_msg 'Setting default event handler...'
    # Call Murano.
    evthlr.default_event_script(sol_b.api_id) do |request, http|
      response = http.request(request)
      MrMurano::Verbose.whirly_stop
      if response.is_a?(Net::HTTPSuccess)
        say('Created default event handler')
      elsif response.is_a?(Net::HTTPConflict)
        evt_hlr_exists = true
      else
        resp_msg = MrMurano::Verbose.fancy_ticks(Rainbow(response.message).underline)
        MrMurano::Verbose.error("Failed to create default event handler: #{resp_msg}")
        evthlr.showHttpError(request, response)
      end
    end
  end
  if evt_hlr_exists
    msg = 'Event handler already created'
    if warn_on_conflict
      sercfg.warning msg
    else
      say(msg)
    end
  end
  puts '' if verbose
end

#list_option_override(bizes_or_solz) ⇒ Object

*** HighLine Bug Workaround




18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/MrMurano/commands/business.rb', line 18

def list_option_override(bizes_or_solz)
  # The Highline library has a bug where if the terminal is not as wide as
  # text being displayed in a list of options it will attempt to divide by 0
  # and crash. In Highline's source (version 1.7.10) 'lib/highline.rb', see
  # the block from lines 465 to 500. The specific error occurs on line 479
  # when the 'option' variable is calculated to a default value of 0 when
  # 'limit' is less than 'max_length' on line 472.
  # Link: https://github.com/JEG2/highline/blob/1-7-stable/lib/highline.rb
  obj_with_largest_name = bizes_or_solz.max_by { |obj| obj.name.length }
  max_obj_name_length = obj_with_largest_name.name.length

  # (lb): Prevent HighLine from crashing on divide-by-zero by specifying
  # list_option explicitly. These two lines fix the HighLine code by
  # ensuring the option value -- used as a denominator -- is nonzero.
  # See ll. 471-2:
  #   https://github.com/JEG2/highline/blob/1-7-stable/lib/highline.rb#L471
  # Note, too, that wrap_at is set by a different library, rb-commander, at:
  #   https://github.com/exosite/murano-cli-commander/blob/master/lib/commander/methods.rb#L8
  limit = $terminal.wrap_at || 80
  [1, (limit + 2) / (max_obj_name_length + 2)].max
end

#migrations_dirObject

***



73
74
75
# File 'lib/MrMurano/commands/postgresql.rb', line 73

def migrations_dir
  File.join($cfg['location.base'], ($cfg['postgresql.migrations_dir'] || ''))
end

#must_be_nonempty_sql!(sqls, mgrt_path = nil) ⇒ Object



77
78
79
80
81
82
83
84
85
# File 'lib/MrMurano/commands/postgresql.rb', line 77

def must_be_nonempty_sql!(sqls, mgrt_path=nil)
  return unless sqls.to_s.empty?
  if mgrt_path
    MrMurano::Verbose.error("SQL file is empty: #{mgrt_path}")
  else
    MrMurano::Verbose.error('No SQL!')
  end
  exit 1
end

#must_business_network!(business_network) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/MrMurano/commands/network.rb', line 59

def must_business_network!(business_network)
  return if !business_network.nil? && !business_network[:name].nil?
  if business_network.nil?
    MrMurano::Verbose.error(
      'Error getting business network.'
    )
  elsif business_network[:name].nil?
    MrMurano::Verbose.error(
      'Business network is not configured.'
    )
  else
    MrMurano::Verbose.error(
      'Error with business network.'
    )
  end
  exit 1
end

#must_fetch_solutions!(options, args = [], biz = nil, exitnonzero: false) ⇒ Object

Get a list of solutions under the business.

  • Optionally filter by –type: in the command block, call cmd_add_solntype_pickers, and then in the action block, call cmd_defaults_solntype_pickers, and then call this method.

  • Optional restrict to just solutions in the current project.



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/MrMurano/commands/solution_picker.rb', line 95

def must_fetch_solutions!(options, args=[], biz=nil, exitnonzero: false)
  solz = []

  if biz.nil?
    biz = MrMurano::Business.new
    biz.must_business_id!
  end
  if args.any?
    #raise 'Cannot use options.all and solution pickers' unless options.all.nil?
    flattened = args.map { |cell| cell.split(',') }.flatten
    api_id = []
    name = []
    fuzzy = []
    if options.id
      api_id = flattened
    elsif options.name
      name = flattened
    else
      fuzzy = flattened
    end
    solz += solution_get_solutions(
      biz, options.type, api_id: api_id, name: name, fuzzy: fuzzy
    )
  end

  if any_solution_pickers!(options)
    #raise 'Cannot use options.all and solution pickers' unless options.all.nil?
    #
    # MAYBE: DRY this code. Rather than copy-paste-find-replace block of code.
    #   See also: any_business_pickers?
    #
    api_id = []
    name = []
    fuzzy = []
    if options.application_id
      api_id = [options.application_id]
    elsif options.application_name
      name = [options.application_name]
    elsif options.application
      fuzzy = [options.application]
    end
    if !api_id.empty? || !name.empty? || !fuzzy.empty?
      solz += solution_get_solutions(
        biz, :application, api_id: api_id, name: name, fuzzy: fuzzy
      )
    end
    #
    api_id = []
    name = []
    fuzzy = []
    if options.product_id
      api_id = [options.product_id]
    elsif options.product_name
      name = [options.product_name]
    elsif options.product
      fuzzy = [options.product]
    end
    if !api_id.empty? || !name.empty? || !fuzzy.empty?
      solz += solution_get_solutions(
        biz, :product, api_id: api_id, name: name, fuzzy: fuzzy
      )
    end
    #
  end

  if args.none? && !any_solution_pickers!(options)
    if !options.all
      if %i[all application].include?(options.type) && $cfg['application.id']
        solz += solution_get_solutions(
          biz, :application, api_id: $cfg['application.id']
        )
      end
      if %i[all product].include?(options.type) && $cfg['product.id']
        solz += solution_get_solutions(
          biz, :product, api_id: $cfg['product.id']
        )
      end
    else
      solz += solution_get_solutions(biz, options.type)
    end
  end

  culled = {}
  solz.select! do |sol|
    if culled[sol.api_id]
      false
    else
      culled[sol.api_id] = true
      true
    end
  end

  if solz.empty?
    MrMurano::Verbose.error(MSG_SOLUTIONS_NONE_FOUND)
    exit exitnonzero && 1 || 0
  end

  biz.sort_solutions!(solz)

  solz
end

#must_have_value!(value) ⇒ Object



113
114
115
116
117
# File 'lib/MrMurano/commands/keystore.rb', line 113

def must_have_value!(value)
  return unless value.nil?
  MrMurano::Verbose.warning('Missing value')
  exit 1
end

#ordered_hash(dict) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/MrMurano/hash.rb', line 138

def ordered_hash(dict)
  ohash = OrderedHash.new
  dict.keys.sort.each do |key|
    value = dict[key]
    if value.is_a? Hash
      ohash[key] = ordered_hash(value)
    else
      ohash[key] = value
    end
  end
  ohash
end

#OrderedHash(*a, &b) ⇒ Object

class OrderedHash



198
199
200
# File 'lib/MrMurano/orderedhash.rb', line 198

def OrderedHash(*a, &b)
  OrderedHash.new(*a, &b)
end

#postgresql_migrations_helpObject



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/MrMurano/commands/postgresql.rb', line 16

def postgresql_migrations_help
  %(
To view the current migration version, run:

  #{progname} postgresql migrations version

To view the path of the migration directory, run:

  #{progname} postgresql migrations directory
  ).strip
end

#prognameObject



12
13
14
# File 'lib/MrMurano/commands/postgresql.rb', line 12

def progname
  File.basename($PROGRAM_NAME)
end

#show_business_networkObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/MrMurano/commands/network.rb', line 44

def show_business_network
  biz = MrMurano::Business.new
  biz.must_business_id!
  MrMurano::Verbose.whirly_start(
    'Checking for configured business network...'
  )
  business_network = biz.get_business_network(biz.bid)
  MrMurano::Verbose.whirly_stop

  must_business_network!(business_network)
  puts('Network Name: ' + business_network[:name])
  puts('Child Business Tier: ' + business_network[:tier][:id])
  puts('Child Business Price: ' + business_network[:tier][:price].to_s)
end

#solution_ask_for_name(sol_model) ⇒ Object



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/MrMurano/commands/solution_picker.rb', line 258

def solution_ask_for_name(sol_model)
  solname = ''
  while solname == ''
    solname = ask("Enter the #{sol_model.type_name} name [leave blank to skip]: ")
    puts ''
    if solname == ''
      confirmed = ask(
        Rainbow("Really skip the #{sol_model.type_name}").bright.underline + '? [Y/n] '
      )
      if confirmed == '' || TruthyFalsey.new(confirmed).truthy?
        puts ''
        solname = nil
      end
    else
      # Try setting the name on the dummy solution; warn if fails, and keep looping.
      begin
        # Test sol.name_validate_regex.
        sol_model.set_name!(solname)
      rescue MrMurano::ConfigError => _err
        say(sol_model.name_validate_help)
        # keep looping
        solname = ''
      end
    end
  end
  solname
rescue EOFError
  # E.g., the user pressed Ctrl-D.
  #   "error: The input stream is exhausted."
  MrMurano::Verbose.error('murano out!')
  exit 2
end

#solution_delete(name_or_id, use_sol: nil, type: :all, yes: false) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/MrMurano/commands/solution.rb', line 199

def solution_delete(name_or_id, use_sol: nil, type: :all, yes: false)
  biz = MrMurano::Business.new
  biz.must_business_id!

  if name_or_id == '*'
    return unless biz.cmd_confirm_delete!(
      'all solutions', yes, 'abort!'
    ) do |confirmed|
      confirmed
    end
    name_or_id = ''
  end

  if !use_sol.nil?
    solz = [use_sol]
  else
    MrMurano::Verbose.whirly_start('Looking for solutions...')
    solz = biz.solutions(type: type)
    # This used to use Hash.value? to see if the name exactly matches
    # any key's value. But we should be able to stick to using name.
    #  (E.g., it used to call sol.meta.value?(name_or_id), but this
    #   would return true if, say, sol.meta[:any_key] equaled name_or_id.)
    unless name_or_id.empty?
      solz.select! do |sol|
        sol.api_id == name_or_id \
          || sol.name == name_or_id \
          || sol.domain =~ /#{Regexp.escape(name_or_id)}\./i
      end
    end
    MrMurano::Verbose.whirly_stop
    if $cfg['tool.debug']
      say 'Matches found:'
      biz.outf(solz)
    end
  end

  n_deleted = 0
  n_faulted = 0
  if solz.empty?
    if !name_or_id.empty?
      name_or_id_q = MrMurano::Verbose.fancy_ticks(name_or_id)
      MrMurano::Verbose.error("No solution matching #{name_or_id_q} found")
    else
      MrMurano::Verbose.error(MSG_SOLUTIONS_NONE_FOUND)
    end
    exit 1
  else
    # Solutions of different types can have the same name, so warning that
    # more than one solution was found when searching by name is not valid.
    #unless name_or_id.empty? or solz.length == 1
    #  MrMurano::Verbose.warning(
    #    "Unexpected number of solutions: found #{solz.length} for #{name_or_id} but expected 1"
    #  )
    #end
    MrMurano::Verbose.whirly_start('Deleting solutions...')
    solz.each do |sol|
      ret = biz.delete_solution(sol.sid)
      if ret.nil? || (!ret.is_a?(Hash) && !ret.empty?)
        MrMurano::Verbose.error("Delete failed: #{ret}")
        n_faulted += 1
      else
        n_deleted += 1
        # Clear the ID from the config.
        MrMurano::Config::CFG_SOLUTION_ID_KEYS.each do |keyn|
          $cfg.set(keyn, nil) if $cfg[keyn] == sol.api_id
        end
      end
    end
    MrMurano::Verbose.whirly_stop
  end

  [n_deleted, n_faulted]
end

#solution_delete_report(n_deleted, n_faulted) ⇒ Object



273
274
275
276
277
278
279
280
281
282
# File 'lib/MrMurano/commands/solution.rb', line 273

def solution_delete_report(n_deleted, n_faulted)
  unless n_deleted.nil? || n_deleted.zero?
    # FIXME: Should this use 'say' or 'outf'?
    inflection = MrMurano::Verbose.pluralize?('solution', n_deleted)
    say "Deleted #{n_deleted} #{inflection}"
  end
  return if n_faulted.nil? || n_faulted.zero?
  inflection = MrMurano::Verbose.pluralize?('solution', n_faulted)
  MrMurano::Verbose.error("Failed to delete #{n_faulted} #{inflection}")
end

#solution_factory_reset(sol) ⇒ Object



369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/MrMurano/Solution.rb', line 369

def solution_factory_reset(sol)
  new_sol = nil
  if sol.is_a? MrMurano::Solution
    unless sol.meta[:template].to_s.empty?
      begin
        clazz = Object.const_get("MrMurano::#{sol.meta[:template].capitalize}")
        new_sol = clazz.new(sol)
        new_sol.meta = sol.meta
      rescue NameError => _err
        MrMurano::Verbose.warning(
          "Unrecognized solution :template value: #{sol.meta[:template]}"
        )
      end
    end
  end
  new_sol || sol
end

#solution_find_or_create(biz: nil, type: nil, **options) ⇒ Object



369
370
371
372
373
374
375
376
# File 'lib/MrMurano/commands/solution_picker.rb', line 369

def solution_find_or_create(biz: nil, type: nil, **options)
  type = options[:type] if type.nil?
  raise 'You mush specify the :type of solution' if type.nil? && options[:create_ok]
  options[:match_enable] = true if options[:match_enable].nil?
  finder = MrMurano::InteractiveSolutionFinder.new(options)
  model = biz.solution_from_type!(type)
  finder.find_or_create(model)
end

#solution_get_solutions(biz, type, api_id: nil, name: nil, fuzzy: nil) ⇒ Object



244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/MrMurano/commands/solution_picker.rb', line 244

def solution_get_solutions(biz, type, api_id: nil, name: nil, fuzzy: nil)
  if type == :all
    inflection = 'solutions'
  else
    inflection = MrMurano::Verbose.pluralize?(type.to_s, 0)
  end
  MrMurano::Verbose.whirly_start("Fetching #{inflection}...")
  solz = biz.solutions(
    type: type, api_id: api_id, name: name, fuzzy: fuzzy, invalidate: false
  )
  MrMurano::Verbose.whirly_stop
  solz
end

#sync_add_options(cmd, locale) ⇒ Object



13
14
15
16
17
18
# File 'lib/MrMurano/commands/sync.rb', line 13

def sync_add_options(cmd, locale)
  cmd.option '--[no-]delete', %(Don't delete things from #{locale})
  cmd.option '--[no-]create', %(Don't create things on #{locale})
  cmd.option '--[no-]update', %(Don't update things on #{locale})
  cmd.option '--ignore-errors', %(Don't die on sync errors)
end

#syncdown_files(options, args = []) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/MrMurano/commands/sync.rb', line 20

def syncdown_files(options, args=[])
  args = [] if args.nil?
  num_synced = 0
  MrMurano::SyncRoot.instance.each_filtered(options) do |_name, _type, klass, desc|
    MrMurano::Verbose.whirly_msg "Syncing #{Inflecto.pluralize(desc)}..."
    sol = klass.new
    num_synced += sol.syncdown(options, args)
  end
  MrMurano::Verbose.whirly_stop
  num_synced
end

#syncup_files(options, args = []) ⇒ Object



79
80
81
82
83
84
85
86
# File 'lib/MrMurano/commands/sync.rb', line 79

def syncup_files(options, args=[])
  MrMurano::SyncRoot.instance.each_filtered(options) do |_name, _type, klass, desc|
    MrMurano::Verbose.whirly_msg "Syncing #{Inflecto.pluralize(desc)}..."
    sol = klass.new
    sol.syncup(options, args)
  end
  MrMurano::Verbose.whirly_stop
end


246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/MrMurano/commands/link.rb', line 246

def unlink_solutions(sol_a, sol_b)
  sercfg = MrMurano::ServiceConfig.new(sol_a.api_id)
  MrMurano::Verbose.whirly_msg 'Fetching services...'
  #scfgs = sercfg.list('?select=service,id,solution_id,script_key,alias')
  scfgs = sercfg.search(sol_b.api_id)
  MrMurano::Verbose.whirly_stop

  if scfgs.length > 1
    sercfg.warning "More than one service configuration found: #{scfgs}"
  elsif scfgs.empty?
    sercfg.warning 'No matching service configurations found; nothing to unlink'
    #exit 1
  end

  sercfg.debug "Found #{scfgs.length} configurations to unlink from the Application"

  scfgs.each do |svc|
    sercfg.debug "Deleting #{svc[:service]} : #{svc[:script_key]} : #{svc[:id]}"
    ret = sercfg.remove(svc[:id])
    if !ret.nil?
      msg = "Unlinked #{MrMurano::Verbose.fancy_ticks(svc[:script_key])}"
      msg += " from #{sol_a.quoted_name}" unless sol_a.quoted_name.to_s.empty?
      say(msg)
    else
      sercfg.warning "Failed to unlink #{MrMurano::Verbose.fancy_ticks(svc[:id])}"
    end
  end

  MrMurano::Verbose.whirly_msg 'Fetching handlers...'
  evthlr = MrMurano::EventHandlerSolnApp.new(sol_a.api_id)
  hdlrs = evthlr.search(sol_b.api_id)
  #evt_hlr_exists = hdlrs.any?
  MrMurano::Verbose.whirly_stop

  if hdlrs.length > 1
    sercfg.warning "More than one event handler found: #{hdlrs}"
  elsif hdlrs.empty?
    sercfg.warning 'No matching event handlers found; nothing to delete'
    #exit 1
  end

  hdlrs.each do |evth|
    evthlr.debug "Deleting #{evth[:service]} : #{evth[:alias]} : #{evth[:id]}"
    ret = evthlr.remove(evth[:id])
    if !ret.nil?
      msg = "Removed #{MrMurano::Verbose.fancy_ticks(evth[:alias])}"
      msg += " from #{sol_a.quoted_name}" unless sol_a.quoted_name.to_s.empty?
      say(msg)
    else
      svc_id = MrMurano::Verbose.fancy_ticks(svc[:id])
      MrMurano::Verbose.warning "Failed to remove handler #{svc_id}"
    end
  end
end

#wire_cmd_device_enableObject



413
414
415
416
# File 'lib/MrMurano/commands/devices.rb', line 413

def wire_cmd_device_enable
  device_enable_cmd = DeviceEnableCmd.new
  command('device enable') { |cmd| device_enable_cmd.command_init(cmd) }
end

#wire_cmd_elementObject



602
603
604
605
606
607
608
609
610
611
# File 'lib/MrMurano/commands/element.rb', line 602

def wire_cmd_element
  element_cmd = ElementCmd.new

  command(:element) { |cmd| element_cmd.command_element_help(cmd) }

  command('element show') { |cmd| element_cmd.command_element_show(cmd) }

  command('element edit') { |cmd| element_cmd.command_element_edit(cmd) }
  alias_command 'element update', 'element edit'
end

#wire_cmd_exchangeObject



266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/MrMurano/commands/exchange.rb', line 266

def wire_cmd_exchange
  exchange_cmd = ExchangeCmd.new

  command(:exchange) { |cmd| exchange_cmd.command_exchange_help(cmd) }

  command('exchange list') { |cmd| exchange_cmd.command_exchange_list(cmd) }
  alias_command 'exchange list available', 'exchange list', '--no-added'
  alias_command 'exchange list purchased', 'exchange list', '--added'

  command('exchange purchase') { |cmd| exchange_cmd.command_exchange_purchase(cmd) }
  alias_command 'exchange add', 'exchange purchase'
  alias_command 'exchange buy', 'exchange purchase'
end

#wire_cmd_initObject



423
424
425
426
# File 'lib/MrMurano/commands/init.rb', line 423

def wire_cmd_init
  init_cmd = InitCmd.new
  command(:init) { |cmd| init_cmd.command_init(cmd) }
end

#wire_cmd_logsObject



682
683
684
685
686
687
688
689
# File 'lib/MrMurano/commands/logs.rb', line 682

def wire_cmd_logs
  logs_cmd = LogsCmd.new
  command(:logs) { |cmd| logs_cmd.command_logs(cmd) }
  alias_command 'logs application', 'logs', '--type', 'application'
  alias_command 'logs product', 'logs', '--type', 'product'
  alias_command 'application logs', 'logs', '--type', 'application'
  alias_command 'product logs', 'logs', '--type', 'product'
end

#wire_cmd_serviceObject



559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
# File 'lib/MrMurano/commands/service.rb', line 559

def wire_cmd_service
  service_cmd = ServiceCmd.new

  command(:service) { |cmd| service_cmd.command_service(cmd) }

  command('service add') { |cmd| service_cmd.command_service_add(cmd) }
  alias_command 'service create', 'service add'

  command('service delete') { |cmd| service_cmd.command_service_delete(cmd) }
  alias_command 'service remove', 'service delete'

  command('service get') { |cmd| service_cmd.command_service_get(cmd) }

  command('service list') { |cmd| service_cmd.command_service_list(cmd) }
  alias_command 'services list', 'service list'
  alias_command 'service list available', 'service list', '--hide-added'
  alias_command 'service list all', 'service list', '--show-all'
  alias_command 'service list full', 'service list', '--show-all', '--show-type', '--show-state', '--show-source', '--show-desc'
  alias_command 'service status', 'service list', '--only-added'
end

#wire_cmd_statusObject

StatusCmd



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/MrMurano/commands/status.rb', line 270

def wire_cmd_status
  status_cmd = StatusCmd.new

  command(:status) { |cmd| status_cmd.command_status(cmd) }
  alias_command(
    'diff', 'status', '--diff', '--no-grouped',
  )
  alias_command(
    'diff application', 'status', '--diff', '--no-grouped', '--type', 'application',
  )
  alias_command(
    'diff product', 'status', '--diff', '--no-grouped', '--type', 'product',
  )
  alias_command(
    'application diff', 'status', '--diff', '--no-grouped', '--type', 'application',
  )
  alias_command(
    'product diff', 'status', '--diff', '--no-grouped', '--type', 'product',
  )
end