Class: Phut::Netns

Inherits:
Object
  • Object
show all
Extended by:
Finder, ShellRunner
Includes:
ShellRunner
Defined in:
lib/phut/netns.rb

Overview

‘ip netns …` command runner

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ShellRunner

sh, sudo

Methods included from Finder

find_by, find_by!

Constructor Details

#initialize(name:, ip_address: nil, mac_address: nil, netmask: '255.255.255.255', route: {}, vlan: nil) ⇒ Netns

rubocop:disable ParameterLists



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/phut/netns.rb', line 54

def initialize(name:,
               ip_address: nil,
               mac_address: nil,
               netmask: '255.255.255.255',
               route: {},
               vlan: nil)
  @name = name
  @ip_address = ip_address
  @mac_address = mac_address
  @netmask = netmask
  @route = Route.new(net: route[:net], gateway: route[:gateway])
  @vlan = vlan
end

Instance Attribute Details

#ip_addressObject (readonly)

Returns the value of attribute ip_address.



50
51
52
# File 'lib/phut/netns.rb', line 50

def ip_address
  @ip_address
end

#mac_addressObject (readonly)

Returns the value of attribute mac_address.



51
52
53
# File 'lib/phut/netns.rb', line 51

def mac_address
  @mac_address
end

#nameObject (readonly)

Returns the value of attribute name.



49
50
51
# File 'lib/phut/netns.rb', line 49

def name
  @name
end

Class Method Details

.allObject

rubocop:disable MethodLength rubocop:disable AbcSize



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/phut/netns.rb', line 16

def self.all
  sh('ip netns list').split("\n").map do |each|
    name = each.split.first
    ip_addr_list =
      sudo("ip netns exec #{name} ip -4 -o addr list").split("\n")
    mac_addr_list =
      sudo("ip netns exec #{name} ip -4 -o link list").split("\n")
    if ip_addr_list.size > 1
      %r{inet ([^/]+)/(\d+)} =~ ip_addr_list[1]
      ip_address = Regexp.last_match(1)
      mask_length = Regexp.last_match(2).to_i
      netmask = IPAddr.new('255.255.255.255').mask(mask_length).to_s
      %r{link/ether ((?:[a-f\d]{2}:){5}[a-f\d]{2})}i =~ mac_addr_list[1]
      new(name: name, ip_address: ip_address, netmask: netmask,
          mac_address: Regexp.last_match(1))
    else
      new(name: name)
    end
  end.sort_by(&:name)
end

.create(*args) ⇒ Object

rubocop:enable MethodLength rubocop:enable AbcSize



39
40
41
# File 'lib/phut/netns.rb', line 39

def self.create(*args)
  new(*args).tap(&:run)
end

.destroy_allObject



43
44
45
# File 'lib/phut/netns.rb', line 43

def self.destroy_all
  all.each(&:stop)
end

Instance Method Details

#deviceObject



86
87
88
89
90
# File 'lib/phut/netns.rb', line 86

def device
  return unless /^\d+: #{Veth::PREFIX}(\d+)_([^:\.]*?)[@:]/ =~
                sudo("ip netns exec #{name} ip -o link show")
  Veth.new(name: $LAST_MATCH_INFO[2], link_id: $LAST_MATCH_INFO[1].to_i)
end

#device=(veth) ⇒ Object

rubocop:disable MethodLength rubocop:disable AbcSize



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/phut/netns.rb', line 94

def device=(veth)
  sudo "ip link set dev #{veth} netns #{name}"

  vlan_suffix = @vlan ? ".#{@vlan}" : ''
  if @vlan
    sudo "ip netns exec #{name} ip link set #{veth} up"
    sudo "ip netns exec #{name} "\
         "ip link add link #{veth} name "\
         "#{veth}#{vlan_suffix} type vlan id #{@vlan}"
  end
  if @mac_address
    sudo "ip netns exec #{name} "\
         "ip link set #{veth}#{vlan_suffix} address #{@mac_address}"
  end
  sudo "ip netns exec #{name} ip link set #{veth}#{vlan_suffix} up"
  sudo "ip netns exec #{name} "\
       "ip addr replace #{@ip_address}/#{@netmask} "\
       "dev #{veth}#{vlan_suffix}"
  sudo "ip netns exec #{name} ip link set #{veth}#{vlan_suffix} up"

  @route.add name
end

#exec(command) ⇒ Object



82
83
84
# File 'lib/phut/netns.rb', line 82

def exec(command)
  sudo "ip netns exec #{name} #{command}"
end

#netmaskObject

rubocop:enable MethodLength rubocop:enable AbcSize



119
120
121
122
123
124
# File 'lib/phut/netns.rb', line 119

def netmask
  if %r{inet [^/]+/(\d+) } =~
     sudo("ip netns exec #{name} ip -o -4 address show dev #{device}")
    IPAddr.new('255.255.255.255').mask(Regexp.last_match(1).to_i).to_s
  end
end

#routeObject



126
127
128
# File 'lib/phut/netns.rb', line 126

def route
  Route.read name
end

#runObject

rubocop:enable MethodLength rubocop:enable ParameterLists



70
71
72
73
# File 'lib/phut/netns.rb', line 70

def run
  sudo "ip netns add #{name}"
  sudo "ip netns exec #{name} ifconfig lo 127.0.0.1"
end

#stopObject



75
76
77
78
79
80
# File 'lib/phut/netns.rb', line 75

def stop
  sudo("ip netns pids #{name}").split("\n").each do |each|
    exec "kill #{each}"
  end
  sudo "ip netns delete #{name}"
end

#vlanObject



130
131
132
133
134
135
# File 'lib/phut/netns.rb', line 130

def vlan
  if /^\d+: #{device.device}\.(\d+)@/ =~
     sudo("ip netns exec #{name} ip -o link show")
    Regexp.last_match(1)
  end
end