omf_rc_openflow 6.0.0.pre → 6.0.0.pre.1
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.
- data/README.md +17 -8
- data/bin/omf_rc_virtual_openflow_switch_factory +83 -0
- data/example/openflow_slice_factory_controller.rb +1 -0
- data/example/openflow_slice_factory_test.rb +1 -1
- data/example/virtual_openflow_switch_factory_controller.rb +33 -0
- data/example/virtual_openflow_switch_factory_test.rb +74 -0
- data/lib/omf_rc/resource_proxy/openflow_slice.rb +1 -1
- data/lib/omf_rc/resource_proxy/openflow_slice_factory.rb +1 -2
- data/lib/omf_rc/resource_proxy/virtual_openflow_switch.rb +143 -0
- data/lib/omf_rc/resource_proxy/virtual_openflow_switch_factory.rb +77 -0
- data/lib/omf_rc/util/{openflow_tools.rb → openflow_slice_tools.rb} +1 -2
- data/lib/omf_rc/util/virtual_openflow_switch_tools.rb +62 -0
- data/lib/omf_rc_openflow.rb +4 -1
- data/lib/omf_rc_openflow/version.rb +1 -1
- data/omf_rc_openflow.gemspec +2 -2
- metadata +15 -7
data/README.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# OmfRcOpenflow
|
2
2
|
|
3
|
-
|
3
|
+
This package includes OMF6 Resource Controllers (RCs) related to the OpenFlow technology.
|
4
|
+
The OMF6 framework considers everything (hardware, software, etc) as a separate resource.
|
5
|
+
This version includes the RCs of the Stanford software tools, named FlowVisor and OpenvSwitch.
|
6
|
+
|
7
|
+
* FlowVisor creates OpenFlow Slices (slicing the flow space into separate pieces), so the corresponding RC is the OpenFlow_Slice_Factory.
|
8
|
+
* OpenvSwitch creates Virtual OpenFlow Switches on top of a Linux machine using the machine's interfaces, so the corresponding RC is the Virtual_OpenFlow_Switch_Factory.
|
4
9
|
|
5
10
|
## Installation
|
6
11
|
|
@@ -18,12 +23,16 @@ Or install it yourself as:
|
|
18
23
|
|
19
24
|
## Usage
|
20
25
|
|
21
|
-
|
26
|
+
In a Linux machine that runs FlowVisor or OpenvSwitch software, execute:
|
27
|
+
|
28
|
+
$ omf_rc_openflow_slice_factory
|
29
|
+
|
30
|
+
Or execute:
|
31
|
+
|
32
|
+
$ omf_rc_virtual_openflow_slice_factory
|
33
|
+
|
34
|
+
to control the FlowVisor or OpenvSwitch resource in a OMF6 Experiment Controller (EC).
|
35
|
+
|
36
|
+
The 'example' subdirectory includes some examples of experiment descriptions, that could be feeded to the omf_ec binary (the OMF6 EC)
|
22
37
|
|
23
|
-
## Contributing
|
24
38
|
|
25
|
-
1. Fork it
|
26
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
-
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require 'omf_rc'
|
5
|
+
require 'omf_rc/resource_factory'
|
6
|
+
require 'omf_rc_openflow'
|
7
|
+
|
8
|
+
$stdout.sync = true
|
9
|
+
|
10
|
+
options = {
|
11
|
+
uid: `hostname`.chomp
|
12
|
+
}
|
13
|
+
|
14
|
+
executable_name = File.basename($PROGRAM_NAME)
|
15
|
+
oml_enabled = false
|
16
|
+
|
17
|
+
begin
|
18
|
+
oml_enabled = OML4R::init(ARGV, :appName => executable_name) do |opts|
|
19
|
+
opts.banner = "usage: #{executable_name} [options]"
|
20
|
+
|
21
|
+
opts.on("-u USER", "Username") do |user|
|
22
|
+
options[:user] = user
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("-p PASSWORD", "Password") do |password|
|
26
|
+
options[:password] = password
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("-s SERVER", "PubSub server") do |server|
|
30
|
+
options[:server] = server
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-t TOPIC", "PubSub topic to create, also becomes the uid of the resource, default to hostname") do |topic|
|
34
|
+
options[:uid] = topic
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on("-d", "--debug", "Debug mode") do
|
38
|
+
options[:debug] = true
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on("-l LOG_FILE_DIR", "Write log file to this folder") do |file_dir|
|
42
|
+
options[:log_file_dir] = file_dir
|
43
|
+
end
|
44
|
+
end
|
45
|
+
rescue => e
|
46
|
+
# Right now OML4R does not raise proper exceptions :(
|
47
|
+
# OML4R requires --oml-noop to be set if we want to run without doing any
|
48
|
+
# measurements... this is too restrictive here, we want to run without OML
|
49
|
+
# if no OML parameters were set and this even if --oml-noop is not set.
|
50
|
+
if e.message.include?('OML4R: Missing values for parameters :expID ')
|
51
|
+
puts "Warning: Missing some OML options to instrument this RC, so it will "+
|
52
|
+
"run without instrumentation. (see --oml-help)"
|
53
|
+
else
|
54
|
+
puts e.message
|
55
|
+
exit(1)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
OmfCommon::Measure.enable if oml_enabled
|
60
|
+
|
61
|
+
unless options[:server] && options[:user] && options[:password]
|
62
|
+
puts "Error: Missing parameters to connect to a PubSub Server (see --help)"
|
63
|
+
exit(1)
|
64
|
+
end
|
65
|
+
|
66
|
+
Logging.logger.root.level = :debug if options[:debug]
|
67
|
+
Blather.logger = logger
|
68
|
+
|
69
|
+
if options[:log_file_dir] && File.exist?(options[:log_file_dir])
|
70
|
+
Logging.logger.root.add_appenders(
|
71
|
+
Logging.appenders.file(
|
72
|
+
"#{options[:log_file_dir]}/omf_rc.log",
|
73
|
+
:layout => Logging.layouts.pattern(:date_pattern => '%F %T %z',
|
74
|
+
:pattern => '[%d] %-5l %c: %m\n')))
|
75
|
+
end
|
76
|
+
|
77
|
+
EM.run do
|
78
|
+
virtual_openflow_switch_factory = OmfRc::ResourceFactory.new(:virtual_openflow_switch_factory, options)
|
79
|
+
virtual_openflow_switch_factory.connect
|
80
|
+
|
81
|
+
trap(:INT) { virtual_openflow_switch_factory.disconnect }
|
82
|
+
trap(:TERM) { virtual_openflow_switch_factory.disconnect }
|
83
|
+
end
|
@@ -19,6 +19,7 @@ opts = {
|
|
19
19
|
|
20
20
|
Logging.logger.root.level = :debug if opts[:debug]
|
21
21
|
|
22
|
+
OmfRc::ResourceFactory.load_addtional_resource_proxies(File.dirname(__FILE__)+"/../lib/omf_rc/util")
|
22
23
|
OmfRc::ResourceFactory.load_addtional_resource_proxies(File.dirname(__FILE__)+"/../lib/omf_rc/resource_proxy")
|
23
24
|
|
24
25
|
EM.run do
|
@@ -15,7 +15,7 @@ msgs = {
|
|
15
15
|
config_slice: @comm.configure_message([name: 'test', contact_email: 'a@a']),
|
16
16
|
slices: @comm.request_message([:slices]),
|
17
17
|
config_flows: @comm.configure_message([flows: [{operation: 'add', device: '00:00:00:00:00:00:00:01', eth_dst: '11:22:33:44:55:66'},
|
18
|
-
{operation: 'add', device:
|
18
|
+
{operation: 'add', device: '00:00:00:00:00:00:00:01', eth_dst: '11:22:33:44:55:77'}]]),
|
19
19
|
}
|
20
20
|
|
21
21
|
@flowvisor_topic.subscribe {msgs[:create_slice].publish @flowvisor_id}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'omf_rc'
|
4
|
+
require 'omf_rc/resource_factory'
|
5
|
+
$stdout.sync = true
|
6
|
+
|
7
|
+
Blather.logger = logger
|
8
|
+
|
9
|
+
opts = {
|
10
|
+
# XMPP server domain
|
11
|
+
server: 'srv.mytestbed.net',
|
12
|
+
user: 'ovs',
|
13
|
+
password: 'pw',
|
14
|
+
uid: 'ovs',
|
15
|
+
# Debug mode of not
|
16
|
+
debug: false
|
17
|
+
}
|
18
|
+
|
19
|
+
Logging.logger.root.level = :debug if opts[:debug]
|
20
|
+
|
21
|
+
OmfRc::ResourceFactory.load_addtional_resource_proxies(File.dirname(__FILE__)+"/../lib/omf_rc/util")
|
22
|
+
OmfRc::ResourceFactory.load_addtional_resource_proxies(File.dirname(__FILE__)+"/../lib/omf_rc/resource_proxy")
|
23
|
+
|
24
|
+
EM.run do
|
25
|
+
# Use resource factory method to initialise a new instance of garage
|
26
|
+
info "Starting #{opts[:uid]}"
|
27
|
+
flowvisor = OmfRc::ResourceFactory.new(:virtual_openflow_switch_factory, opts)
|
28
|
+
flowvisor.connect
|
29
|
+
|
30
|
+
# Disconnect garage from XMPP server, when these two signals received
|
31
|
+
trap(:INT) { flowvisor.disconnect }
|
32
|
+
trap(:TERM) { flowvisor.disconnect }
|
33
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# OMF_VERSIONS = 6.0
|
2
|
+
|
3
|
+
@comm = OmfEc.comm
|
4
|
+
|
5
|
+
# @comm is default communicator defined in script runner
|
6
|
+
#
|
7
|
+
@ovs_id = "ovs"
|
8
|
+
@ovs_topic = @comm.get_topic(@ovs_id)
|
9
|
+
|
10
|
+
@switch_id = nil
|
11
|
+
@switch_topic = nil
|
12
|
+
|
13
|
+
|
14
|
+
msgs = {
|
15
|
+
switches: @comm.request_message([:switches]),
|
16
|
+
create_switch: @comm.create_message([type: 'virtual_openflow_switch']),
|
17
|
+
config_switch_name: @comm.configure_message([name: 'br0']),
|
18
|
+
config_add_port: @comm.configure_message([ports: {operation: 'add', name: 'tun0', type: 'tunnel'}]),
|
19
|
+
request_port: @comm.request_message([port: {information: 'netdev-tunnel/get-port', name: 'tun0'}]),
|
20
|
+
configure_port: @comm.configure_message([port: {name: 'tun0', remote_ip: '138.48.3.201', remote_port: '39505'}]),
|
21
|
+
}
|
22
|
+
|
23
|
+
@ovs_topic.subscribe {msgs[:switches].publish @ovs_id}
|
24
|
+
|
25
|
+
# If flowvisor is not raised, the following rule will be activated.
|
26
|
+
@ovs_topic.on_message lambda {|m| m.operation == :inform && m.read_content('inform_type') == 'CREATION_FAILED' } do |message|
|
27
|
+
logger.error message.read_content('reason')
|
28
|
+
done!
|
29
|
+
end
|
30
|
+
|
31
|
+
msgs[:switches].on_inform_status do |message|
|
32
|
+
logger.info "OVS (#{message.read_property('uid')}) requested switches: #{message.read_property('switches')}"
|
33
|
+
msgs[:create_switch].publish @ovs_id
|
34
|
+
end
|
35
|
+
|
36
|
+
msgs[:create_switch].on_inform_creation_ok do |message|
|
37
|
+
@switch_id = message.resource_id
|
38
|
+
@switch_topic = @comm.get_topic(@switch_id)
|
39
|
+
|
40
|
+
msgs[:release_switch] ||= @comm.release_message {|m| m.element('resource_id', @switch_id)}
|
41
|
+
msgs[:release_switch].on_inform_released do |message|
|
42
|
+
logger.info "Switch (#{@switch_id}) released"
|
43
|
+
m = @comm.request_message([:switches])
|
44
|
+
m.on_inform_status do |message|
|
45
|
+
logger.info "OVS (#{message.read_property('uid')}) requested switches: #{message.read_property('switches')}"
|
46
|
+
done!
|
47
|
+
end
|
48
|
+
m.publish @ovs_id
|
49
|
+
end
|
50
|
+
|
51
|
+
logger.info "Switch (#{@switch_id}) created"
|
52
|
+
@switch_topic.subscribe {msgs[:config_switch_name].publish @switch_id}
|
53
|
+
end
|
54
|
+
|
55
|
+
msgs[:config_switch_name].on_inform_status do |message|
|
56
|
+
logger.info "Switch (#{message.read_property('uid')}) configured name: #{message.read_property('name')}"
|
57
|
+
msgs[:config_add_port].publish @switch_id
|
58
|
+
end
|
59
|
+
|
60
|
+
msgs[:config_add_port].on_inform_status do |message|
|
61
|
+
logger.info "Switch (#{message.read_property('uid')}) configured ports: #{message.read_property('ports')}"
|
62
|
+
msgs[:request_port].publish @switch_id
|
63
|
+
end
|
64
|
+
|
65
|
+
msgs[:request_port].on_inform_status do |message|
|
66
|
+
logger.info "Switch (#{message.read_property('uid')}) requested port: #{message.read_property('port')}"
|
67
|
+
msgs[:configure_port].publish @switch_id
|
68
|
+
end
|
69
|
+
|
70
|
+
msgs[:configure_port].on_inform_status do |message|
|
71
|
+
logger.info "Switch (#{message.read_property('uid')}) configured port: #{message.read_property('port')}"
|
72
|
+
msgs[:release_switch].publish @ovs_id
|
73
|
+
end
|
74
|
+
|
@@ -19,7 +19,7 @@ module OmfRc::ResourceProxy::OpenflowSliceFactory
|
|
19
19
|
|
20
20
|
register_proxy :openflow_slice_factory
|
21
21
|
|
22
|
-
utility :
|
22
|
+
utility :openflow_slice_tools
|
23
23
|
|
24
24
|
|
25
25
|
# Checks if the created child is an :openflow_slice resource and passes the connection arguments that are essential for the connection with flowvisor instance
|
@@ -37,7 +37,6 @@ module OmfRc::ResourceProxy::OpenflowSliceFactory
|
|
37
37
|
opts.property.flowvisor_connection_args = resource.property.flowvisor_connection_args
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
40
|
# A new resource uses the default connection arguments (ip adress, port, etc) to connect with a flowvisor instance
|
42
41
|
hook :before_ready do |resource|
|
43
42
|
resource.property.flowvisor_connection_args = FLOWVISOR_CONNECTION_DEFAULTS
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# This resource is created from the parent :virtual_openflow_switch_factory resource.
|
2
|
+
# It is related with a bridge of an ovsdb-server instance, and behaves as a proxy between experimenter and the actual ovsdb-server bridge.
|
3
|
+
#
|
4
|
+
module OmfRc::ResourceProxy::VirtualOpenflowSwitch
|
5
|
+
include OmfRc::ResourceProxyDSL
|
6
|
+
|
7
|
+
register_proxy :virtual_openflow_switch, :create_by => :virtual_openflow_switch_factory
|
8
|
+
|
9
|
+
utility :virtual_openflow_switch_tools
|
10
|
+
|
11
|
+
|
12
|
+
# Switch name is initiated with value "nil"
|
13
|
+
hook :before_ready do |resource|
|
14
|
+
resource.property.name = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
# Before release, the related ovsdb-server instance should also remove the corresponding switch
|
18
|
+
hook :before_release do |resource|
|
19
|
+
arguments = {
|
20
|
+
"method" => "transact",
|
21
|
+
"params" => [ "Open_vSwitch",
|
22
|
+
{ "op" => "mutate",
|
23
|
+
"table" => "Open_vSwitch",
|
24
|
+
"where" => [],
|
25
|
+
"mutations" => [["bridges", "delete", ["set", [["uuid", resource.property.uuid]]]]]
|
26
|
+
},
|
27
|
+
{ "op" => "delete",
|
28
|
+
"table" => "Bridge",
|
29
|
+
"where" => [["name", "==", resource.property.name]],
|
30
|
+
},
|
31
|
+
{ "op" => "delete",
|
32
|
+
"table" => "Port",
|
33
|
+
"where" => [["name", "==", resource.property.name]]
|
34
|
+
},
|
35
|
+
{ "op" => "delete",
|
36
|
+
"table" => "Interface",
|
37
|
+
"where" => [["name", "==", resource.property.name]]
|
38
|
+
}
|
39
|
+
],
|
40
|
+
"id" => "remove-switch"
|
41
|
+
}
|
42
|
+
resource.ovs_connection("ovsdb-server", arguments)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# Switch name is one-time configured
|
47
|
+
configure :name do |resource, name|
|
48
|
+
raise "The name cannot be changed" if resource.property.name
|
49
|
+
resource.property.name = name.to_s
|
50
|
+
arguments = {
|
51
|
+
"method" => "transact",
|
52
|
+
"params" => [ "Open_vSwitch",
|
53
|
+
{ "op" => "insert",
|
54
|
+
"table" => "Interface",
|
55
|
+
"row" => {"name" => resource.property.name, "type" => "internal"},
|
56
|
+
"uuid-name" => "new_interface"
|
57
|
+
},
|
58
|
+
{ "op" => "insert",
|
59
|
+
"table" => "Port",
|
60
|
+
"row" => {"name" => resource.property.name, "interfaces" => ["named-uuid", "new_interface"]},
|
61
|
+
"uuid-name" => "new_port"
|
62
|
+
},
|
63
|
+
{ "op" => "insert",
|
64
|
+
"table" => "Bridge",
|
65
|
+
"row" => {"name" => resource.property.name, "ports" => ["named-uuid", "new_port"], "datapath_type" => "netdev"},
|
66
|
+
"uuid-name" => "new_bridge"
|
67
|
+
},
|
68
|
+
{ "op" => "mutate",
|
69
|
+
"table" => "Open_vSwitch",
|
70
|
+
"where" => [],
|
71
|
+
"mutations" => [["bridges", "insert", ["set", [["named-uuid", "new_bridge"]]]]]
|
72
|
+
}
|
73
|
+
],
|
74
|
+
"id" => "add-switch"
|
75
|
+
}
|
76
|
+
result = resource.ovs_connection("ovsdb-server", arguments)["result"]
|
77
|
+
raise "The requested switch already existed in ovsdb-server or there is another problem" if result[4]
|
78
|
+
resource.property.uuid = result[2]["uuid"][1]
|
79
|
+
resource.property.name
|
80
|
+
end
|
81
|
+
|
82
|
+
# Add/remove port
|
83
|
+
configure :ports do |resource, array_parameters|
|
84
|
+
array_parameters = [array_parameters] if !array_parameters.kind_of?(Array)
|
85
|
+
array_parameters.each do |parameters|
|
86
|
+
arguments = nil
|
87
|
+
if parameters.operation == "add"
|
88
|
+
arguments = {
|
89
|
+
"method" => "transact",
|
90
|
+
"params" => [ "Open_vSwitch",
|
91
|
+
{ "op" => "insert",
|
92
|
+
"table" => "Interface",
|
93
|
+
"row" => {"name" => parameters.name, "type" => parameters.type},
|
94
|
+
"uuid-name" => "new_interface"
|
95
|
+
},
|
96
|
+
{ "op" => "insert",
|
97
|
+
"table" => "Port",
|
98
|
+
"row" => {"name" => parameters.name, "interfaces" => ["named-uuid", "new_interface"]},
|
99
|
+
"uuid-name" => "new_port"
|
100
|
+
},
|
101
|
+
{ "op" => "mutate",
|
102
|
+
"table" => "Bridge",
|
103
|
+
"where" => [["name", "==", resource.property.name]],
|
104
|
+
"mutations" => [["ports", "insert", ["set", [["named-uuid", "new_port"]]]]]
|
105
|
+
}
|
106
|
+
],
|
107
|
+
"id" => "add-port"
|
108
|
+
}
|
109
|
+
elsif parameters.operation == "remove" # TODO: It is not filled
|
110
|
+
end
|
111
|
+
result = resource.ovs_connection("ovsdb-server", arguments)["result"]
|
112
|
+
raise "The configuration of the switch ports faced a problem" if result[3]
|
113
|
+
end
|
114
|
+
resource.ports
|
115
|
+
end
|
116
|
+
|
117
|
+
# Request port information (XXX: very restrictive, just to support our case)
|
118
|
+
request :port do |resource, parameters|
|
119
|
+
arguments = {
|
120
|
+
"method" => parameters.information,
|
121
|
+
"params" => [parameters.name],
|
122
|
+
"id" => "port-info"
|
123
|
+
}
|
124
|
+
resource.ovs_connection("ovs-vswitchd", arguments)["result"]
|
125
|
+
end
|
126
|
+
|
127
|
+
# Configure port (XXX: very restrictive, just to support our case)
|
128
|
+
configure :port do |resource, parameters|
|
129
|
+
arguments = {
|
130
|
+
"method" => "transact",
|
131
|
+
"params" => [ "Open_vSwitch",
|
132
|
+
{ "op" => "mutate",
|
133
|
+
"table" => "Interface",
|
134
|
+
"where" => [["name", "==", parameters.name]],
|
135
|
+
"mutations" => [["options", "insert", ["map",
|
136
|
+
[["remote_ip", parameters.remote_ip], ["remote_port", parameters.remote_port.to_s]]]]]
|
137
|
+
}
|
138
|
+
],
|
139
|
+
"id" => "configure-port"
|
140
|
+
}
|
141
|
+
resource.ovs_connection("ovsdb-server", arguments)["result"]
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# This resourse is related with an ovsdb-server (interface of an OVSDB database) and behaves as a proxy between experimenter and this.
|
2
|
+
#
|
3
|
+
module OmfRc::ResourceProxy::VirtualOpenflowSwitchFactory
|
4
|
+
include OmfRc::ResourceProxyDSL
|
5
|
+
|
6
|
+
# The default arguments of the communication between this resource and the ovsdb-server
|
7
|
+
OVS_CONNECTION_DEFAULTS = {
|
8
|
+
ovsdb_server_host: "localhost",
|
9
|
+
ovsdb_server_port: "6635",
|
10
|
+
ovsdb_server_socket: "/usr/local/var/run/openvswitch/db.sock",
|
11
|
+
ovsdb_server_conn: "unix", # default "unix" between "tcp" and "unix"
|
12
|
+
ovs_vswitchd_pid: "/usr/local/var/run/openvswitch/ovs-vswitchd.pid",
|
13
|
+
ovs_vswitchd_socket: "/usr/local/var/run/openvswitch/ovs-vswitchd.%s.ctl",
|
14
|
+
ovs_vswitchd_conn: "unix" #default "unix"
|
15
|
+
}
|
16
|
+
|
17
|
+
|
18
|
+
register_proxy :virtual_openflow_switch_factory
|
19
|
+
|
20
|
+
utility :virtual_openflow_switch_tools
|
21
|
+
|
22
|
+
|
23
|
+
# Checks if the created child is an :virtual_openflow_switch resource and passes the connection arguments
|
24
|
+
hook :before_create do |resource, type, opts = nil|
|
25
|
+
if type.to_sym != :virtual_openflow_switch
|
26
|
+
raise "This resource doesn't create resources of type "+type
|
27
|
+
end
|
28
|
+
begin
|
29
|
+
arguments = {
|
30
|
+
"method" => "list_dbs",
|
31
|
+
"params" => [],
|
32
|
+
"id" => "list_dbs"
|
33
|
+
}
|
34
|
+
resource.ovs_connection("ovsdb-server", arguments)
|
35
|
+
rescue
|
36
|
+
raise "This resource is not connected with an ovsdb-server instance, so it cannot create virtual openflow switches"
|
37
|
+
end
|
38
|
+
opts.property ||= Hashie::Mash.new
|
39
|
+
opts.property.provider = ">> #{resource.uid}"
|
40
|
+
opts.property.ovs_connection_args = resource.property.ovs_connection_args
|
41
|
+
end
|
42
|
+
|
43
|
+
# A new resource uses the default connection arguments (ip adress, port, socket, etc) to connect with a ovsdb-server instance
|
44
|
+
hook :before_ready do |resource|
|
45
|
+
resource.property.ovs_connection_args = OVS_CONNECTION_DEFAULTS
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
# Configures the ovsdb-server connection arguments (ip adress, port, socket, etc)
|
50
|
+
configure :ovs_connection do |resource, ovs_connection_args|
|
51
|
+
raise "Connection with a new ovsdb-server instance is not allowed if there exist created switches" if !resource.children.empty?
|
52
|
+
resource.property.ovs_connection_args.update(ovs_connection_args)
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
# Returns the ovsdb-server connection arguments (ip adress, port, socket, etc)
|
57
|
+
request :ovs_connection do |resource|
|
58
|
+
resource.property.ovs_connection_args
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns a list of virtual openflow switches, that correspond to the ovsdb-server bridges.
|
62
|
+
request :switches do |resource|
|
63
|
+
arguments = {
|
64
|
+
"method" => "transact",
|
65
|
+
"params" => [ "Open_vSwitch",
|
66
|
+
{ "op" => "select",
|
67
|
+
"table" => "Bridge",
|
68
|
+
"where" => [],
|
69
|
+
"columns" => ["name"]
|
70
|
+
}
|
71
|
+
],
|
72
|
+
"id" => "switches"
|
73
|
+
}
|
74
|
+
result = resource.ovs_connection("ovsdb-server", arguments)["result"]
|
75
|
+
result[0]["rows"].map {|hash_name| hash_name["name"]}
|
76
|
+
end
|
77
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'xmlrpc/client'
|
2
2
|
|
3
|
-
module OmfRc::Util::
|
3
|
+
module OmfRc::Util::OpenflowSliceTools
|
4
4
|
include OmfRc::ResourceProxyDSL
|
5
5
|
|
6
6
|
# The version of the flowvisor that this resource is able to control
|
@@ -71,7 +71,6 @@ module OmfRc::Util::OpenflowTools
|
|
71
71
|
end
|
72
72
|
|
73
73
|
work :transformed_parameters do |resource, parameters|
|
74
|
-
|
75
74
|
match = []
|
76
75
|
FLOW_MATCH_FEATURES.each do |feature|
|
77
76
|
match << "#{feature}=#{parameters[feature]}" if parameters[feature]
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module OmfRc::Util::VirtualOpenflowSwitchTools
|
2
|
+
include OmfRc::ResourceProxyDSL
|
3
|
+
|
4
|
+
# Internal function that returns a hash result of the json-request to the ovsdb-server or the ovs-switchd instances
|
5
|
+
work :ovs_connection do |resource, target, arguments|
|
6
|
+
stream = nil
|
7
|
+
if target == "ovsdb-server"
|
8
|
+
if resource.property.ovs_connection_args.ovsdb_server_conn == "tcp"
|
9
|
+
stream = TCPSocket.new(resource.property.ovs_connection_args.ovsdb_server_host,
|
10
|
+
resource.property.ovs_connection_args.ovsdb_server_port)
|
11
|
+
elsif resource.property.ovs_connection_args.ovsdb_server_conn == "unix"
|
12
|
+
stream = UNIXSocket.new(resource.property.ovs_connection_args.ovsdb_server_socket)
|
13
|
+
end
|
14
|
+
elsif target == "ovs-vswitchd"
|
15
|
+
if resource.property.ovs_connection_args.ovs_vswitchd_conn == "unix"
|
16
|
+
file = File.new(resource.property.ovs_connection_args.ovs_vswitchd_pid, "r")
|
17
|
+
pid = file.gets.chomp
|
18
|
+
file.close
|
19
|
+
socket = resource.property.ovs_connection_args.ovs_vswitchd_socket % [pid]
|
20
|
+
stream = UNIXSocket.new(socket)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
stream.puts(arguments.to_json)
|
24
|
+
string = stream.gets('{')
|
25
|
+
counter = 1 # number of read '['
|
26
|
+
while counter > 0
|
27
|
+
char = stream.getc
|
28
|
+
if char == '{'
|
29
|
+
counter += 1
|
30
|
+
elsif char == '}'
|
31
|
+
counter -= 1
|
32
|
+
end
|
33
|
+
string += char
|
34
|
+
end
|
35
|
+
stream.close
|
36
|
+
JSON.parse(string)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Internal function that returns the ports of a specific switch
|
40
|
+
work :ports do |resource|
|
41
|
+
arguments = {
|
42
|
+
"method" => "transact",
|
43
|
+
"params" => [ "Open_vSwitch",
|
44
|
+
{ "op" => "select",
|
45
|
+
"table" => "Bridge",
|
46
|
+
"where" => [["name", "==", resource.property.name]],
|
47
|
+
"columns" => ["ports"]
|
48
|
+
},
|
49
|
+
{ "op" => "select",
|
50
|
+
"table" => "Port",
|
51
|
+
"where" => [],
|
52
|
+
"columns" => ["name", "_uuid"]
|
53
|
+
}
|
54
|
+
],
|
55
|
+
"id" => "ports"
|
56
|
+
}
|
57
|
+
result = resource.ovs_connection("ovsdb-server", arguments)["result"]
|
58
|
+
uuid2name = Hash[result[1]["rows"].map {|hash_uuid_name| [hash_uuid_name["_uuid"][1], hash_uuid_name["name"]]}]
|
59
|
+
uuids = result[0]["rows"][0]["ports"][1].map {|array_uuid| array_uuid[1]}
|
60
|
+
uuids.map {|v| uuid2name[v]}
|
61
|
+
end
|
62
|
+
end
|
data/lib/omf_rc_openflow.rb
CHANGED
@@ -2,4 +2,7 @@ require "omf_rc_openflow/version"
|
|
2
2
|
|
3
3
|
require 'omf_rc/resource_proxy/openflow_slice_factory.rb'
|
4
4
|
require 'omf_rc/resource_proxy/openflow_slice.rb'
|
5
|
-
require 'omf_rc/util/
|
5
|
+
require 'omf_rc/util/openflow_slice_tools.rb'
|
6
|
+
require 'omf_rc/resource_proxy/virtual_openflow_switch_factory.rb'
|
7
|
+
require 'omf_rc/resource_proxy/virtual_openflow_switch.rb'
|
8
|
+
require 'omf_rc/util/virtual_openflow_switch_tools.rb'
|
data/omf_rc_openflow.gemspec
CHANGED
@@ -4,8 +4,8 @@ require File.expand_path('../lib/omf_rc_openflow/version', __FILE__)
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.authors = ["Kostas Choumas"]
|
6
6
|
gem.email = ["kohoumas@gmail.com"]
|
7
|
-
gem.description = %q{
|
8
|
-
gem.summary = %q{
|
7
|
+
gem.description = %q{OMF6 Resource Controllers related to the Openflow technology}
|
8
|
+
gem.summary = %q{OMF6 Resource Controllers related to the Openflow technology, including the Stanford software tools named FlowVisor and OpenvSwitch}
|
9
9
|
gem.homepage = "http://nitlab.inf.uth.gr"
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omf_rc_openflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.0.pre
|
4
|
+
version: 6.0.0.pre.1
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: omf_rc
|
16
|
-
requirement: &
|
16
|
+
requirement: &20646460 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,12 +21,13 @@ dependencies:
|
|
21
21
|
version: 6.0.0.pre
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
description:
|
24
|
+
version_requirements: *20646460
|
25
|
+
description: OMF6 Resource Controllers related to the Openflow technology
|
26
26
|
email:
|
27
27
|
- kohoumas@gmail.com
|
28
28
|
executables:
|
29
29
|
- omf_rc_openflow_slice_factory
|
30
|
+
- omf_rc_virtual_openflow_switch_factory
|
30
31
|
extensions: []
|
31
32
|
extra_rdoc_files: []
|
32
33
|
files:
|
@@ -36,11 +37,17 @@ files:
|
|
36
37
|
- README.md
|
37
38
|
- Rakefile
|
38
39
|
- bin/omf_rc_openflow_slice_factory
|
40
|
+
- bin/omf_rc_virtual_openflow_switch_factory
|
39
41
|
- example/openflow_slice_factory_controller.rb
|
40
42
|
- example/openflow_slice_factory_test.rb
|
43
|
+
- example/virtual_openflow_switch_factory_controller.rb
|
44
|
+
- example/virtual_openflow_switch_factory_test.rb
|
41
45
|
- lib/omf_rc/resource_proxy/openflow_slice.rb
|
42
46
|
- lib/omf_rc/resource_proxy/openflow_slice_factory.rb
|
43
|
-
- lib/omf_rc/
|
47
|
+
- lib/omf_rc/resource_proxy/virtual_openflow_switch.rb
|
48
|
+
- lib/omf_rc/resource_proxy/virtual_openflow_switch_factory.rb
|
49
|
+
- lib/omf_rc/util/openflow_slice_tools.rb
|
50
|
+
- lib/omf_rc/util/virtual_openflow_switch_tools.rb
|
44
51
|
- lib/omf_rc_openflow.rb
|
45
52
|
- lib/omf_rc_openflow/version.rb
|
46
53
|
- omf_rc_openflow.gemspec
|
@@ -67,6 +74,7 @@ rubyforge_project:
|
|
67
74
|
rubygems_version: 1.8.11
|
68
75
|
signing_key:
|
69
76
|
specification_version: 3
|
70
|
-
summary:
|
77
|
+
summary: OMF6 Resource Controllers related to the Openflow technology, including the
|
78
|
+
Stanford software tools named FlowVisor and OpenvSwitch
|
71
79
|
test_files: []
|
72
80
|
has_rdoc:
|