Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MAC address and VLAN configuration to netns #35

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions features/dsl_netns.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
Feature: The netns DSL directive.
@sudo
Scenario: phut run with "netns(alias) { ip ... }"
Given a file named "network.conf" with:
"""
netns('host1') {
ip '192.168.8.6'
}
netns('host2') {
ip '192.168.8.7'
}
link 'host1', 'host2'
"""
When I do phut run "network.conf"
Then a netns named "host1" launches
And the "netmask" of the netns "host1" should be "/24"
And the "default_gateway" of the netns "host1" should be ""
And a netns named "host2" launches
And the "netmask" of the netns "host2" should be "/24"
And the "default_gateway" of the netns "host2" should be ""

@sudo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

シナリオとシナリオの間には空行を入れてください。

Scenario: phut run with "netns(alias) { ip, netmask, route ... }"
Given a file named "network.conf" with:
"""
netns('host1') {
ip '192.168.8.6'
netmask '255.255.255.128'
route net: '0.0.0.0/0', gateway: '192.168.8.1'
}
netns('host2') {
ip '192.168.8.7'
netmask '255.255.255.128'
route net: '0.0.0.0/0', gateway: '192.168.8.1'
}
link 'host1', 'host2'
"""
When I do phut run "network.conf"
Then a netns named "host1" launches
And the "netmask" of the netns "host1" should be "/25"
And the "default_gateway" of the netns "host1" should be "192.168.8.1"
And a netns named "host2" launches
And the "netmask" of the netns "host2" should be "/25"
And the "default_gateway" of the netns "host2" should be "192.168.8.1"

@sudo
Scenario: phut run with "netns(alias) { ip, vlan }"
Given a file named "network.conf" with:
"""
netns('host1') {
ip '192.168.8.6'
vlan 10
}
netns('host2') {
ip '192.168.8.7'
vlan 20
}
link 'host1', 'host2'
"""
When I do phut run "network.conf"
Then a netns named "host1" launches
And the "vlan" of the netns "host1" should be "10"
And a netns named "host2" launches
And the "vlan" of the netns "host2" should be "20"

@sudo
Scenario: phut run with "netns(alias) { ip, mac }"
Given a file named "network.conf" with:
"""
netns('host1') {
ip '192.168.8.6'
mac '00:53:00:00:00:01'
}
netns('host2') {
ip '192.168.8.7'
mac '00:53:00:00:00:02'
}
link 'host1', 'host2'
"""
When I do phut run "network.conf"
Then a netns named "host1" launches
And the "mac" of the netns "host1" should be "00:53:00:00:00:01"
And a netns named "host2" launches
And the "mac" of the netns "host2" should be "00:53:00:00:00:02"
22 changes: 22 additions & 0 deletions features/step_definitions/phut_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,28 @@
step %(a file named "vhost.#{name}.pid" should exist)
end

Then(/^a netns named "(.*?)" launches$/) do |name|
expect(`ip netns`).to match(/^#{name}$/)
end

# rubocop:disable LineLength
Then(/^the "(.*?)" of the netns "(.*?)" should be "(.*?)"$/) do |key, netns, value|
command =
case key
when 'netmask'
"ip addr list dev #{netns} | grep inet"
when 'default_gateway'
'ip route list match 0/0'
when 'vlan'
"ip link list dev #{netns}.#{value}"
else
'ip link list ; ip addr list'
end

expect(`sudo ip netns exec #{netns} #{command}`).to match(/#{value}/)
end
# rubocop:enable LineLength

Then(/^a link is created between "(.*?)" and "(.*?)"$/) do |name_a, name_b|
cd('.') do
link = Phut::Parser.new.parse(@config_file).fetch([name_a, name_b].sort)
Expand Down
50 changes: 43 additions & 7 deletions lib/phut/netns.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,55 @@ def initialize(options, name, logger)
@logger = logger
end

# rubocop:disable AbcSize
def run
setup_netns
setup_link
setup_ip
end

def stop
sh "sudo ip netns delete #{name}"
end

private

def setup_netns
sh "sudo ip netns add #{name}"
sh "sudo ip link set dev #{network_device} netns #{name}"
sh "sudo ip netns exec #{name} ifconfig lo 127.0.0.1"
end

def setup_link
setup_vlan
setup_mac_address
sh "sudo ip netns exec #{name} ip link set lo up"
sh "sudo ip netns exec #{name}"\
" ifconfig #{network_device} #{ip} netmask #{netmask}"
sh "sudo ip netns exec #{name} route add -net #{net} gw #{gateway}"
" ip link set #{network_device}#{vlan_suffix} up"
end
# rubocop:enable AbcSize

def stop
sh "sudo ip netns delete #{name}"
def setup_vlan
return unless vlan
sh "sudo ip netns exec #{name}"\
" ip link set #{network_device} up"
sh "sudo ip netns exec #{name}"\
" ip link add link #{network_device} name"\
" #{network_device}#{vlan_suffix} type vlan id #{vlan}"
end

def setup_mac_address
sh "sudo ip netns exec #{name}"\
" ip link set #{network_device}#{vlan_suffix} address #{mac}" if mac
end

def setup_ip
sh "sudo ip netns exec #{name} ip addr replace 127.0.0.1 dev lo"
sh "sudo ip netns exec #{name}"\
" ip addr replace #{ip}/#{netmask} dev #{network_device}#{vlan_suffix}"
sh "sudo ip netns exec #{name}"\
" ip route add #{net} via #{gateway}" if gateway
end

def vlan_suffix
vlan ? ".#{vlan}" : ''
end

def method_missing(message, *_args)
Expand Down
16 changes: 15 additions & 1 deletion lib/phut/syntax/netns_directive.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ class NetnsDirective < Directive
attribute :netmask

def initialize(alias_name, &block)
@attributes = { name: alias_name }
@attributes =
{ name: alias_name,
netmask: '255.255.255.0',
net: '0.0.0.0',
gateway: nil,
mac: nil,
vlan: nil }
instance_eval(&block)
end

Expand All @@ -20,6 +26,14 @@ def route(options)
@attributes[:net] = options.fetch(:net)
@attributes[:gateway] = options.fetch(:gateway)
end

def mac(value)
@attributes[:mac] = value
end

def vlan(value)
@attributes[:vlan] = value
end
end
end
end