omf_rc_openflow 6.0.0.pre → 6.0.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|