\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/chef/embedded/lib/ruby/gems/2.7.0/gems/inspec-core-4.22.1/lib/inspec/resources/

Viewing File: bridge.rb

require "inspec/resources/file"

# Usage:
# describe bridge('br0') do
#   it { should exist }
#   it { should have_interface 'eth0' }
# end

module Inspec::Resources
  class Bridge < Inspec.resource(1)
    name "bridge"
    supports platform: "unix"
    desc "Use the bridge InSpec audit resource to test basic network bridge properties, such as name, if an interface is defined, and the associations for any defined interface."
    example <<~EXAMPLE
      describe bridge 'br0' do
        it { should exist }
        it { should have_interface 'eth0' }
      end
    EXAMPLE

    def initialize(bridge_name)
      @bridge_name = bridge_name

      @bridge_provider = nil
      if inspec.os.linux?
        @bridge_provider = LinuxBridge.new(inspec)
      elsif inspec.os.windows?
        @bridge_provider = WindowsBridge.new(inspec)
      else
        return skip_resource "The `bridge` resource is not supported on your OS yet."
      end
    end

    def exists?
      !bridge_info.nil? && !bridge_info[:name].nil?
    end

    def has_interface?(interface)
      return skip_resource "The `bridge` resource does not provide interface detection for Windows yet" if inspec.os.windows?

      bridge_info.nil? ? false : bridge_info[:interfaces].include?(interface)
    end

    def interfaces
      bridge_info.nil? ? nil : bridge_info[:interfaces]
    end

    def to_s
      "Bridge #{@bridge_name}"
    end

    private

    def bridge_info
      return @cache if defined?(@cache)

      @cache = @bridge_provider.bridge_info(@bridge_name) unless @bridge_provider.nil?
    end
  end

  class BridgeDetection
    attr_reader :inspec
    def initialize(inspec)
      @inspec = inspec
    end
  end

  # Linux Bridge
  # If /sys/class/net/{interface}/bridge exists then it must be a bridge
  # /sys/class/net/{interface}/brif contains the network interfaces
  # @see http://www.tldp.org/HOWTO/BRIDGE-STP-HOWTO/set-up-the-bridge.html
  # @see http://unix.stackexchange.com/questions/40560/how-to-know-if-a-network-interface-is-tap-tun-bridge-or-physical
  class LinuxBridge < BridgeDetection
    def bridge_info(bridge_name)
      # read bridge information
      bridge = inspec.file("/sys/class/net/#{bridge_name}/bridge").directory?
      return nil unless bridge

      # load interface names
      interfaces = inspec.command("ls -1 /sys/class/net/#{bridge_name}/brif/")
      interfaces = interfaces.stdout.chomp.split("\n")
      {
        name: bridge_name,
        interfaces: interfaces,
      }
    end
  end

  # Windows Bridge
  # select netadapter by adapter binding for windows
  # Get-NetAdapterBinding -ComponentID ms_bridge | Get-NetAdapter
  # @see https://technet.microsoft.com/en-us/library/jj130921(v=wps.630).aspx
  # RegKeys: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}
  class WindowsBridge < BridgeDetection
    def bridge_info(bridge_name)
      # find all bridge adapters
      cmd = inspec.command("Get-NetAdapterBinding -ComponentID ms_bridge | Get-NetAdapter | Select-Object -Property Name, InterfaceDescription | ConvertTo-Json")

      # filter network interface
      begin
        bridges = JSON.parse(cmd.stdout)
      rescue JSON::ParserError => _e
        return nil
      end

      # ensure we have an array of groups
      bridges = [bridges] unless bridges.is_a?(Array)

      # select the requested interface
      bridges = bridges.each_with_object([]) do |adapter, adapter_collection|
        # map object
        info = {
          name: adapter["Name"],
          interfaces: nil,
        }
        adapter_collection.push(info) if info[:name].casecmp(bridge_name) == 0
      end

      return nil if bridges.empty?

      warn "[Possible Error] detected multiple bridges interfaces with the name #{bridge_name}" if bridges.size > 1
      bridges[0]
    end
  end
end