omf_rc_openflow 6.0.0.pre

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/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in omf_rc_foo.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Jack C Hong
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # OmfRcOpenflow
2
+
3
+ OMF Resource Controllers related to Openflow
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'omf_rc_openflow'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install omf_rc_openflow
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
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
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -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
+ openflow_slice_factory = OmfRc::ResourceFactory.new(:openflow_slice_factory, options)
79
+ openflow_slice_factory.connect
80
+
81
+ trap(:INT) { openflow_slice_factory.disconnect }
82
+ trap(:TERM) { openflow_slice_factory.disconnect }
83
+ end
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'omf_rc'
4
+ require 'omf_rc/resource_factory'
5
+ #require 'omf_rc_openflow'
6
+ $stdout.sync = true
7
+
8
+ Blather.logger = logger
9
+
10
+ opts = {
11
+ # XMPP server domain
12
+ server: 'srv.mytestbed.net',
13
+ user: 'flowvisor',
14
+ password: 'pw',
15
+ uid: 'flowvisor',
16
+ # Debug mode of not
17
+ debug: false
18
+ }
19
+
20
+ Logging.logger.root.level = :debug if opts[:debug]
21
+
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(:openflow_slice_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,64 @@
1
+ # OMF_VERSIONS = 6.0
2
+
3
+ @comm = OmfEc.comm
4
+
5
+ # @comm is default communicator defined in script runner
6
+ #
7
+ @flowvisor_id = "flowvisor"
8
+ @flowvisor_topic = @comm.get_topic(@flowvisor_id)
9
+
10
+ @slice_id = nil
11
+ @slice_topic = nil
12
+
13
+ msgs = {
14
+ create_slice: @comm.create_message([type: 'openflow_slice']),
15
+ config_slice: @comm.configure_message([name: 'test', contact_email: 'a@a']),
16
+ slices: @comm.request_message([:slices]),
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: 1, in_port: 10}]]),
19
+ }
20
+
21
+ @flowvisor_topic.subscribe {msgs[:create_slice].publish @flowvisor_id}
22
+
23
+ # If flowvisor is not raised, the following rule will be activated.
24
+ @flowvisor_topic.on_message lambda {|m| m.operation == :inform && m.read_content('inform_type') == 'CREATION_FAILED' } do |message|
25
+ logger.error message.read_content('reason')
26
+ done!
27
+ end
28
+
29
+ msgs[:create_slice].on_inform_creation_ok do |message|
30
+ @slice_id = message.resource_id
31
+ @slice_topic = @comm.get_topic(@slice_id)
32
+
33
+ msgs[:release_slice] ||= @comm.release_message {|m| m.element('resource_id', @slice_id)}
34
+ msgs[:release_slice].on_inform_released do |message|
35
+ logger.info "Slice (#{@slice_id}) released"
36
+ m = @comm.request_message([:slices])
37
+ m.on_inform_status do |message|
38
+ logger.info "Flowvisor (#{message.read_property('uid')}) requested slices: #{message.read_property('slices').join(', ')}"
39
+ done!
40
+ end
41
+ m.publish @flowvisor_id
42
+ end
43
+
44
+ logger.info "Slice (#{@slice_id}) created"
45
+ @slice_topic.subscribe {msgs[:config_slice].publish @slice_id}
46
+ end
47
+
48
+ msgs[:config_slice].on_inform_status do |message|
49
+ logger.info "Slice (#{message.read_property('uid')}) configured name: #{message.read_property('name')} & contact_email: #{message.read_property('contact_email')}"
50
+ msgs[:slices].publish @flowvisor_id
51
+ end
52
+
53
+ msgs[:slices].on_inform_status do |message|
54
+ logger.info "Flowvisor (#{message.read_property('uid')}) requested slices: #{message.read_property('slices').join(', ')}"
55
+ msgs[:config_flows].publish @slice_id
56
+ end
57
+
58
+ msgs[:config_flows].on_inform_status do |message|
59
+ logger.info "Slice (#{message.read_property('uid')}) configured flows: "
60
+ message.read_property('flows').each do |flow|
61
+ logger.info " #{flow}"
62
+ end
63
+ msgs[:release_slice].publish @flowvisor_id
64
+ end
@@ -0,0 +1,82 @@
1
+ # This resource is created from the parent :openflow_slice_factory resource.
2
+ # It is related with a slice of a flowvisor instance, and behaves as a proxy between experimenter and the actual flowvisor slice.
3
+ #
4
+ module OmfRc::ResourceProxy::OpenflowSlice
5
+ include OmfRc::ResourceProxyDSL
6
+
7
+ # The default parameters of a new slice. The openflow controller is assumed to be in the same working station with flowvisor instance
8
+ SLICE_DEFAULTS = {
9
+ passwd: "1234",
10
+ url: "tcp:127.0.0.1:9933",
11
+ email: "nothing@nowhere"
12
+ }
13
+
14
+
15
+ register_proxy :openflow_slice, :create_by => :openflow_slice_factory
16
+
17
+ utility :openflow_tools
18
+
19
+
20
+ # Slice's name is initiated with value "nil"
21
+ hook :before_ready do |resource|
22
+ resource.property.name = nil
23
+ end
24
+
25
+ # Before release, the related flowvisor instance should also remove the corresponding slice
26
+ hook :before_release do |resource|
27
+ resource.flowvisor_connection.call("api.deleteSlice", resource.property.name)
28
+ end
29
+
30
+
31
+ # The name is one-time configured
32
+ configure :name do |resource, name|
33
+ raise "The name cannot be changed" if resource.property.name
34
+ resource.property.name = name.to_s
35
+ begin
36
+ resource.flowvisor_connection.call("api.createSlice", name.to_s, *SLICE_DEFAULTS.values)
37
+ rescue Exception => e
38
+ if e.message["Cannot create slice with existing name"]
39
+ logger.warn message = "The requested slice already existed in Flowvisor"
40
+ else
41
+ raise e
42
+ end
43
+ end
44
+ resource.property.name
45
+ end
46
+
47
+ # Configures the slice password
48
+ configure :passwd do |resource, passwd|
49
+ resource.flowvisor_connection.call("api.changePasswd", resource.property.name, passwd.to_s)
50
+ passwd.to_s
51
+ end
52
+
53
+ # Configures the slice parameters
54
+ [:contact_email, :drop_policy, :controller_hostname, :controller_port].each do |configure_sym|
55
+ configure configure_sym do |resource, value|
56
+ resource.flowvisor_connection.call("api.changeSlice", resource.property.name, configure_sym.to_s, value.to_s)
57
+ value.to_s
58
+ end
59
+ end
60
+
61
+ # Adds/removes a flow to this slice, specified by device, port, etc.
62
+ configure :flows do |resource, array_parameters|
63
+ array_parameters = [array_parameters] if !array_parameters.kind_of?(Array)
64
+ array_parameters.each do |parameters|
65
+ resource.flowvisor_connection.call("api.changeFlowSpace", resource.transformed_parameters(parameters))
66
+ end
67
+ resource.flows
68
+ end
69
+
70
+
71
+ # Returns a hash table with the name of this slice, its controller (ip and port) and other related information
72
+ request :info do |resource|
73
+ result = resource.flowvisor_connection.call("api.getSliceInfo", resource.property.name)
74
+ result[:name] = resource.property.name
75
+ result
76
+ end
77
+
78
+ # Returns a string with statistics about the use of this slice
79
+ request :stats do |resource|
80
+ resource.flowvisor_connection.call("api.getSliceStats", resource.property.name)
81
+ end
82
+ end
@@ -0,0 +1,72 @@
1
+ # This resourse is related with a flowvisor instance and behaves as a proxy between experimenter and flowvisor.
2
+ #
3
+ module OmfRc::ResourceProxy::OpenflowSliceFactory
4
+ include OmfRc::ResourceProxyDSL
5
+
6
+ # The default arguments of the communication between this resource and the flowvisor instance
7
+ FLOWVISOR_CONNECTION_DEFAULTS = {
8
+ host: "localhost",
9
+ path: "/xmlrc",
10
+ port: "8080",
11
+ proxy_host: nil,
12
+ proxy_port: nil,
13
+ user: "fvadmin",
14
+ password: "openflow",
15
+ use_ssl: "true",
16
+ timeout: nil
17
+ }
18
+
19
+
20
+ register_proxy :openflow_slice_factory
21
+
22
+ utility :openflow_tools
23
+
24
+
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
26
+ hook :before_create do |resource, type, opts = nil|
27
+ if type.to_sym != :openflow_slice
28
+ raise "This resource doesn't create resources of type "+type
29
+ end
30
+ begin
31
+ resource.flowvisor_connection
32
+ rescue
33
+ raise "This resource is not connected with a flowvisor instance, so it cannot create openflow slices"
34
+ end
35
+ opts.property ||= Hashie::Mash.new
36
+ opts.property.provider = ">> #{resource.uid}"
37
+ opts.property.flowvisor_connection_args = resource.property.flowvisor_connection_args
38
+ end
39
+
40
+
41
+ # A new resource uses the default connection arguments (ip adress, port, etc) to connect with a flowvisor instance
42
+ hook :before_ready do |resource|
43
+ resource.property.flowvisor_connection_args = FLOWVISOR_CONNECTION_DEFAULTS
44
+ end
45
+
46
+
47
+ # Configures the flowvisor connection arguments (ip adress, port, etc)
48
+ configure :flowvisor_connection do |resource, flowvisor_connection_args|
49
+ raise "Connection with a new flowvisor instance is not allowed if there exist created slices" if !resource.children.empty?
50
+ resource.property.flowvisor_connection_args.update(flowvisor_connection_args)
51
+ end
52
+
53
+
54
+ # Returns the flowvisor connection arguments (ip adress, port, etc)
55
+ request :flowvisor_connection do |resource|
56
+ resource.property.flowvisor_connection_args
57
+ end
58
+
59
+ # Returns a list of the existed slices or the connected devices
60
+ {:slices => "listSlices", :devices => "listDevices"}.each do |request_sym, handler_name|
61
+ request request_sym do |resource|
62
+ resource.flowvisor_connection.call("api.#{handler_name}")
63
+ end
64
+ end
65
+
66
+ # Returns information or statistics for a device specified by the given id
67
+ {:device_info => "getDeviceInfo", :device_stats => "getSwitchStats"}.each do |request_sym, handler_name|
68
+ request request_sym do |resource, device|
69
+ resource.flowvisor_connection.call("api.#{handler_name}", device.to_s)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,103 @@
1
+ require 'xmlrpc/client'
2
+
3
+ module OmfRc::Util::OpenflowTools
4
+ include OmfRc::ResourceProxyDSL
5
+
6
+ # The version of the flowvisor that this resource is able to control
7
+ FLOWVISOR_VERSION = "FV version=flowvisor-0.8.4"
8
+
9
+ # Parts of the regular expression that describes a flow entry for flowvisor
10
+ FLOWVISOR_FLOWENTRY_REGEXP_DEVIDED = [
11
+ /dpid=\[(?<device>.+)\]/,
12
+ /ruleMatch=\[OFMatch\[(?<match>.+)\]\]/,
13
+ /actionsList=\[Slice:(?<slice>.+)=(?<actions>.+)\]/,
14
+ /id=\[(?<id>.+)\]/,
15
+ /priority=\[(?<priority>.+)\]/
16
+ ]
17
+
18
+ # The regular expression that describes a flow entry for flowvisor
19
+ FLOWVISOR_FLOWENTRY_REGEXP = /FlowEntry\[#{FLOWVISOR_FLOWENTRY_REGEXP_DEVIDED.join(',')},\]/
20
+
21
+ # The names of the flow (or flow entry) features
22
+ FLOW_FEATURES = %w{device match slice actions id priority}
23
+
24
+ # The names of the flow (or flow entry) features that are specified by the "match" feature
25
+ FLOW_MATCH_FEATURES = %w{in_port eth_src eth_dst ip_src ip_dst}
26
+
27
+ # The default features of a new flow (or flow entry)
28
+ FLOW_DEFAULTS = {
29
+ priority: "10",
30
+ actions: "4"
31
+ }
32
+
33
+
34
+ # Returns the flows (flow entries) that exist for this flowvisor
35
+ request :flows do |resource, filter = nil|
36
+ resource.flows(filter)
37
+ end
38
+
39
+
40
+ # Internal function that creates a connection with a flowvisor instance and checks it
41
+ work :flowvisor_connection do |resource|
42
+ xmlrpc_client = XMLRPC::Client.new_from_hash(resource.property.flowvisor_connection_args)
43
+ xmlrpc_client.instance_variable_get("@http").verify_mode = OpenSSL::SSL::VERIFY_NONE
44
+ ping_msg = "test"
45
+ pong_msg = "PONG(#{resource.property.flowvisor_connection_args[:user]}): #{FLOWVISOR_VERSION}::#{ping_msg}"
46
+ raise "Connection with #{FLOWVISOR_VERSION} was not successful" if xmlrpc_client.call("api.ping", ping_msg) != pong_msg
47
+ xmlrpc_client
48
+ end
49
+
50
+ # Internal function that returns the flows (flow entries) that exist in the connected flowvisor instance
51
+ work :flows do |resource, filter = nil|
52
+ result = resource.flowvisor_connection.call("api.listFlowSpace")
53
+ result.map! do |line|
54
+ array_values = line.match(FLOWVISOR_FLOWENTRY_REGEXP)[1..-1]
55
+ # Example of above array's content: %w{00:00:...:01 in_port=1 test 4 30 10}
56
+ array_features_values_zipped = FLOW_FEATURES.zip(array_values)
57
+ # Example of above array's content: %w{device 00:00:...:01 match in_port=1 slice test actions 4 id 30 priority 10}
58
+ hash = Hashie::Mash.new(Hash[array_features_values_zipped])
59
+ # The following code adds extra features that are specified by the "match" feature
60
+ hash["match"].split(",").each do |couple|
61
+ array = couple.split("=")
62
+ hash[array[0]] = array[1]
63
+ end
64
+ hash
65
+ end
66
+ result.delete_if {|hash| hash["slice"] != resource.property.name} if resource.type.to_sym == :openflow_slice
67
+ FLOW_FEATURES.each do |feature|
68
+ result.delete_if {|hash| hash[feature] != filter[feature].to_s} if filter[feature]
69
+ end if filter
70
+ result
71
+ end
72
+
73
+ work :transformed_parameters do |resource, parameters|
74
+
75
+ match = []
76
+ FLOW_MATCH_FEATURES.each do |feature|
77
+ match << "#{feature}=#{parameters[feature]}" if parameters[feature]
78
+ end
79
+ match = match.join(",")
80
+
81
+ result = []
82
+ case parameters.operation
83
+ when "add"
84
+ h = Hashie::Mash.new
85
+ h.operation = parameters.operation.upcase
86
+ h.priority = parameters.priority ? parameters.priority.to_s : FLOW_DEFAULTS[:priority]
87
+ h.dpid = parameters.device.to_s
88
+ h.actions = "Slice:#{resource.property.name}=#{(parameters.actions ? parameters.actions : FLOW_DEFAULTS[:actions])}"
89
+ h.match = "OFMatch[#{match}]"
90
+ result << h
91
+ when "remove"
92
+ resource.flows(parameters).each do |f|
93
+ if f.match == match
94
+ h = Hashie::Mash.new
95
+ h.operation = parameters.operation.upcase
96
+ h.id = f.id
97
+ result << h
98
+ end
99
+ end
100
+ end
101
+ result
102
+ end
103
+ end
@@ -0,0 +1,3 @@
1
+ module OmfRcOpenflow
2
+ VERSION = "6.0.0.pre"
3
+ end
@@ -0,0 +1,5 @@
1
+ require "omf_rc_openflow/version"
2
+
3
+ require 'omf_rc/resource_proxy/openflow_slice_factory.rb'
4
+ require 'omf_rc/resource_proxy/openflow_slice.rb'
5
+ require 'omf_rc/util/openflow_tools.rb'
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/omf_rc_openflow/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Kostas Choumas"]
6
+ gem.email = ["kohoumas@gmail.com"]
7
+ gem.description = %q{OMF Resource Controllers related to Openflow}
8
+ gem.summary = %q{OMF Resource Controllers related to Openflow}
9
+ gem.homepage = "http://nitlab.inf.uth.gr"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "omf_rc_openflow"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = OmfRcOpenflow::VERSION
17
+ gem.add_runtime_dependency "omf_rc", "~> 6.0.0.pre"
18
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omf_rc_openflow
3
+ version: !ruby/object:Gem::Version
4
+ version: 6.0.0.pre
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Kostas Choumas
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: omf_rc
16
+ requirement: &20473800 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 6.0.0.pre
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *20473800
25
+ description: OMF Resource Controllers related to Openflow
26
+ email:
27
+ - kohoumas@gmail.com
28
+ executables:
29
+ - omf_rc_openflow_slice_factory
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - bin/omf_rc_openflow_slice_factory
39
+ - example/openflow_slice_factory_controller.rb
40
+ - example/openflow_slice_factory_test.rb
41
+ - lib/omf_rc/resource_proxy/openflow_slice.rb
42
+ - lib/omf_rc/resource_proxy/openflow_slice_factory.rb
43
+ - lib/omf_rc/util/openflow_tools.rb
44
+ - lib/omf_rc_openflow.rb
45
+ - lib/omf_rc_openflow/version.rb
46
+ - omf_rc_openflow.gemspec
47
+ homepage: http://nitlab.inf.uth.gr
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>'
63
+ - !ruby/object:Gem::Version
64
+ version: 1.3.1
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 1.8.11
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: OMF Resource Controllers related to Openflow
71
+ test_files: []
72
+ has_rdoc: