diff --git a/lib/puppet/util/network_device/mikrotik/facts.rb b/lib/puppet/util/network_device/mikrotik/facts.rb index b52feeb..030ab6f 100644 --- a/lib/puppet/util/network_device/mikrotik/facts.rb +++ b/lib/puppet/util/network_device/mikrotik/facts.rb @@ -2,7 +2,7 @@ class Puppet::Util::NetworkDevice::Mikrotik::Facts attr_reader :transport - + def initialize(transport) @transport = transport end @@ -12,20 +12,65 @@ def connection end def retrieve - facts_raw = {} - system_resources = connection.get_reply("/system/resource/getall") - system_resources.each do |system_resource| + facts_raw = {} + Puppet.info("Getting device facts.") + system_resources = connection.get_reply("/system/resource/getall") + Puppet.debug("Got device facts: #{system_resources.inspect}") + system_resources.each do |system_resource| if system_resource.key?('!re') facts_raw = system_resource.reject { |k, v| ['!re', '.tag'].include? k } end end - + facts = {} facts_raw.each do |k, v| new_key = k.gsub(/-/, '_') facts[new_key] = v end - - facts + + facts.merge(get_other_facts) + end + + def get_other_facts + other_facts = { + 'osfamily' => 'Mikrotik', + 'os' => { + 'family' => 'Mikrotik', + 'name' => 'RouterOS' + } + } + other_facts['ec2_metadata'] = ec2_metadata if transport.include_ec2_facts? + other_facts + end + + def ec2_metadata + Puppet.info('Getting EC2 metadata facts from device.') + { + 'instance-id' => ec2('instance-id'), + 'instance-type' => ec2('instance-type'), + 'local-ipv4' => ec2('local-ipv4'), + 'mac' => ec2('mac'), + 'public-ipv4' => ec2('public-ipv4'), + 'placement' => { + 'availability-zone' => ec2('placement/availability-zone'), + }, + } + end + + def ec2(path) + params = { + 'url' => "http://169.254.169.254/latest/meta-data/#{path}", + 'mode' => 'http', + 'output' => 'user', + } + p_array = params.map { |k,v| "=#{k}=#{v}" } + Puppet.debug("Requested device fetch #{params.inspect}") + reply = connection.get_reply('/tool/fetch',*p_array) + Puppet.debug("Got response: #{reply.inspect}") + if result = reply.find_sentence('data') + result['data'] + else + nil + end end end \ No newline at end of file diff --git a/lib/puppet/util/network_device/transport/mikrotik.rb b/lib/puppet/util/network_device/transport/mikrotik.rb index 79c6f5a..e0e06db 100644 --- a/lib/puppet/util/network_device/transport/mikrotik.rb +++ b/lib/puppet/util/network_device/transport/mikrotik.rb @@ -9,13 +9,38 @@ class Puppet::Util::NetworkDevice::Transport::Mikrotik < Puppet::Util::NetworkDe def initialize(url, _options = {}) require 'uri' - + url_object = URI(url) - if (url_object.scheme == 'api') - @connection = MTik::Connection.new :host => url_object.host, :user => url_object.user, :pass => url_object.password, :unecrypted_plaintext => true, :conn_timeout => 10 - else - raise "The Mikrotik module currently only support API access. Use api:// in URL." - end + case url_object.scheme + when 'api' + @connection = MTik::Connection.new :host => url_object.host, :user => url_object.user, :pass => url_object.password, :unencrypted_plaintext => true, :conn_timeout => 10 + when 'file' + config = JSON.parse(File.read(url_object.path)) + + raise "When using an advanced config file, the 'host' option is required" unless config['host'] + + opts = { + host: config['host'], + user: config['user'], + pass: config['password'], + conn_timeout: 10, + use_ssl: config['use_ssl'], + }.compact! + + opts[:port] = config['port'].to_i if config['port'] + opts[:conn_timeout] = config['conn_timeout'].to_i if config['conn_timeout'] + opts[:cmd_timeout] = config['cmd_timeout'].to_i if config['cmd_timeout'] + opts[:unencrypted_plaintext] = config.has_key?('unencrypted_plaintext') ? config['unencrypted_plaintext'] : !config['use_ssl'] + + @connection = MTik::Connection.new(opts) + @include_ec2_facts = config['include_ec2_facts'] + else + raise "The Mikrotik module currently only support API access. Use either api:// in URL, or use file:// for advanced config from a separate JSON file." + end + end + + def include_ec2_facts? + !!@include_ec2_facts end end \ No newline at end of file