Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
fortinet / lib / fortinet / firewallservice.rb
Size: Mime:
# frozen_string_literal: true

module Fortinet
  # Represents a service in the firewall
  class FirewallService
    def initialize(data, type)
      @data = data
      @type = type
    end

    def self.all
      Fortinet.do('get', '/api/v2/cmdb/firewall.service/custom')['results'].map { |data| new(data) }
    end

    def self.get_no_type(name)
      data = Fortinet.do('get', "/api/v2/cmdb/firewall.service/custom/#{name}")['results'].first
      new(data, 'custom')
    rescue RestClient::NotFound
      begin
        data = Fortinet.do('get', "/api/v2/cmdb/firewall.service/group/#{name}")['results'].first
        new(data, 'group')
      rescue RestClient::NotFound
        nil
      end
    end

    def self.get_with_type(name, type)
      data = Fortinet.do('get', "/api/v2/cmdb/firewall.service/#{type}/#{name}")['results'].first
      new(data, type)
    rescue RestClient::NotFound
      nil
    end

    def self.get(name, type = nil)
      type.nil? ? get_no_type(name) : get_with_type(name, type)
    end

    # type is custom or group
    def self.create(name, type)
      begin
        Fortinet.do('post', "/api/v2/cmdb/firewall.service/#{type}", { 'name' => name })
      rescue RestClient::FailedDependency
        raise StandardError, "Trying to create #{type} called #{name}, but that name already exists"
      end
      get(name)
    end

    def set(what, value)
      Fortinet.do('put', "/api/v2/cmdb/firewall.service/#{@type}/#{@data['name']}", { 'name' => @data['name'], what => value })
      @data = Fortinet.do('get', "/api/v2/cmdb/firewall.service/#{@type}/#{@data['name']}")['results'].first
    end

    def members
      @data['member'].map { |m| FirewallService.get(m['name']) }
    end

    def members=(members)
      if members.empty?
        set('member', [{ 'name' => 'none' }])
      else
        set('member', members.map { |m| Hash['name', m.is_a?(FirewallService) ? m.name : m] })
      end
    end

    def protocol=(proto)
      case proto.downcase
      when 'tcp'
        set('protocol', 'TCP/UDP/SCTP')
        set('protocol-number', 6)
      when 'udp'
        set('protocol', 'TCP/UDP/SCTP')
        set('protocol-number', 17)
      when /^[0-9]+/
        set('protocol', 'IP')
        set('protocol-number', proto)
      when 'icmp'
        set('protocol', 'ICMP')
      else
        raise StandardError, "Unknown protocol #{proto}"
      end
    end

    def protocol
      case @data['protocol']
      when 'TCP/UDP/SCTP'
        return 'tcp' if @data['protocol-number'] == 6
        return 'udp' if @data['protocol-number'] == 17

        raise StandardError, "Unknown protocol (#{@data['protocol']} / #{@data['protocol-number']})"
      when 'IP'
        @data['protocol-number']
      else
        @data['protocol']
      end
    end

    def port=(port)
      case protocol
      when 'tcp'
        set('tcp-portrange', port)
      when 'udp'
        set('udp-portrange', port)
      else
        raise StandardError, 'Unknown protocol'
      end
    end

    def port
      case protocol
      when 'tcp'
        @data['tcp-portrange']
      when 'udp'
        @data['udp-portrange']
      else
        raise StandardError, 'Unknown protocol'
      end
    end

    # Meta program up some nice methods
    %w[icmpcode icmptype color].each do |property|
      define_method property do
        @data[property]
      end

      next if method_defined?("#{property}=")

      define_method "#{property}=" do |value|
        set(property, value)
      end
    end
  end
end