phut 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 976e821178942cdc0a5ce7aae154ebbfc0f3f1bd
4
- data.tar.gz: de76db53ba5388fb53a75ee06eb55157f8ffd55a
3
+ metadata.gz: 681a58fd291ea016d0ffc8d56a9c62fb3ab38568
4
+ data.tar.gz: 48d70fb96ecac1cbddb1868172d4b8a0af0163ed
5
5
  SHA512:
6
- metadata.gz: 8b633f79a7e4057b6818d75313409ec16207a4ba73dd8a89a1664576caac6f6ac0033e330792b0cd85a690dc5b2c3d24f29a9fb4ee15d87003ed8319a85b23fd
7
- data.tar.gz: d2533b9a48e4d5ebe38958ca2fc41076012cbb61cb0387fcca29a56a86565698c7f74abceefedead44917d3a89ab19be1985a3421f036d4ee9ea86a2a3519aba
6
+ metadata.gz: e2eab81e9e6b03c262a5debdcec17eb12aa3f565e99fcf27f8e904f68f84b0d1fedf1c29e6deee08a6e4e9a471c937fe8a2d9f76e0a9340e9b69009e82b63427
7
+ data.tar.gz: bb22c24a34980bc1f7b7284b2f81d04efac05e2345bb41bda36deb105c84a69a04108fdf0d1842b6a955eb79d452c3e9a8904aa53b7f2af72a6b3afe4736ecfc
data/CHANGELOG.md CHANGED
@@ -3,6 +3,16 @@
3
3
  ## develop (unreleased)
4
4
 
5
5
 
