Class: MrMurano::Gateway::Device

Inherits:
GweBase
  • Object
show all
Defined in:
lib/MrMurano/Gateway.rb

Overview

Talking to the devices on a Gateway

Constant Summary collapse

DEVICE_AUTH_TYPES =

Create a device with given Identity

i[
  certificate
  password
  token
  csr
].freeze

Constants included from SolutionId

SolutionId::INVALID_API_ID, SolutionId::UNEXPECTED_TYPE_OR_ERROR_MSG

Constants included from Verbose

Verbose::TABULARIZE_DATA_FORMAT_ERROR

Constants included from AccountBase

AccountBase::LOGIN_ADVICE, AccountBase::LOGIN_NOTICE

Instance Attribute Summary

Attributes included from SolutionId

#api_id, #sid, #valid_api_id

Instance Method Summary collapse

Methods inherited from GweBase

#endpoint, #info

Methods included from SyncAllowed

#download_item_allowed, #remove_item_allowed, #removelocal_item_allowed, #sync_item_allowed, #upload_item_allowed

Methods included from SolutionId

#affirm_valid, #api_id?, #endpoint, #init_api_id!, #valid_api_id?

Methods included from Verbose

ask_yes_no, #ask_yes_no, #assert, assert, cmd_confirm_delete!, #cmd_confirm_delete!, debug, #debug, dump_file_json, dump_file_plain, dump_file_yaml, #dump_output_file, #error, error, #error_file_format!, fancy_ticks, #fancy_ticks, #load_file_json, #load_file_plain, #load_file_yaml, #load_input_file, outf, #outf, #outformat_engine, #pluralize?, pluralize?, #prepare_hash_csv, #read_hashf!, #tabularize, tabularize, verbose, #verbose, warning, #warning, #whirly_interject, whirly_interject, #whirly_linger, whirly_linger, #whirly_msg, whirly_msg, #whirly_pause, whirly_pause, #whirly_start, whirly_start, #whirly_stop, whirly_stop, #whirly_unpause, whirly_unpause

Methods included from AccountBase

#add_headers, #ask_for_password!, #ask_for_user!, #cfg_clear_user_and_business, #credentials_reset, #get, #invalidate_token, #login_info, #logout, #must_prompt_if_logged_off!, #token, #token_reset, #verify_cfg_auth!, #verify_cfg_auth_persist, #verify_cfg_auth_scheme!, #verify_cfg_auth_ttl, #verify_set, warn_configfile_env_maybe

Methods included from Http

#add_headers, #curldebug, curldebug_after, curldebug_elapsed, curldebug_log, #delete, #endpoint, #get, #host, #http, #http_reset, #isJSON, #json_opts, #patch, #post, #postf, #put, #showHttpError, #user, #workit, #workit_response

Constructor Details

#initializeDevice

Returns a new instance of Device.



379
380
381
382
# File 'lib/MrMurano/Gateway.rb', line 379

def initialize
  super
  @uriparts << :identity
end

Instance Method Details

#activate(identifier) ⇒ Object

Call the device Activation URI.

Only useful durring debugging of devices.

Parameters:

  • identifier (String)

    Who to activate.



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
536
537
538
539
# File 'lib/MrMurano/Gateway.rb', line 504

def activate(identifier)
  info = GweBase.new.info
  raise "Gateway info not found for #{identifier}" if info.nil?
  fqdn = info[:fqdn]
  debug "Found FQDN: #{fqdn}"
  fqdn = "#{@api_id}.m2.exosite.io" if fqdn.nil?

  uri = URI("https://#{fqdn}/provision/activate")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.start
  request = Net::HTTP::Post.new(uri)
  request.form_data = {
    vendor: @api_id,
    model: @api_id,
    sn: identifier,
  }
  request['User-Agent'] = "MrMurano/#{MrMurano::VERSION}"
  request['Authorization'] = nil
  request.content_type = 'application/x-www-form-urlencoded; charset=utf-8'
  curldebug(request)

  whirly_start('Activating Device...')
  response = http.request(request)
  whirly_stop

  case response
  when Net::HTTPSuccess
    return response.body
  when Net::HTTPConflict
    error('The specified device is already activated.')
    exit 1
  else
    showHttpError(request, response)
  end
end

#enable(id, opts = nil) ⇒ Object Also known as: whitelist, create



432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
# File 'lib/MrMurano/Gateway.rb', line 432

def enable(id, opts=nil)
  opts = {} if opts.nil?
  props = { auth: {}, locked: false }
  # See: okami_api/api/swagger/swagger.yaml
  unless opts[:expire].nil?
    begin
      props[:auth][:expire] = Integer(opts[:expire])
    rescue ArgumentError
      # Callers should prevent this, so ugly raise is okay.
      raise ":expire option is not a valid number: #{fancy_ticks(opts[:expire])}"
    end
  end
  unless opts[:type].nil?
    opts[:type] = opts[:type].to_sym
    unless DEVICE_AUTH_TYPES.include?(opts[:type])
      complaint = ":type must be one of #{DEVICE_AUTH_TYPES.join('|')}"
      raise complaint
    end
    props[:auth][:type] = opts[:type]
  end
  unless opts[:key].nil?
    # 2018-07-10: (lb): I think the `read` feature is no longer used
    #   (no callers pass in a File object any more).
    props[:auth][:key] = opts[:key].is_a?(String) && opts[:key] || opts[:key].read
    props[:auth][:type] = :certificate if props[:auth][:type].nil?
  end
  whirly_start('Enabling Device...')
  putted = put("/#{CGI.escape(id.to_s)}", props)
  whirly_stop
  putted
