diff options
| author | Saku Ytti <saku@ytti.fi> | 2013-04-19 12:36:45 +0300 | 
|---|---|---|
| committer | Saku Ytti <saku@ytti.fi> | 2013-04-19 12:41:29 +0300 | 
| commit | 96668cc2dc0367e3d1a3ec94265ce889b62d8ada (patch) | |
| tree | 340f92a6dd4b68e41a946729c8fae34db7aff40b | |
| parent | 9d217025fac3e335c308f02e7377e14ccfdc0e66 (diff) | |
Add restful API
| -rw-r--r-- | .rspec | 1 | ||||
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | TODO.md | 5 | ||||
| -rw-r--r-- | lib/oxidized/api/domain.rb | 48 | ||||
| -rw-r--r-- | lib/oxidized/api/rest.rb | 43 | ||||
| -rw-r--r-- | lib/oxidized/config/bootstrap.rb | 3 | ||||
| -rw-r--r-- | lib/oxidized/config/defaults.rb | 1 | ||||
| -rw-r--r-- | lib/oxidized/core.rb | 15 | ||||
| -rw-r--r-- | lib/oxidized/manager.rb | 1 | ||||
| -rw-r--r-- | lib/oxidized/node.rb | 19 | ||||
| -rw-r--r-- | lib/oxidized/nodes.rb | 20 | ||||
| -rw-r--r-- | lib/oxidized/output/git.rb | 1 | ||||
| -rw-r--r-- | spec/nodes_spec.rb | 13 | 
13 files changed, 151 insertions, 22 deletions
@@ -0,0 +1 @@ +--colour @@ -1,6 +1,7 @@  # Pitch   * automatically adds/removes threads to meet configured retrieval interval - * can move node immediately to head-of-queue (maybe trigger from snmp trap or syslog), to be serviced by next spawned thread + * restful API to move node immediately to head-of-queue (maybe trigger from snmp trap or syslog), to be serviced by next spawned thread (GET /nodes/next/$node) + * restful API to reload list of nodes (GET /nodes/reload)  # Install   early days, but try to run it and edit ~/.config/oxidized/config @@ -15,11 +15,6 @@ I don't really need it myself, since I don't have platforms where it would be ne    * should we try to avoid max threads from being hit? (like maybe non-success thread is pulling average?) -# restful API (puma+sinatra): -  * ask to reload node list -  * move node to head of queue - -  # config     * save keys as strings, load as symbols? diff --git a/lib/oxidized/api/domain.rb b/lib/oxidized/api/domain.rb new file mode 100644 index 0000000..fa6a1c7 --- /dev/null +++ b/lib/oxidized/api/domain.rb @@ -0,0 +1,48 @@ +# this is not used, just added here if I want to revive it + +module Oxidized +  require 'socket' +  require 'json' +  module API +    class Domain +      def initialize nodes, socket=CFG.api +        puts 'here' +        @nodes = nodes +        File.unlink socket rescue Errno::ENOENT +        @server = UNIXServer.new socket +      end +      def work +        io = select [@server], nil, nil, Config::Sleep +        process io.first.first.accept if io +      end +      def read +        @socket.recv 1024 +      end +      def write data='' +        begin +          @socket.send JSON.dump(data), 0 +        rescue Errno::EPIPE +        end +      end +      def process socket +        @socket = socket +        cmd = read +        cmd, data = cmd.split /\s+/, 2 +        data = data.to_s.chomp +        case cmd +        when /next/i +          @nodes.next data +          write 'OK' +        when /reload/i +          @nodes.load if data.match /nodes/i +          write 'OK' +        when /list/i +          write @nodes.map{|e|e.name} +        when /node/i +          write @nodes.show(data) +        end +        @socket.close +      end +    end +  end +end diff --git a/lib/oxidized/api/rest.rb b/lib/oxidized/api/rest.rb new file mode 100644 index 0000000..ee06bc8 --- /dev/null +++ b/lib/oxidized/api/rest.rb @@ -0,0 +1,43 @@ +module Oxidized +  require 'webrick' +  require 'json' +  module API +    class Rest +      def initialize nodes, listen +        @nodes = nodes +        addr, port = listen.to_s.split ':' +        port, addr = addr, nil if not port +        @web = WEBrick::HTTPServer.new :BindAddress=>addr, :Port=>port +        maps +      end +      def work +        req = select @web.listeners, nil, nil, Config::Sleep +        while req +          @web.run req.first.first.accept +          req = select @web.listeners, nil, nil, 0 +        end +      end +      def maps +        @web.mount_proc '/nodes' do |req, res| +          #script_name, #path_info +          case req.path_info[1..-1] +          # /nodes/reload - reloads list of nodes +          when 'reload' +            @nodes.load +            res.body = JSON.dump 'OK' +          # /nodes/next/node - moves node to head of queue +          when /next\/(.*)/ +            @nodes.next $1 +            res.body = JSON.dump 'OK' +          # /nodes/list - returns list of nodes +          when 'list' +            res.body = JSON.dump @nodes.list +          # /nodes/show/node - returns data about node +          when /show\/(.*)/ +            res.body = JSON.dump @nodes.show $1 +          end +        end +      end +    end +  end +end diff --git a/lib/oxidized/config/bootstrap.rb b/lib/oxidized/config/bootstrap.rb index e44dde7..2991fa3 100644 --- a/lib/oxidized/config/bootstrap.rb +++ b/lib/oxidized/config/bootstrap.rb @@ -10,6 +10,7 @@ module Oxidized    CFG.threads  = 10    CFG.timeout  = 5    CFG.prompt   = /^([\w\.\-@]{3,30}[#>]\s?)$/  +  CFG.rest     = 8888    CFG.input    = {      :default => 'ssh',    } @@ -17,7 +18,7 @@ module Oxidized      :default => 'git',    }    CFG.source   = { -    :default => 'ascii', +    :default => 'csv',    }    CFG.model_map = {      'cisco'   => 'ios', diff --git a/lib/oxidized/config/defaults.rb b/lib/oxidized/config/defaults.rb index a07e1a6..943d90b 100644 --- a/lib/oxidized/config/defaults.rb +++ b/lib/oxidized/config/defaults.rb @@ -5,6 +5,7 @@ module Oxidized      OutputDir = File.join Directory, %w(lib oxidized output)      ModelDir  = File.join Directory, %w(lib oxidized model)      SourceDir = File.join Directory, %w(lib oxidized source)  +    Sleep     = 1    end    class << self      attr_accessor :mgr diff --git a/lib/oxidized/core.rb b/lib/oxidized/core.rb index 76aa330..59292f9 100644 --- a/lib/oxidized/core.rb +++ b/lib/oxidized/core.rb @@ -4,6 +4,7 @@ module Oxidized    require 'oxidized/worker'    require 'oxidized/nodes'    require 'oxidized/manager' +  require 'oxidized/api/rest'    class << self      def new *args        Core.new args @@ -14,8 +15,18 @@ module Oxidized      def initialize args        Oxidized.mgr = Manager.new        nodes        = Nodes.new -      worker       = Worker.new nodes -      loop { worker.work; sleep 1 } +      @worker      = Worker.new nodes +      @rest        = API::Rest.new nodes, CFG.rest if CFG.rest +      run +    end + +    private + +    def run +      while true +        @worker.work +        @rest ? @rest.work : sleep(Config::Sleep) +      end      end    end  end diff --git a/lib/oxidized/manager.rb b/lib/oxidized/manager.rb index 0edf9e7..8c53d64 100644 --- a/lib/oxidized/manager.rb +++ b/lib/oxidized/manager.rb @@ -37,6 +37,7 @@ module Oxidized        @model.merge! _model       end      def source= _source +      return nil if @source.key? _source        _source = Manager.load Config::SourceDir, _source        return false if _source.empty?        @source.merge! _source diff --git a/lib/oxidized/node.rb b/lib/oxidized/node.rb index 740834a..de04c98 100644 --- a/lib/oxidized/node.rb +++ b/lib/oxidized/node.rb @@ -28,6 +28,25 @@ module Oxidized        [status, config]      end +    def serialize +      h = { +        :name  => @name, +        :ip    => @ip, +        :group => @group, +        :model => @model.class.to_s, +        :last  => nil, +      } +      if @last +        h[:last] = { +          :start  => @last.start, +          :end    => @last.end, +          :status => @last.status, +          :time   => @last.time, +        } +      end +      h +    end +      private      def resolve_prompt opt diff --git a/lib/oxidized/nodes.rb b/lib/oxidized/nodes.rb index 467d3a0..3e58348 100644 --- a/lib/oxidized/nodes.rb +++ b/lib/oxidized/nodes.rb @@ -2,7 +2,7 @@ module Oxidized    require 'oxidized/node'    class Nodes < Array      attr_accessor :source -    alias :del :delete +    alias :put :unshift      def initialize *args        super        load if args.empty? @@ -17,17 +17,25 @@ module Oxidized        replace new      end      def list -      self +      map { |e| e.name }      end -    # @param node [String] name of the node inserted into nodes array -    def put node -      unshift node +    def find_index node +      index { |e| e.name == node } +    end +    def show node +      i = find_index node +      self[i].serialize if i +    end +    def del node +      i = find_index node +      delete_at i if i      end      # @param node [String] name of the node moved into the head of array -    def top node +    def next node        n = del node        put n if n      end +    alias :top :next      # @return [String] node from the head of the array      def get        (self << shift).last diff --git a/lib/oxidized/output/git.rb b/lib/oxidized/output/git.rb index 77d18bb..019d83b 100644 --- a/lib/oxidized/output/git.rb +++ b/lib/oxidized/output/git.rb @@ -28,7 +28,6 @@ class Git < Output        repo = File.join File.dirname(repo), opt[:group] + '.git'      end      begin -        repo = Repo.new repo        actor = Actor.new user, email        update_repo repo, file, data, msg, actor diff --git a/spec/nodes_spec.rb b/spec/nodes_spec.rb index ad51525..80ed300 100644 --- a/spec/nodes_spec.rb +++ b/spec/nodes_spec.rb @@ -1,15 +1,16 @@ -require 'oxidized/nodes' +require 'oxidized' +Oxidized.mgr = Oxidized::Manager.new  describe Oxidized::Nodes do    before(:each) do      @nodes_org = %w(ltt-pe1.hel kes2-rr1.tku tor-peer1.oul -                hal-p2.tre sav-gr1-sw1.kuo psl-sec-pe1.hel) +                hal-p2.tre sav-gr1-sw1.kuo psl-sec-pe1.hel).map { |e| Oxidized::Node.new(:name=>e) }      @nodes = Oxidized::Nodes.new @nodes_org.dup    end    describe '#put' do      it 'adds node to top of queue' do -      node = 'kst-p1.sto' +      node = Oxidized::Node.new(:name=>'kst-p1.sto')        @nodes.put node        expect(@nodes).to eq [node] + @nodes_org      end @@ -30,15 +31,15 @@ describe Oxidized::Nodes do      end    end -  describe '#top' do +  describe '#next' do      it 'moves node to top of queue' do        node = @nodes[3] -      @nodes.top node +      @nodes.next node.name        expect(@nodes).to start_with [node]      end      it 'does not change node count' do        before = @nodes.size -      @nodes.top @nodes[3] +      @nodes.next @nodes[3].name        expect(before).to eq @nodes.size      end    end  | 