6
+ ## 0.4.0 (3/19/2015)
7
+ ### New features
8
+ * Add `phut show` command.
9
+
10
+ ### Changes
11
+ * [#14](https://github.com/trema/phut/issues/14): Switch port number
12
+ to which a virtual link is attached is implicitly determined by the
13
+ ordering of `link` directives in DSL file.
14
+
15
+
6
16
  ## 0.3.1 (3/17/2015)
7
17
  ### Bugs fixed
8
18
  * Set switch's dpid before connecting to a controller.
@@ -10,7 +20,8 @@
10
20
 
11
21
  ## 0.3.0 (3/17/2015)
12
22
  ### Changes
13
- * [#20](https://github.com/trema/phut/pull/20): Use apt installed version of Open vSwitch.
23
+ * [#20](https://github.com/trema/phut/pull/20): Use apt installed
24
+ version of Open vSwitch.
14
25
 
15
26
 
16
27
  ## 0.2.4 (3/12/2015)
data/Rakefile CHANGED
@@ -2,9 +2,11 @@ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib')
2
2
 
3
3
  require 'rake/clean'
4
4
 
5
+ RELISH_PROJECT = 'trema/phut'
6
+
5
7
  task default: :test
6
8
  task test: [:spec, :cucumber, :quality]
7
- task quality: [:rubocop, :reek, :flog]
8
9
  task travis: [:spec, 'cucumber:travis', :quality]
10
+ task quality: [:rubocop, :reek, :flog, :flay]
9
11
 
10
12
  Dir.glob('tasks/*.rake').each { |each| import each }
data/bin/phut CHANGED
@@ -72,6 +72,14 @@ module Phut
72
72
  end
73
73
  end
74
74
 
75
+ desc 'Shows information on switch'
76
+ arg_name 'SWITCH'
77
+ command :show do |c|
78
+ c.action do |_global_options, _options, args|
79
+ system "sudo ovs-ofctl show br#{args[0]}"
80
+ end
81
+ end
82
+
75
83
  desc 'Stops a virtual network'
76
84
  arg_name 'FILE'
77
85
  command :stop do |c|
@@ -1,22 +1,51 @@
1
- Feature: The link DSL directive.
1
+ Feature: The link directive of phut DSL
2
2
  @sudo
3
- Scenario: phut run with "link ..."
3
+ Scenario: link name_a, name_b
4
4
  Given a file named "network.conf" with:
5
- """
6
- vswitch { dpid '0xabc' }
7
- vhost { ip '192.168.0.1' }
8
- link '0xabc', '192.168.0.1'
9
- """
5
+ """
6
+ vswitch { dpid 0xabc }
7
+ vhost { ip '192.168.0.1' }
8
+ link '0xabc', '192.168.0.1'
9
+ """
10
10
  When I do phut run "network.conf"
11
11
  Then a link is created between "0xabc" and "192.168.0.1"
12
12
 
13
13
  @sudo
14
- Scenario: phut run with "link alias1, alias2"
14
+ Scenario: link alias_a, alias_b
15
15
  Given a file named "network.conf" with:
16
- """
17
- vswitch('my_switch') { dpid '0xabc' }
18
- vhost('host1') { ip '192.168.0.1' }
19
- link 'my_switch', 'host1'
20
- """
16
+ """
17
+ vswitch('my_switch') { dpid 0xabc }
18
+ vhost('host1') { ip '192.168.0.1' }
19
+ link 'my_switch', 'host1'
20
+ """
21
21
  When I do phut run "network.conf"
22
22
  Then a link is created between "my_switch" and "host1"
23
+
24
+ @sudo
25
+ Scenario: connect multiple links to a switch
26
+ Given a file named "network.conf" with:
27
+ """
28
+ vswitch { datapath_id 0xabc }
29
+
30
+ vhost('host1') {
31
+ ip '192.168.0.1'
32
+ }
33
+ vhost('host2') {
34
+ ip '192.168.0.2'
35
+ }
36
+ vhost('host3') {
37
+ ip '192.168.0.3'
38
+ }
39
+
40
+ link '0xabc', 'host1'
41
+ link '0xabc', 'host2'
42
+ link '0xabc', 'host3'
43
+ """
44
+ When I do phut run "network.conf"
45
+ And I run `phut show 0xabc`
46
+ Then a link is created between "0xabc" and "host1"
47
+ And a link is created between "0xabc" and "host2"
48
+ And a link is created between "0xabc" and "host3"
49
+ And the output from "phut show 0xabc" should contain "1(0xabc_1)"
50
+ And the output from "phut show 0xabc" should contain "2(0xabc_2)"
51
+ And the output from "phut show 0xabc" should contain "3(0xabc_3)"
@@ -37,6 +37,7 @@ Feature: Shell
37
37
  And I type "vswitch 0xabc"
38
38
  When I type "kill 0xabc"
39
39
  And I type "quit"
40
+ And I run `sleep 1`
40
41
  Then a vswitch named "0xabc" should not be running
41
42
 
42
43
  @shell
@@ -7,11 +7,11 @@ When(/^I do phut run "(.*?)"$/) do |file_name|
7
7
  end
8
8
 
9
9
  Then(/^a vswitch named "(.*?)" should be running$/) do |name|
10
- expect(system("sudo ovs-vsctl br-exists #{name}")).to be(true)
10
+ expect(system("sudo ovs-vsctl br-exists br#{name}")).to be_truthy
11
11
  end
12
12
 
13
13
  Then(/^a vswitch named "(.*?)" should not be running$/) do |name|
14
- expect(system("sudo ovs-vsctl br-exists #{name}")).to be(false)
14
+ expect(system("sudo ovs-vsctl br-exists br#{name}")).to be_falsey
15
15
  end
16
16
 
17
17
  Then(/^a vhost named "(.*?)" launches$/) do |name|
@@ -23,9 +23,7 @@ end
23
23
 
24
24
  Then(/^a link is created between "(.*?)" and "(.*?)"$/) do |name_a, name_b|
25
25
  in_current_dir do
26
- link = Phut::Parser.new.parse(@config_file).links.find do |each|
27
- each.name_a == name_a && each.name_b == name_b
28
- end
26
+ link = Phut::Parser.new.parse(@config_file).fetch([name_a, name_b].sort)
29
27
  expect(link).to be_up
30
28
  end
31
29
  end
@@ -1,19 +1,41 @@
1
- require 'forwardable'
2
1
  require 'phut/null_logger'
3
2
  require 'phut/open_vswitch'
4
3
 
5
4
  module Phut
6
5
  # Parsed DSL data.
7
6
  class Configuration
8
- extend Forwardable
9
-
10
- def_delegators :@all, :fetch, :[]
7
+ attr_reader :links
11
8
 
12
9
  def initialize(logger = NullLogger.new)
13
10
  @all = {}
11
+ @links = []
14
12
  @logger = logger
15
13
  end
16
14
 
15
+ # rubocop:disable MethodLength
16
+ def fetch(key)
17
+ case key
18
+ when String
19
+ @all.fetch(key)
20
+ when Array
21
+ @links.each do |each|
22
+ return each if [each.name_a, each.name_b].sort == key.sort
23
+ end
24
+ fail "link #{key.join ' '} not found."
25
+ else
26
+ fail "Invalid key: #{key.inspect}"
27
+ end
28
+ end
29
+ # rubocop:enable MethodLength
30
+
31
+ def find_network_device_by_name(name)
32
+ @links.each do |each|
33
+ device = each.find_network_device_by_name(name)
34
+ return device if device
35
+ end
36
+ fail "No network device found for #{name}."
37
+ end
38
+
17
39
  def vswitches
18
40
  @all.values.select { |each| each.is_a? OpenVswitch }
19
41
  end
@@ -22,10 +44,6 @@ module Phut
22
44
  @all.values.select { |each| each.is_a? Vhost }
23
45
  end
24
46
 
25
- def links
26
- @all.values.select { |each| each.is_a? VirtualLink }
27
- end
28
-
29
47
  def run
30
48
  links.each(&:run)
31
49
  vhosts.each { |each| each.run vhosts }
@@ -49,10 +67,8 @@ module Phut
49
67
  Vhost.new(attrs[:ip], attrs[:mac], attrs[:promisc], name, @logger)
50
68
  end
51
69
 
52
- # This method smells of :reek:LongParameterList
53
- def add_link(name_a, device_a, name_b, device_b)
54
- @all[[name_a, name_b]] =
55
- VirtualLink.new(name_a, device_a, name_b, device_b, @logger)
70
+ def add_link(name_a, name_b)
71
+ @links << VirtualLink.new(name_a, name_b, @logger)
56
72
  end
57
73
 
58
74
  private
@@ -9,12 +9,12 @@ module Phut
9
9
 
10
10
  attr_reader :dpid
11
11
  alias_method :datapath_id, :dpid
12
- attr_writer :interfaces
12
+ attr_reader :network_devices
13
13
 
14
14
  def initialize(dpid, name = nil, logger = NullLogger.new)
15
15
  @dpid = dpid
16
16
  @name = name
17
- @interfaces = []
17
+ @network_devices = []
18
18
  @logger = logger
19
19
  end
20
20
 
@@ -26,25 +26,29 @@ module Phut
26
26
  "vswitch (name = #{name}, dpid = #{format('%#x', @dpid)})"
27
27
  end
28
28
 
29
+ # rubocop:disable MethodLength
29
30
  # rubocop:disable AbcSize
30
31
  def run
31
- sh "sudo ovs-vsctl add-br #{name}"
32
- sh "sudo /sbin/sysctl -w net.ipv6.conf.#{name}.disable_ipv6=1 -q"
33
- @interfaces.each { |each| sh "sudo ovs-vsctl add-port #{name} #{each}" }
34
- sh "sudo ovs-vsctl set bridge #{name} protocols=OpenFlow10" \
35
- " other-config:datapath-id=#{dpid_zero_filled}"
36
- sh "sudo ovs-vsctl set-controller #{name} tcp:127.0.0.1:6633"\
37
- " -- set controller #{name} connection-mode=out-of-band"
38
- sh "sudo ovs-vsctl set-fail-mode #{name} secure"
32
+ sh "sudo ovs-vsctl add-br #{bridge_name}"
33
+ sh "sudo /sbin/sysctl -w net.ipv6.conf.#{bridge_name}.disable_ipv6=1 -q"
34
+ @network_devices.each do |each|
35
+ sh "sudo ovs-vsctl add-port #{bridge_name} #{each}"
36
+ end
37
+ sh "sudo ovs-vsctl set bridge #{bridge_name} protocols=OpenFlow10" \
38
+ " other-config:datapath-id=#{dpid_zero_filled}"
39
+ sh "sudo ovs-vsctl set-controller #{bridge_name} tcp:127.0.0.1:6633"\
40
+ " -- set controller #{bridge_name} connection-mode=out-of-band"
41
+ sh "sudo ovs-vsctl set-fail-mode #{bridge_name} secure"
39
42
  rescue
40
43
  raise "Open vSwitch (dpid = #{@dpid}) is already running!"
41
44
  end
42
45
  alias_method :start, :run
46
+ # rubocop:enable MethodLength
43
47
  # rubocop:enable AbcSize
44
48
 
45
49
  def stop
46
50
  fail "Open vSwitch (dpid = #{@dpid}) is not running!" unless running?
47
- sh "sudo ovs-vsctl del-br #{name}"
51
+ sh "sudo ovs-vsctl del-br #{bridge_name}"
48
52
  end
49
53
  alias_method :shutdown, :stop
50
54
 
@@ -54,23 +58,27 @@ module Phut
54
58
  end
55
59
 
56
60
  def bring_port_up(port_number)
57
- sh "sudo ovs-ofctl mod-port #{name} #{port_number} up"
61
+ sh "sudo ovs-ofctl mod-port #{bridge_name} #{port_number} up"
58
62
  end
59
63
 
60
64
  def bring_port_down(port_number)
61
- sh "sudo ovs-ofctl mod-port #{name} #{port_number} down"
65
+ sh "sudo ovs-ofctl mod-port #{bridge_name} #{port_number} down"
62
66
  end
63
67
 
64
68
  def dump_flows
65
- `sudo ovs-ofctl dump-flows #{name}`
69
+ `sudo ovs-ofctl dump-flows #{bridge_name}`
66
70
  end
67
71
 
68
72
  def running?
69
- system "sudo ovs-vsctl br-exists #{name}"
73
+ system "sudo ovs-vsctl br-exists #{bridge_name}"
70
74
  end
71
75
 
72
76
  private
73
77
 
78
+ def bridge_name
79
+ 'br' + name
80
+ end
81
+
74
82
  def restart
75
83
  stop
76
84
  start
data/lib/phut/parser.rb CHANGED
@@ -7,45 +7,42 @@ module Phut
7
7
  class Parser
8
8
  def initialize(logger = NullLogger.new)
9
9
  @config = Configuration.new(logger)
10
+ @port_number = Hash.new(0)
10
11
  end
11
12
 
12
13
  def parse(file)
13
14
  Syntax.new(@config).instance_eval IO.read(file), file
14
- assign_vswitch_interfaces
15
- assign_vhost_interface
15
+ connect_links_to_switches
16
+ connect_links_to_vhosts
16
17
  @config
17
18
  end
18
19
 
19
20
  private
20
21
 
21
- def assign_vswitch_interfaces
22
- @config.vswitches.each do |each|
23
- each.interfaces = find_interfaces_by_name(each.name)
22
+ def connect_links_to_switches
23
+ @config.links.each do |each|
24
+ maybe_assign_network_device_to_vswitch each
24
25
  end
25
26
  end
26
27
 
27
- def assign_vhost_interface
28
+ def connect_links_to_vhosts
28
29
  @config.vhosts.each do |each|
29
- each.interface = find_host_interface_by_name(each.name)
30
+ each.network_device = @config.find_network_device_by_name(each.name)
30
31
  end
31
32
  end
32
33
 
33
- def find_interfaces_by_name(name)
34
- find_device_by_name(name, :name_a, :device_a) +
35
- find_device_by_name(name, :name_b, :device_b)
36
- end
37
-
38
- def find_host_interface_by_name(name)
39
- find_interfaces_by_name(name).tap do |interface|
40
- fail "No link found for host #{name}" if interface.empty?
41
- fail "Multiple links connect to host #{name}" if interface.size > 1
42
- end.first
34
+ def maybe_assign_network_device_to_vswitch(link)
35
+ @config.vswitches.each do |each|
36
+ switch_name = each.name
37
+ network_device = link.find_network_device_by_name(switch_name)
38
+ next unless network_device
39
+ network_device.port_number = new_port_number(switch_name)
40
+ each.network_devices << network_device
41
+ end
43
42
  end
44
43
 
45
- def find_device_by_name(name, name_type, device_type)
46
- @config.links.select do |each|
47
- each.__send__(name_type) == name
48
- end.map(&device_type)
44
+ def new_port_number(switch_name)
45
+ @port_number[switch_name] += 1
49
46
  end
50
47
  end
51
48
  end
data/lib/phut/syntax.rb CHANGED
@@ -71,42 +71,8 @@ module Phut
71
71
  end
72
72
  end
73
73
 
74
- # The 'link name_a, name_b' directive.
75
- class LinkDirective
76
- # Generates an unique Link ID
77
- class LinkId
78
- def initialize
79
- init
80
- end
81
-
82
- def init
83
- @index = 0
84
- end
85
-
86
- def generate
87
- @index += 1
88
- end
89
- end
90
-
91
- LinkIdSingleton = LinkId.new
92
-
93
- def initialize(name_a, name_b, link_id)
94
- @attributes = {}
95
- @attributes[:name_a] = name_a
96
- @attributes[:name_b] = name_b
97
- link_id = LinkIdSingleton.generate
98
- @attributes[:device_a] = "link#{link_id}-0"
99
- @attributes[:device_b] = "link#{link_id}-1"
100
- end
101
-
102
- def [](key)
103
- @attributes[key]
104
- end
105
- end
106
-
107
74
  def initialize(config)
108
75
  @config = config
109
- LinkDirective::LinkIdSingleton.init
110
76
  end
111
77
 
112
78
  def vswitch(alias_name = nil, &block)
@@ -120,9 +86,7 @@ module Phut
120
86
  end
121
87
 
122
88
  def link(name_a, name_b)
123
- link_id = @config.links.size
124
- attrs = LinkDirective.new(name_a, name_b, link_id)
125
- @config.add_link name_a, attrs[:device_a], name_b, attrs[:device_b]
89
+ @config.add_link name_a, name_b
126
90
  end
127
91
  end
128
92
  end
data/lib/phut/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # Base module.
2
2
  module Phut
3
- VERSION = '0.3.1'
3
+ VERSION = '0.4.0'
4
4
  end