end

#enable_batch(local, expire = nil) ⇒ void

This method returns an undefined value.

Create a bunch of devices at once

Parameters:

  • local (String, Pathname)

    CSV file of identifiers

  • expire (Number) (defaults to: nil)

    Expire time for all identities



470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
# File 'lib/MrMurano/Gateway.rb', line 470

def enable_batch(local, expire=nil)
  # Need to modify @uriparts for just this endpoint call.
  uriparts = @uriparts
  @uriparts[-1] = :identities
  uri = endpoint
  @uriparts = uriparts
  file = HTTP::FormData::File.new(local.to_s, content_type: 'text/csv')
  opts = {}
  opts[:identities] = file
  opts[:expire] = expire unless expire.nil?
  form = HTTP::FormData.create(**opts)
  req = Net::HTTP::Post.new(uri)
  add_headers(req)
  req.content_type = form.content_type
  req.content_length = form.content_length
  req.body = form.to_s
  whirly_start('Enabling Devices...')
  workit(req)
  whirly_stop
  nil
end

#fetch(id, _untainted = false) ⇒ Object

Get one device

Parameters:

  • id (String)

    The identity to fetch



411
412
413
# File 'lib/MrMurano/Gateway.rb', line 411

def fetch(id, _untainted=false)
  get("/#{CGI.escape(id.to_s)}")
end

#list(limit = nil, before = nil) ⇒ Object

All devices (pagination?)

Parameters:

  • limit (Number, String) (defaults to: nil)

    How many devices to return

  • before (Number, String) (defaults to: nil)

    timestamp for something. TODO: want offset.



387
388
389
390
391
392
393
394
395
396
397
# File 'lib/MrMurano/Gateway.rb', line 387

def list(limit=nil, before=nil)
  pr = {}
  pr[:limit] = limit unless limit.nil?
  pr[:before] = before unless before.nil?
  pr = nil if pr.empty?
  get('/', pr)
  # MAYBE/2017-08-17:
  #   ret = get('/', pr)
  #   return [] unless ret.is_a?(Array)
  #   sort_by_name(ret)
end

#lock(identifier) ⇒ Object



559
560
561
# File 'lib/MrMurano/Gateway.rb', line 559

def lock(identifier)
  patch("/#{CGI.escape(identifier.to_s)}", locked: true)
end

#query(args) ⇒ Object



399
400
401
402
403
404
405
406
407
# File 'lib/MrMurano/Gateway.rb', line 399

def query(args)
  # TODO: actually just part of list.
  # ?limit=#
  # ?before=<time stamp in ms>
  # ?status={whitelisted, provisioned, locked, devmode, reprovision}
  # ?identity=<pattern>
  # ?ipaddress=<pattern>
  # ?version=<pattern>
end

#read(identifier) ⇒ Object

Read the current state for a device

Parameters:

  • identifier (String)

    The identifier for the device to read.



553
554
555
556
557
# File 'lib/MrMurano/Gateway.rb', line 553

def read(identifier)
  # EXPLAIN/2017-08-23: Why not escape the ID?
  #   #{CGI.escape(identifier.to_s)}
  get("/#{identifier}/state")
end

#remove(identifier) ⇒ Object

Delete a device

Parameters:

  • identifier (String)

    Who to delete.



494
495
496
497
# File 'lib/MrMurano/Gateway.rb', line 494

def remove(identifier)
  return unless remove_item_allowed(identifier)
  delete("/#{CGI.escape(identifier.to_s)}")
end

#revoke(identifier) ⇒ Object



567
568
569
# File 'lib/MrMurano/Gateway.rb', line 567

def revoke(identifier)
  patch("/#{CGI.escape(identifier.to_s)}", auth: { expire: 0 })
end

#unlock(identifier) ⇒ Object



563
564
565
# File 'lib/MrMurano/Gateway.rb', line 563

def unlock(identifier)
  patch("/#{CGI.escape(identifier.to_s)}", locked: false)
end

#write(identifier, values) ⇒ Object

Write the set point for aliases on a device

Parameters:

  • identifier (String)

    The identifier for the device to write.

  • values (Hash)

    Aliases and the values to write.



544
545
546
547
548
549
# File 'lib/MrMurano/Gateway.rb', line 544

def write(identifier, values)
  debug "Will Write: #{values}"
  # EXPLAIN/2017-08-23: Why not escape the ID?
  #   #{CGI.escape(identifier.to_s)}
  patch("/#{identifier}/state", values)
end