class Aio::Device::ParentDevice

Constants

Interface
InvalidInput
设备类型

attr_reader :device_type

Attributes

cmds_context[RW]

cmds_context = { “cmd_full_name” => [ {

              device_type_1 => klass1, 
              device_type_2 => klass2},
context ] }
cmds_useful[RW]

按cmd名称管理有用信息 Hash = { cmd_name => { :case => useful } }

device_info[RW]

设备的基本信息

device_name[RW]
manager_ip[RW]

管理IP

name[RW]
warning_klass[RW]

Warning信息模块

Public Class Methods

new() click to toggle source
# File lib/aio/core/device/parent_device.rb, line 47
def initialize
  self.cmds_context = {}
  self.device_name = ""
  self.cmds_useful = {}

  @warning_klass = Aio::Text::Warning.new
  @device_type = ""
  @device_info = {}
end

Public Instance Methods

add_cmd(klass_info) click to toggle source

增加cmd @Param klass_info 为Array

klass_info = ["maybe_device_type", cmd_klass]
# File lib/aio/core/device/parent_device.rb, line 81
def add_cmd(klass_info)
  maybe_device_type = klass_info[0]
  cmd_klass = klass_info[1]

  cmd_full_name = cmd_klass.cmd_full

  # 有可能已经有了其他设备类型的模块
  # 那么通过Hash的方式存储所有的模块
  cmds_context[cmd_full_name] ||= []
  cmds_context[cmd_full_name][0] ||= {}
  cmds_context[cmd_full_name][0][maybe_device_type] = cmd_klass
  return cmd_full_name
end
add_cmd_context_by_cmd_name(cmd_full_name, context) click to toggle source

两种用法: 在有klass的时候可以添加为完整cmds_context 当没有klass的话,也可以加。那么klass项为nil

# File lib/aio/core/device/parent_device.rb, line 98
def add_cmd_context_by_cmd_name(cmd_full_name, context)
  cmds_context[cmd_full_name] ||= []
  cmds_context[cmd_full_name][1] = context
end
add_cmd_context_by_klass(klass_info, context) click to toggle source

整合上面两个方法,成为一步

# File lib/aio/core/device/parent_device.rb, line 104
def add_cmd_context_by_klass(klass_info, context)
  cmd_full_name = add_cmd(klass_info)
  add_cmd_context_by_cmd_name(cmd_full_name, context)
  return cmds_context[cmd_full_name]
end
device_type() click to toggle source
# File lib/aio/core/device/parent_device.rb, line 65
def device_type
  if @device_type.empty?
    return "other"
  end

  @device_type
end
has_cmd?(cmd) click to toggle source

判断是否有cmd的信息

# File lib/aio/core/device/parent_device.rb, line 74
def has_cmd?(cmd)
  @cmds_useful.has_key?(cmd)
end
inspect() click to toggle source
# File lib/aio/core/device/parent_device.rb, line 61
def inspect
  "#<#{self.class}>"
end
instance() click to toggle source
# File lib/aio/core/device/parent_device.rb, line 57
def instance
  self
end
interface() click to toggle source

FIXME 无法获得正确的父类Interface

# File lib/aio/core/device/parent_device.rb, line 43
def interface
  self.class::Interface
end
method_missing(m, *args, &block) click to toggle source

1.导向命令方法模块 2.导向Warning类

Calls superclass method
# File lib/aio/core/device/parent_device.rb, line 235
def method_missing(m, *args, &block)
  if Aio::Device::Methods.respond_to?(m)
    Aio::Device::Methods.klass = self
    Aio::Device::Methods.send(m)

  elsif Aio::Text::Warning.instance_methods(false).include?(m.to_sym)
    warning_klass.send(m, *args)
  else
    super
  end
end
parse() click to toggle source

