diff --git a/README.md b/README.md index 93e2f1d..5ec6c3a 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,11 @@ Or install it yourself as: In a Linux machine that runs FlowVisor or OpenvSwitch software, execute: - $ omf_rc_openflow_slice_factory + $ omf_rc_openflow_slice_factory -u xmpp://user:password@domain -i topic Or execute: - $ omf_rc_virtual_openflow_slice_factory + $ omf_rc_virtual_openflow_slice_factory -u xmpp://user:password@domain -i topic to control the FlowVisor or OpenvSwitch resource in a OMF6 Experiment Controller (EC). diff --git a/bin/omf_rc_openflow_slice_factory b/bin/omf_rc_openflow_slice_factory index 34c3dff..78e9d21 100755 --- a/bin/omf_rc_openflow_slice_factory +++ b/bin/omf_rc_openflow_slice_factory @@ -1,45 +1,40 @@ #!/usr/bin/env ruby -require "optparse" +require 'optparse' +require 'erb' + require 'omf_rc' require 'omf_rc/resource_factory' require 'omf_rc_openflow' $stdout.sync = true - -options = { - uid: `hostname`.chomp -} - +options = {} executable_name = File.basename($PROGRAM_NAME) oml_enabled = false +gem_version = Gem::Specification.find_by_name('omf_rc_openflow').version.to_s begin oml_enabled = OML4R::init(ARGV, :appName => executable_name) do |opts| opts.banner = "usage: #{executable_name} [options]" - opts.on("-u USER", "Username") do |user| - options[:user] = user + opts.on("-c CONFIGFILE", "Configuration File") do |file| + options[:configfile] = file end - opts.on("-p PASSWORD", "Password") do |password| - options[:password] = password + opts.on("-a ADVANCED_CONFIGFILE", "Advanced Configuration File") do |file| + options[:advanced_configfile] = file end - opts.on("-s SERVER", "PubSub server") do |server| - options[:server] = server + opts.on("-u URI", "Communication URI (xmpp://user:password@domain)") do |uri| + options[:uri] = uri end - opts.on("-t TOPIC", "PubSub topic to create, also becomes the uid of the resource, default to hostname") do |topic| - options[:uid] = topic + opts.on("-e ENVIRONMENT", "Environment (development, production ...)") do |environment| + options[:environment] = environment end - opts.on("-d", "--debug", "Debug mode") do - options[:debug] = true - end - - opts.on("-l LOG_FILE_DIR", "Write log file to this folder") do |file_dir| - options[:log_file_dir] = file_dir + opts.on("-i UID", "UID of the resource, also becomes the pubsub topic of the resource, default to hostname") do |uid| + options[:uid] = uid end end rescue => e @@ -56,28 +51,47 @@ rescue => e end end +if !options[:configfile].nil? + cfg_options = YAML.load(ERB.new(File.read(options[:configfile])).result) + options = cfg_options.merge(options) +end + +options[:uid] ||=`hostname`.chomp + OmfCommon::Measure.enable if oml_enabled -unless options[:server] && options[:user] && options[:password] +options[:environment] ||= :development + +if options[:uri] + common_options = { communication: { url: options[:uri] } } +else + common_options = {} +end + +if !options[:advanced_configfile].nil? + a_cfg_options = (YAML.load_file(options[:advanced_configfile])) + common_options = a_cfg_options.merge(common_options) +end + +unless common_options[:communication] && common_options[:communication][:url] puts "Error: Missing parameters to connect to a PubSub Server (see --help)" exit(1) end -Logging.logger.root.level = :debug if options[:debug] -Blather.logger = logger +resource_options = { + uid: options[:uid] +} -if options[:log_file_dir] && File.exist?(options[:log_file_dir]) - Logging.logger.root.add_appenders( - Logging.appenders.file( - "#{options[:log_file_dir]}/omf_rc.log", - :layout => Logging.layouts.pattern(:date_pattern => '%F %T %z', - :pattern => '[%d] %-5l %c: %m\n'))) -end +#OmfRc::ResourceFactory.load_default_resource_proxies -EM.run do - openflow_slice_factory = OmfRc::ResourceFactory.new(:openflow_slice_factory, options) - openflow_slice_factory.connect +OmfCommon.init(options[:environment].to_sym, common_options) do |el| + info "Starting OMF Resource Controller for OpenFlow Slice factory (FlowVisor) version '#{gem_version}'" - trap(:INT) { openflow_slice_factory.disconnect } - trap(:TERM) { openflow_slice_factory.disconnect } + OmfCommon.comm.on_connected do |comm| + info "Connected as #{comm.jid}" if comm.jid + res = OmfRc::ResourceFactory.create(:openflow_slice_factory, resource_options) + + comm.on_interrupted { res.disconnect } + end end +info "Stopping OMF Resource Controller for OpenFlow slice factory version '#{gem_version}'" diff --git a/bin/omf_rc_virtual_openflow_switch_factory b/bin/omf_rc_virtual_openflow_switch_factory index 807b314..a0b988b 100755 --- a/bin/omf_rc_virtual_openflow_switch_factory +++ b/bin/omf_rc_virtual_openflow_switch_factory @@ -1,45 +1,40 @@ #!/usr/bin/env ruby -require "optparse" +require 'optparse' +require 'erb' + require 'omf_rc' require 'omf_rc/resource_factory' require 'omf_rc_openflow' $stdout.sync = true - -options = { - uid: `hostname`.chomp -} - +options = {} executable_name = File.basename($PROGRAM_NAME) oml_enabled = false +gem_version = Gem::Specification.find_by_name('omf_rc_openflow').version.to_s begin oml_enabled = OML4R::init(ARGV, :appName => executable_name) do |opts| opts.banner = "usage: #{executable_name} [options]" - opts.on("-u USER", "Username") do |user| - options[:user] = user + opts.on("-c CONFIGFILE", "Configuration File") do |file| + options[:configfile] = file end - opts.on("-p PASSWORD", "Password") do |password| - options[:password] = password + opts.on("-a ADVANCED_CONFIGFILE", "Advanced Configuration File") do |file| + options[:advanced_configfile] = file end - opts.on("-s SERVER", "PubSub server") do |server| - options[:server] = server + opts.on("-u URI", "Communication URI (xmpp://user:password@domain)") do |uri| + options[:uri] = uri end - opts.on("-t TOPIC", "PubSub topic to create, also becomes the uid of the resource, default to hostname") do |topic| - options[:uid] = topic + opts.on("-e ENVIRONMENT", "Environment (development, production ...)") do |environment| + options[:environment] = environment end - opts.on("-d", "--debug", "Debug mode") do - options[:debug] = true - end - - opts.on("-l LOG_FILE_DIR", "Write log file to this folder") do |file_dir| - options[:log_file_dir] = file_dir + opts.on("-i UID", "UID of the resource, also becomes the pubsub topic of the resource, default to hostname") do |uid| + options[:uid] = uid end end rescue => e @@ -56,28 +51,47 @@ rescue => e end end +if !options[:configfile].nil? + cfg_options = YAML.load(ERB.new(File.read(options[:configfile])).result) + options = cfg_options.merge(options) +end + +options[:uid] ||=`hostname`.chomp + OmfCommon::Measure.enable if oml_enabled -unless options[:server] && options[:user] && options[:password] +options[:environment] ||= :development + +if options[:uri] + common_options = { communication: { url: options[:uri] } } +else + common_options = {} +end + +if !options[:advanced_configfile].nil? + a_cfg_options = (YAML.load_file(options[:advanced_configfile])) + common_options = a_cfg_options.merge(common_options) +end + +unless common_options[:communication] && common_options[:communication][:url] puts "Error: Missing parameters to connect to a PubSub Server (see --help)" exit(1) end -Logging.logger.root.level = :debug if options[:debug] -Blather.logger = logger +resource_options = { + uid: options[:uid] +} -if options[:log_file_dir] && File.exist?(options[:log_file_dir]) - Logging.logger.root.add_appenders( - Logging.appenders.file( - "#{options[:log_file_dir]}/omf_rc.log", - :layout => Logging.layouts.pattern(:date_pattern => '%F %T %z', - :pattern => '[%d] %-5l %c: %m\n'))) -end +#OmfRc::ResourceFactory.load_default_resource_proxies -EM.run do - virtual_openflow_switch_factory = OmfRc::ResourceFactory.new(:virtual_openflow_switch_factory, options) - virtual_openflow_switch_factory.connect +OmfCommon.init(options[:environment].to_sym, common_options) do |el| + info "Starting OMF Resource Controller for virtual OpenFlow Switch factory (OpenVSwitch) version '#{gem_version}'" - trap(:INT) { virtual_openflow_switch_factory.disconnect } - trap(:TERM) { virtual_openflow_switch_factory.disconnect } + OmfCommon.comm.on_connected do |comm| + info "Connected as #{comm.jid}" if comm.jid + res = OmfRc::ResourceFactory.create(:virtual_openflow_switch_factory, resource_options) + + comm.on_interrupted { res.disconnect } + end end +info "Stopping OMF Resource Controller for virtual OpenFlow Switch factory version '#{gem_version}'" diff --git a/example/openflow_slice_factory_controller.rb b/example/openflow_slice_factory_controller.rb index b14f97a..787d784 100755 --- a/example/openflow_slice_factory_controller.rb +++ b/example/openflow_slice_factory_controller.rb @@ -3,32 +3,38 @@ require 'omf_rc' require 'omf_rc/resource_factory' #require 'omf_rc_openflow' + $stdout.sync = true -Blather.logger = logger + +op_mode = :development opts = { - # XMPP server domain - server: 'srv.mytestbed.net', - user: 'flowvisor', - password: 'pw', - uid: 'flowvisor', - # Debug mode of not - debug: false + communication: { url: 'xmpp://flowvisor:pw@srv.mytestbed.net' }, + eventloop: { type: :em }, + logging: { + level: 'info' + # level: 'debug', + # appenders: { + # stdout: { + # date_pattern: '%H:%M:%S', + # pattern: '%d %-5l %c{2}: %m\n', + # color_scheme: 'default' + # } + # } + } } -Logging.logger.root.level = :debug if opts[:debug] - OmfRc::ResourceFactory.load_addtional_resource_proxies(File.dirname(__FILE__)+"/../lib/omf_rc/util") OmfRc::ResourceFactory.load_addtional_resource_proxies(File.dirname(__FILE__)+"/../lib/omf_rc/resource_proxy") -EM.run do - # Use resource factory method to initialise a new instance of garage - info "Starting #{opts[:uid]}" - flowvisor = OmfRc::ResourceFactory.new(:openflow_slice_factory, opts) - flowvisor.connect +OmfCommon.init(op_mode, opts) do |el| + OmfCommon.comm.on_connected do |comm| + info ">>> Starting flowvisor" + + flowvisor = OmfRc::ResourceFactory.new(:openflow_slice_factory, opts.merge(uid: 'flowvisor')) - # Disconnect garage from XMPP server, when these two signals received - trap(:INT) { flowvisor.disconnect } - trap(:TERM) { flowvisor.disconnect } + # Disconnect garage from XMPP server, when INT or TERM signals received + comm.on_interrupted { flowvisor.disconnect } + end end diff --git a/example/openflow_slice_factory_test.rb b/example/openflow_slice_factory_test.rb index 7790842..7530186 100644 --- a/example/openflow_slice_factory_test.rb +++ b/example/openflow_slice_factory_test.rb @@ -1,64 +1,60 @@ # OMF_VERSIONS = 6.0 -@comm = OmfEc.comm - -# @comm is default communicator defined in script runner -# -@flowvisor_id = "flowvisor" -@flowvisor_topic = @comm.get_topic(@flowvisor_id) - -@slice_id = nil -@slice_topic = nil - -msgs = { - create_slice: @comm.create_message([type: 'openflow_slice']), - config_slice: @comm.configure_message([name: 'test', contact_email: 'a@a']), - slices: @comm.request_message([:slices]), - 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'}, - {operation: 'add', device: '00:00:00:00:00:00:00:01', eth_dst: '11:22:33:44:55:77'}]]), -} +def create_slice(flowvisor) + flowvisor.create(:openflow_slice, {name: "test"}) do |reply_msg| + if !reply_msg.itype.start_with? "ERROR" #success? + slice = reply_msg.resource + + slice.on_subscribed do + info ">>> Connected to newly created slice #{reply_msg[:res_id]} with name #{reply_msg[:name]}" + on_slice_created(slice) + end + + after(10) do + flowvisor.release(slice) do |reply_msg| + info ">>> Released slice #{reply_msg[:res_id]}" + end + end + else + error ">>> Slice creation failed - #{reply_msg[:reason]}" + end + end +end -@flowvisor_topic.subscribe {msgs[:create_slice].publish @flowvisor_id} +def on_slice_created(slice) -# If flowvisor is not raised, the following rule will be activated. -@flowvisor_topic.on_message lambda {|m| m.operation == :inform && m.read_content('inform_type') == 'CREATION_FAILED' } do |message| - logger.error message.read_content('reason') - done! -end + slice.request([:name]) do |reply_msg| + info "> Slice requested name: #{reply_msg[:name]}" + end -msgs[:create_slice].on_inform_creation_ok do |message| - @slice_id = message.resource_id - @slice_topic = @comm.get_topic(@slice_id) - - msgs[:release_slice] ||= @comm.release_message {|m| m.element('resource_id', @slice_id)} - msgs[:release_slice].on_inform_released do |message| - logger.info "Slice (#{@slice_id}) released" - m = @comm.request_message([:slices]) - m.on_inform_status do |message| - logger.info "Flowvisor (#{message.read_property('uid')}) requested slices: #{message.read_property('slices').join(', ')}" - done! + slice.configure(flows: [{operation: 'add', device: '00:00:00:00:00:00:00:01', eth_dst: '11:22:33:44:55:66'}, + {operation: 'add', device: '00:00:00:00:00:00:00:01', eth_dst: '11:22:33:44:55:77'}]) do |reply_msg| + info "> Slice configured flows:" + reply_msg.read_property('flows').each do |flow| + logger.info " #{flow}" end - m.publish @flowvisor_id end - - logger.info "Slice (#{@slice_id}) created" - @slice_topic.subscribe {msgs[:config_slice].publish @slice_id} -end - -msgs[:config_slice].on_inform_status do |message| - logger.info "Slice (#{message.read_property('uid')}) configured name: #{message.read_property('name')} & contact_email: #{message.read_property('contact_email')}" - msgs[:slices].publish @flowvisor_id -end -msgs[:slices].on_inform_status do |message| - logger.info "Flowvisor (#{message.read_property('uid')}) requested slices: #{message.read_property('slices').join(', ')}" - msgs[:config_flows].publish @slice_id + # Monitor all status, error or warn information from the slice + #slice.on_status do |msg| + # msg.each_property do |name, value| + # info "#{name} => #{value}" + # end + #end + slice.on_error do |msg| + error msg[:reason] + end + slice.on_warn do |msg| + warn msg[:reason] + end end -msgs[:config_flows].on_inform_status do |message| - logger.info "Slice (#{message.read_property('uid')}) configured flows: " - message.read_property('flows').each do |flow| - logger.info " #{flow}" +OmfCommon.comm.subscribe('flowvisor') do |flowvisor| + unless flowvisor.error? + create_slice(flowvisor) + else + error flowvisor.inspect end - msgs[:release_slice].publish @flowvisor_id + + after(20) { info 'Disconnecting ...'; OmfCommon.comm.disconnect } end diff --git a/example/virtual_openflow_switch_factory_controller.rb b/example/virtual_openflow_switch_factory_controller.rb index fbb2f50..194be02 100755 --- a/example/virtual_openflow_switch_factory_controller.rb +++ b/example/virtual_openflow_switch_factory_controller.rb @@ -2,32 +2,39 @@ require 'omf_rc' require 'omf_rc/resource_factory' +#require 'omf_rc_openflow' + $stdout.sync = true -Blather.logger = logger + +op_mode = :development opts = { - # XMPP server domain - server: 'srv.mytestbed.net', - user: 'ovs', - password: 'pw', - uid: 'ovs', - # Debug mode of not - debug: false + communication: { url: 'xmpp://ovs:pw@srv.mytestbed.net' }, + eventloop: { type: :em }, + logging: { + level: 'info' + # level: 'debug', + # appenders: { + # stdout: { + # date_pattern: '%H:%M:%S', + # pattern: '%d %-5l %c{2}: %m\n', + # color_scheme: 'default' + # } + # } + } } -Logging.logger.root.level = :debug if opts[:debug] - OmfRc::ResourceFactory.load_addtional_resource_proxies(File.dirname(__FILE__)+"/../lib/omf_rc/util") OmfRc::ResourceFactory.load_addtional_resource_proxies(File.dirname(__FILE__)+"/../lib/omf_rc/resource_proxy") -EM.run do - # Use resource factory method to initialise a new instance of garage - info "Starting #{opts[:uid]}" - flowvisor = OmfRc::ResourceFactory.new(:virtual_openflow_switch_factory, opts) - flowvisor.connect +OmfCommon.init(op_mode, opts) do |el| + OmfCommon.comm.on_connected do |comm| + info ">>> Starting ovs" + + ovs = OmfRc::ResourceFactory.new(:virtual_openflow_switch_factory, opts.merge(uid: 'ovs')) - # Disconnect garage from XMPP server, when these two signals received - trap(:INT) { flowvisor.disconnect } - trap(:TERM) { flowvisor.disconnect } + # Disconnect garage from XMPP server, when INT or TERM signals received + comm.on_interrupted { ovs.disconnect } + end end diff --git a/example/virtual_openflow_switch_factory_test.rb b/example/virtual_openflow_switch_factory_test.rb index 3a37dc5..1dd51e7 100644 --- a/example/virtual_openflow_switch_factory_test.rb +++ b/example/virtual_openflow_switch_factory_test.rb @@ -1,74 +1,60 @@ # OMF_VERSIONS = 6.0 -@comm = OmfEc.comm - -# @comm is default communicator defined in script runner -# -@ovs_id = "ovs" -@ovs_topic = @comm.get_topic(@ovs_id) - -@switch_id = nil -@switch_topic = nil - - -msgs = { - switches: @comm.request_message([:switches]), - create_switch: @comm.create_message([type: 'virtual_openflow_switch']), - config_switch_name: @comm.configure_message([name: 'br0']), - config_add_port: @comm.configure_message([ports: {operation: 'add', name: 'tun0', type: 'tunnel'}]), - request_port: @comm.request_message([port: {information: 'netdev-tunnel/get-port', name: 'tun0'}]), - configure_port: @comm.configure_message([port: {name: 'tun0', remote_ip: '138.48.3.201', remote_port: '39505'}]), -} - -@ovs_topic.subscribe {msgs[:switches].publish @ovs_id} - -# If flowvisor is not raised, the following rule will be activated. -@ovs_topic.on_message lambda {|m| m.operation == :inform && m.read_content('inform_type') == 'CREATION_FAILED' } do |message| - logger.error message.read_content('reason') - done! +#msgs = { +# request_port: @comm.request_message([port: {name: 'tun0', information: 'netdev-tunnel/get-port'}]), +# configure_port: @comm.configure_message([port: {name: 'tun0', remote_ip: '138.48.3.201', remote_port: '39505'}]), +#} + +def create_switch(ovs) + ovs.create(:virtual_openflow_switch, {name: "test"}) do |reply_msg| + if !reply_msg.itype.start_with? "ERROR" #success? + switch = reply_msg.resource + + switch.on_subscribed do + info ">>> Connected to newly created switch #{reply_msg[:res_id]} with name #{reply_msg[:name]}" + on_switch_created(switch) + end + + after(10) do + ovs.release(switch) do |reply_msg| + info ">>> Released switch #{reply_msg[:res_id]}" + end + end + else + error ">>> Switch creation failed - #{reply_msg[:reason]}" + end + end end -msgs[:switches].on_inform_status do |message| - logger.info "OVS (#{message.read_property('uid')}) requested switches: #{message.read_property('switches')}" - msgs[:create_switch].publish @ovs_id -end +def on_switch_created(switch) -msgs[:create_switch].on_inform_creation_ok do |message| - @switch_id = message.resource_id - @switch_topic = @comm.get_topic(@switch_id) - - msgs[:release_switch] ||= @comm.release_message {|m| m.element('resource_id', @switch_id)} - msgs[:release_switch].on_inform_released do |message| - logger.info "Switch (#{@switch_id}) released" - m = @comm.request_message([:switches]) - m.on_inform_status do |message| - logger.info "OVS (#{message.read_property('uid')}) requested switches: #{message.read_property('switches')}" - done! + switch.configure(ports: {operation: 'add', name: 'tun0', type: 'tunnel'}) do |reply_msg| + info "> Switch configured ports: #{reply_msg[:ports]}" + switch.configure(port: {name: 'tun0', remote_ip: '138.48.3.201', remote_port: '39505'}) do |reply_msg| + info "> Switch configured port: #{reply_msg[:port]}" end - m.publish @ovs_id end - - logger.info "Switch (#{@switch_id}) created" - @switch_topic.subscribe {msgs[:config_switch_name].publish @switch_id} -end - -msgs[:config_switch_name].on_inform_status do |message| - logger.info "Switch (#{message.read_property('uid')}) configured name: #{message.read_property('name')}" - msgs[:config_add_port].publish @switch_id -end -msgs[:config_add_port].on_inform_status do |message| - logger.info "Switch (#{message.read_property('uid')}) configured ports: #{message.read_property('ports')}" - msgs[:request_port].publish @switch_id + # Monitor all status, error or warn information from the switch + #switch.on_status do |msg| + # msg.each_property do |name, value| + # info "#{name} => #{value}" + # end + #end + switch.on_error do |msg| + error msg[:reason] + end + switch.on_warn do |msg| + warn msg[:reason] + end end -msgs[:request_port].on_inform_status do |message| - logger.info "Switch (#{message.read_property('uid')}) requested port: #{message.read_property('port')}" - msgs[:configure_port].publish @switch_id -end +OmfCommon.comm.subscribe('ovs') do |ovs| + unless ovs.error? + create_switch(ovs) + else + error ovs.inspect + end -msgs[:configure_port].on_inform_status do |message| - logger.info "Switch (#{message.read_property('uid')}) configured port: #{message.read_property('port')}" - msgs[:release_switch].publish @ovs_id + after(20) { info 'Disconnecting ...'; OmfCommon.comm.disconnect } end - diff --git a/lib/omf_rc/resource_proxy/openflow_slice.rb b/lib/omf_rc/resource_proxy/openflow_slice.rb index 31097de..ea2ec47 100644 --- a/lib/omf_rc/resource_proxy/openflow_slice.rb +++ b/lib/omf_rc/resource_proxy/openflow_slice.rb @@ -4,23 +4,13 @@ module OmfRc::ResourceProxy::OpenflowSlice include OmfRc::ResourceProxyDSL - # The default parameters of a new slice. The openflow controller is assumed to be in the same working station with flowvisor instance - SLICE_DEFAULTS = { - passwd: "1234", - url: "tcp:127.0.0.1:9933", - email: "nothing@nowhere" - } - register_proxy :openflow_slice, :create_by => :openflow_slice_factory utility :openflow_slice_tools + property :name, :default => nil - # Slice's name is initiated with value "nil" - hook :before_ready do |resource| - resource.property.name = nil - end # Before release, the related flowvisor instance should also remove the corresponding slice hook :before_release do |resource| @@ -28,22 +18,6 @@ module OmfRc::ResourceProxy::OpenflowSlice end - # The name is one-time configured - configure :name do |resource, name| - raise "The name cannot be changed" if resource.property.name - resource.property.name = name.to_s - begin - resource.flowvisor_connection.call("api.createSlice", name.to_s, *SLICE_DEFAULTS.values) - rescue Exception => e - if e.message["Cannot create slice with existing name"] - logger.warn message = "The requested slice already existed in Flowvisor" - else - raise e - end - end - resource.property.name - end - # Configures the slice password configure :passwd do |resource, passwd| resource.flowvisor_connection.call("api.changePasswd", resource.property.name, passwd.to_s) diff --git a/lib/omf_rc/resource_proxy/openflow_slice_factory.rb b/lib/omf_rc/resource_proxy/openflow_slice_factory.rb index 6788a22..92976ca 100644 --- a/lib/omf_rc/resource_proxy/openflow_slice_factory.rb +++ b/lib/omf_rc/resource_proxy/openflow_slice_factory.rb @@ -16,6 +16,13 @@ module OmfRc::ResourceProxy::OpenflowSliceFactory timeout: nil } + # The default parameters of a new slice. The openflow controller is assumed to be in the same working station with flowvisor instance + SLICE_DEFAULTS = { + passwd: "1234", + url: "tcp:127.0.0.1:9933", + email: "nothing@nowhere" + } + register_proxy :openflow_slice_factory @@ -23,15 +30,14 @@ module OmfRc::ResourceProxy::OpenflowSliceFactory # Checks if the created child is an :openflow_slice resource and passes the connection arguments that are essential for the connection with flowvisor instance - hook :before_create do |resource, type, opts = nil| + hook :before_create do |resource, type, opts| if type.to_sym != :openflow_slice raise "This resource doesn't create resources of type "+type + elsif opts.name == nil + raise "The created slice must be configured with a name" end - begin - resource.flowvisor_connection - rescue - raise "This resource is not connected with a flowvisor instance, so it cannot create openflow slices" - end + #opts = Hashie::Mash.new(opts) + resource.flowvisor_connection.call("api.createSlice", opts.name.to_s, *SLICE_DEFAULTS.values) opts.property ||= Hashie::Mash.new opts.property.provider = ">> #{resource.uid}" opts.property.flowvisor_connection_args = resource.property.flowvisor_connection_args diff --git a/lib/omf_rc/resource_proxy/virtual_openflow_switch.rb b/lib/omf_rc/resource_proxy/virtual_openflow_switch.rb index 04373fd..12e55f6 100644 --- a/lib/omf_rc/resource_proxy/virtual_openflow_switch.rb +++ b/lib/omf_rc/resource_proxy/virtual_openflow_switch.rb @@ -8,11 +8,8 @@ module OmfRc::ResourceProxy::VirtualOpenflowSwitch utility :virtual_openflow_switch_tools + property :name, :default => nil - # Switch name is initiated with value "nil" - hook :before_ready do |resource| - resource.property.name = nil - end # Before release, the related ovsdb-server instance should also remove the corresponding switch hook :before_release do |resource| @@ -43,42 +40,6 @@ module OmfRc::ResourceProxy::VirtualOpenflowSwitch end - # Switch name is one-time configured - configure :name do |resource, name| - raise "The name cannot be changed" if resource.property.name - resource.property.name = name.to_s - arguments = { - "method" => "transact", - "params" => [ "Open_vSwitch", - { "op" => "insert", - "table" => "Interface", - "row" => {"name" => resource.property.name, "type" => "internal"}, - "uuid-name" => "new_interface" - }, - { "op" => "insert", - "table" => "Port", - "row" => {"name" => resource.property.name, "interfaces" => ["named-uuid", "new_interface"]}, - "uuid-name" => "new_port" - }, - { "op" => "insert", - "table" => "Bridge", - "row" => {"name" => resource.property.name, "ports" => ["named-uuid", "new_port"], "datapath_type" => "netdev"}, - "uuid-name" => "new_bridge" - }, - { "op" => "mutate", - "table" => "Open_vSwitch", - "where" => [], - "mutations" => [["bridges", "insert", ["set", [["named-uuid", "new_bridge"]]]]] - } - ], - "id" => "add-switch" - } - result = resource.ovs_connection("ovsdb-server", arguments)["result"] - raise "The requested switch already existed in ovsdb-server or there is another problem" if result[4] - resource.property.uuid = result[2]["uuid"][1] - resource.property.name - end - # Add/remove port configure :ports do |resource, array_parameters| array_parameters = [array_parameters] if !array_parameters.kind_of?(Array) diff --git a/lib/omf_rc/resource_proxy/virtual_openflow_switch_factory.rb b/lib/omf_rc/resource_proxy/virtual_openflow_switch_factory.rb index f1df361..6b3dfe5 100644 --- a/lib/omf_rc/resource_proxy/virtual_openflow_switch_factory.rb +++ b/lib/omf_rc/resource_proxy/virtual_openflow_switch_factory.rb @@ -8,10 +8,10 @@ module OmfRc::ResourceProxy::VirtualOpenflowSwitchFactory ovsdb_server_host: "localhost", ovsdb_server_port: "6635", ovsdb_server_socket: "/usr/local/var/run/openvswitch/db.sock", - ovsdb_server_conn: "unix", # default "unix" between "tcp" and "unix" + ovsdb_server_conn: "unix", # default "unix", between "tcp" and "unix" ovs_vswitchd_pid: "/usr/local/var/run/openvswitch/ovs-vswitchd.pid", ovs_vswitchd_socket: "/usr/local/var/run/openvswitch/ovs-vswitchd.%s.ctl", - ovs_vswitchd_conn: "unix" #default "unix" + ovs_vswitchd_conn: "unix" #default "unix", between "tcp" and "unix" } @@ -21,23 +21,43 @@ module OmfRc::ResourceProxy::VirtualOpenflowSwitchFactory # Checks if the created child is an :virtual_openflow_switch resource and passes the connection arguments - hook :before_create do |resource, type, opts = nil| + hook :before_create do |resource, type, opts| if type.to_sym != :virtual_openflow_switch raise "This resource doesn't create resources of type "+type end - begin - arguments = { - "method" => "list_dbs", - "params" => [], - "id" => "list_dbs" - } - resource.ovs_connection("ovsdb-server", arguments) - rescue - raise "This resource is not connected with an ovsdb-server instance, so it cannot create virtual openflow switches" - end + #opts = Hashie::Mash.new(opts) + arguments = { + "method" => "transact", + "params" => [ "Open_vSwitch", + { "op" => "insert", + "table" => "Interface", + "row" => {"name" => opts.name.to_s, "type" => "internal"}, + "uuid-name" => "new_interface" + }, + { "op" => "insert", + "table" => "Port", + "row" => {"name" => opts.name.to_s, "interfaces" => ["named-uuid", "new_interface"]}, + "uuid-name" => "new_port" + }, + { "op" => "insert", + "table" => "Bridge", + "row" => {"name" => opts.name.to_s, "ports" => ["named-uuid", "new_port"], "datapath_type" => "netdev"}, + "uuid-name" => "new_bridge" + }, + { "op" => "mutate", + "table" => "Open_vSwitch", + "where" => [], + "mutations" => [["bridges", "insert", ["set", [["named-uuid", "new_bridge"]]]]] + } + ], + "id" => "add-switch" + } + result = resource.ovs_connection("ovsdb-server", arguments)["result"] + raise "The requested switch already existed in ovsdb-server or other problem" if result[4] opts.property ||= Hashie::Mash.new opts.property.provider = ">> #{resource.uid}" opts.property.ovs_connection_args = resource.property.ovs_connection_args + opts.property.uuid = result[2]["uuid"][1] end # A new resource uses the default connection arguments (ip adress, port, socket, etc) to connect with a ovsdb-server instance diff --git a/lib/omf_rc_openflow/version.rb b/lib/omf_rc_openflow/version.rb index bc14e46..86640b2 100644 --- a/lib/omf_rc_openflow/version.rb +++ b/lib/omf_rc_openflow/version.rb @@ -1,3 +1,3 @@ module OmfRcOpenflow - VERSION = "6.0.0.pre.1" + VERSION = "6.0.0.pre.2" end