最终解析的地方 一定要确定设备类型,否则的话只能单一设备 cmds_context = { cmd_name => [ {

              device_type_1 => klass1, 
              device_type_2 => klass2},
context ] }
# File lib/aio/core/device/parent_device.rb, line 116
def parse

  # 做两次循环,第一次确定设备类型
  2.times do |t|
    cmds_context.each_pair do |cmd_name, info|
      context = info[1]

      # 如果没有cmd模块, 那么就跳过
      next if info[0].nil?

      info[0].each_pair do |device_type, module_klass|

        #module_klass.clear_useful

        # 如果找到了设备类型
        # 那么之后就只对该类型进行解析,其他的跳过
        if ! @device_type.empty? and @device_type != device_type
          next
        end

        module_klass.context = context
        module_klass.warning_klass = @warning_klass

        # 循环模块对内容进行解析
        # 当是第一遍遍历的时候,只找可以决定是什么设备类型的命令
        # 一般都是通过show version 这类命令找到, 那么同时也能找到设备型号和软件版本
        if t == 0 and not module_klass.key_stand
          next

        elsif t == 0 and module_klass.key_stand
          module_klass.parse
          push_device_info(module_klass)

          module_klass.clear_useful
          # 当device_type 有内容时,确定为已知设备类型,那么进行下次循环遍历
          if @device_type.empty?
            next
          else
            @warning_klass.clear
            break
          end
        end

        begin
          # 当是第二遍的时候,则全部解析
          module_klass.clear_useful
          module_klass.device_info = device_info
          module_klass.ext_info = {:device_name => @device_name}
          module_klass.parse
        rescue Aio::Text::Context::OutLineError
        rescue NoMethodError
          print_error "未找到方法,请检查模块的方法名拼写"
        rescue NameError
          print_error "#{module_klass.class} 未检测到对应版本"
        rescue Exception => e
          print_error "#{e.class} : #{module_klass.class}"
          print_error e.message
        ensure
          push_useful(module_klass, cmd_name)
          next
        end
      end
    end
  end

  # 当所有解析循环完成后,如果找到了设备类型
  # 就将此类转为对应子类
  # changeto
  if ! @device_type.empty?
    to = self.send("changeto_#{@device_type}")
  end

  return to ? to : self
end
push_device_info(module_klass) click to toggle source

存放设备基本信息

# File lib/aio/core/device/parent_device.rb, line 192
def push_device_info(module_klass)
  @device_type = module_klass.useful[:device_type].to_s
  @device_info[:device_model] = module_klass.useful[:device_model].to_s
  @device_info[:device_version] = module_klass.useful[:device_version].to_s
  @device_info[:device_template] = module_klass.useful[:device_template].to_s
end
push_useful(module_klass, cmd_name) click to toggle source

当一个模块解析完毕后,将有用信息放入cmds_useful 当有用信息中device_type类为真时, 就可以将此父类转变为具体的类型了 check

# File lib/aio/core/device/parent_device.rb, line 203
def push_useful(module_klass, cmd_name)

  if Aio::Base::Debug.enable?
    puts "parent_device#push_useful"
    pp module_klass
  end

  # 将有用信息放入整体有用信息
  cmds_useful[cmd_name] = module_klass.useful 
end

Private Instance Methods

changeto_cisco() click to toggle source
# File lib/aio/core/device/parent_device.rb, line 251
def changeto_cisco
  to = Cisco.new
  clone(to)
end
changeto_h3c() click to toggle source
# File lib/aio/core/device/parent_device.rb, line 266
def changeto_h3c
  to = H3C.new
  clone(to)
end
changeto_huawei() click to toggle source
# File lib/aio/core/device/parent_device.rb, line 256
def changeto_huawei
  to = Huawei.new
  clone(to)
end
changeto_maipu() click to toggle source
# File lib/aio/core/device/parent_device.rb, line 261
def changeto_maipu
  to = Maipu.new
  clone(to)
end
clone(to) click to toggle source
# File lib/aio/core/device/parent_device.rb, line 271
def clone(to)
  to.device_name            = Aio::Base::Toolkit::DeepClone.clone(self.device_name)
  to.cmds_context   = Aio::Base::Toolkit::DeepClone.clone(self.cmds_context)
  to.manager_ip                     = Aio::Base::Toolkit::DeepClone.clone(self.manager_ip)
  to.device_info            = Aio::Base::Toolkit::DeepClone.clone(self.device_info)
  to.cmds_useful            = Aio::Base::Toolkit::DeepClone.clone(self.cmds_useful)
  to.warning_klass  = Aio::Base::Toolkit::DeepClone.clone(self.warning_klass)
  to
end