openflow-controller 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/ofctl +2 -71
- data/lib/openflow-controller/cli.rb +95 -0
- data/lib/openflow-controller/completion.rb +219 -0
- data/lib/openflow-controller/controller.rb +15 -6
- data/lib/openflow-controller/version.rb +1 -1
- data/spec/controller_spec.rb +1 -0
- data/spec/spec_helper.rb +3 -0
- metadata +24 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f74e50e943f426a39779802e1598be2a3ec7e718
|
|
4
|
+
data.tar.gz: 5bf304ebd253f6dc4978b92db08b4468c0c433f8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ac6728d86881f6aaad177fc65ba88d96b7dc7490cce185f35f13d4c46ee46f70a15cf5c535892f67e4b027ec4b218f7b9ba7aa437ecf751001faa2c4c86c3a2f
|
|
7
|
+
data.tar.gz: 510b7f3df83fc98ed7dbb137f5e8f68278e6b1a2ebf58954624db81c5a4ae1efba98e0d125cd2140abcfbcefb593c0a404d9260164b5945825bfd212ea2c914c
|
data/bin/ofctl
CHANGED
|
@@ -1,73 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
-
require 'cri'
|
|
3
|
-
require 'readline'
|
|
4
2
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
|
5
|
-
require 'openflow-controller'
|
|
6
|
-
|
|
7
|
-
PROMPT = '> '
|
|
8
|
-
BYE_MSG = 'Bye!'
|
|
9
|
-
|
|
10
|
-
command = Cri::Command.define do
|
|
11
|
-
name 'ofctl'
|
|
12
|
-
usage 'ofctl [options] [args]'
|
|
13
|
-
summary 'OpenFlow Controller command-line tool'
|
|
14
|
-
description 'OpenFlow Controller command-line tool'
|
|
15
|
-
|
|
16
|
-
flag :h, :help, 'show help for this command' do |value, cmd|
|
|
17
|
-
puts cmd.help
|
|
18
|
-
exit 0
|
|
19
|
-
end
|
|
20
|
-
flag :d, :debug, 'run controller in debug mode'
|
|
21
|
-
|
|
22
|
-
option :i, :ip, 'IP address of the controller', argument: :optional
|
|
23
|
-
option :p, :port, 'port number of the controller', argument: :optional
|
|
24
|
-
option :c, :controller, 'custom controller file', argument: :optional
|
|
25
|
-
|
|
26
|
-
run do |opts, args, _cmd|
|
|
27
|
-
load opts[:controller] unless opts[:controller].nil?
|
|
28
|
-
|
|
29
|
-
debug = opts[:debug] || false
|
|
30
|
-
|
|
31
|
-
ctl = OpenFlow::Controller::Controller.create(debug)
|
|
32
|
-
|
|
33
|
-
init_form = ctl.logger.formatter
|
|
34
|
-
ctl.logger.formatter = proc do |severity, datetime, progname, msg|
|
|
35
|
-
buf = PROMPT + Readline::line_buffer
|
|
36
|
-
"\r" + ' ' * buf.length + "\r" +
|
|
37
|
-
init_form.call(severity, datetime, progname, msg).blue +
|
|
38
|
-
buf
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
ip = opts[:ip] || OpenFlow::Controller::Controller::DEFAULT_IP_ADDRESS
|
|
42
|
-
port = opts[:port] || OpenFlow::Controller::Controller::DEFAULT_TCP_PORT
|
|
43
|
-
|
|
44
|
-
Thread.abort_on_exception = true
|
|
45
|
-
Thread.new do
|
|
46
|
-
begin
|
|
47
|
-
ctl.run ip, port, args
|
|
48
|
-
rescue StandardError => e
|
|
49
|
-
puts "#{e.class}: #{e.message}".red
|
|
50
|
-
exit 1
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
loop do
|
|
55
|
-
begin
|
|
56
|
-
input = Readline.readline(PROMPT, true)
|
|
57
|
-
if input == 'exit'
|
|
58
|
-
puts BYE_MSG
|
|
59
|
-
exit
|
|
60
|
-
end
|
|
61
|
-
output = ctl.eval(input).inspect
|
|
62
|
-
puts " => #{output}".green
|
|
63
|
-
rescue StandardError => e
|
|
64
|
-
puts "#{e.class}: #{e.message}".red
|
|
65
|
-
rescue SignalException => e
|
|
66
|
-
puts "\n#{BYE_MSG}"
|
|
67
|
-
exit
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
command.run(ARGV)
|
|
3
|
+
require 'openflow-controller/cli'
|
|
4
|
+
OpenFlow::Controller::CLI.run
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require 'cri'
|
|
2
|
+
require 'openflow-controller/completion'
|
|
3
|
+
require 'openflow-controller/controller'
|
|
4
|
+
|
|
5
|
+
module OpenFlow
|
|
6
|
+
module Controller
|
|
7
|
+
class CLI
|
|
8
|
+
PROMPT = '> '
|
|
9
|
+
BYE_MSG = 'Bye!'
|
|
10
|
+
|
|
11
|
+
def self.run
|
|
12
|
+
create_command.run(ARGV)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def self.print_error(e)
|
|
18
|
+
puts "#{e.class}: #{e.message}".red
|
|
19
|
+
puts e.backtrace.join("\n\t").red
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.run_controller_on_thread(ctl, ip, port, args)
|
|
23
|
+
Thread.abort_on_exception = true
|
|
24
|
+
Thread.new do
|
|
25
|
+
begin
|
|
26
|
+
ctl.run ip, port, args
|
|
27
|
+
rescue StandardError => e
|
|
28
|
+
CLI.print_error e
|
|
29
|
+
exit 1
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.run_cli(ctl)
|
|
35
|
+
loop do
|
|
36
|
+
begin
|
|
37
|
+
input = Readline.readline(PROMPT, true)
|
|
38
|
+
if input.nil? || input == 'exit'
|
|
39
|
+
puts if input.nil?
|
|
40
|
+
puts BYE_MSG
|
|
41
|
+
exit
|
|
42
|
+
end
|
|
43
|
+
output = eval(input, ctl.get_binding).inspect
|
|
44
|
+
# output = ctl.eval(input).inspect
|
|
45
|
+
puts " => #{output}".green
|
|
46
|
+
rescue StandardError, SyntaxError => e
|
|
47
|
+
print_error e
|
|
48
|
+
rescue SignalException
|
|
49
|
+
puts
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.create_command
|
|
55
|
+
Cri::Command.define do
|
|
56
|
+
name 'ofctl'
|
|
57
|
+
usage 'ofctl [options] [args]'
|
|
58
|
+
summary 'OpenFlow Controller command-line tool'
|
|
59
|
+
description 'OpenFlow Controller command-line tool'
|
|
60
|
+
|
|
61
|
+
flag :h, :help, 'show help for this command' do |_value, cmd|
|
|
62
|
+
puts cmd.help
|
|
63
|
+
exit 0
|
|
64
|
+
end
|
|
65
|
+
flag :d, :debug, 'run controller in debug mode'
|
|
66
|
+
|
|
67
|
+
option :i, :ip, 'IP address of the controller', argument: :optional
|
|
68
|
+
option :p, :port, 'port number of the controller', argument: :optional
|
|
69
|
+
option :c, :controller, 'custom controller file', argument: :optional
|
|
70
|
+
|
|
71
|
+
run do |opts, args, _cmd|
|
|
72
|
+
load opts[:controller] unless opts[:controller].nil?
|
|
73
|
+
|
|
74
|
+
ctl = Controller.create
|
|
75
|
+
ctl.set_debug if opts[:debug]
|
|
76
|
+
|
|
77
|
+
init_form = ctl.logger.formatter
|
|
78
|
+
ctl.logger.formatter = proc do |severity, datetime, progname, msg|
|
|
79
|
+
buf = PROMPT + Readline::line_buffer
|
|
80
|
+
"\r" + ' ' * buf.length + "\r" +
|
|
81
|
+
init_form.call(severity, datetime, progname, msg).blue +
|
|
82
|
+
buf
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
ip = opts[:ip] || Controller::DEFAULT_IP_ADDRESS
|
|
86
|
+
port = opts[:port] || Controller::DEFAULT_TCP_PORT
|
|
87
|
+
|
|
88
|
+
CLI.run_controller_on_thread ctl, ip, port, args
|
|
89
|
+
CLI.run_cli ctl
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
require 'readline'
|
|
2
|
+
require 'openflow-controller/controller'
|
|
3
|
+
|
|
4
|
+
module OpenFlow
|
|
5
|
+
module Controller
|
|
6
|
+
module Completion
|
|
7
|
+
# Set of reserved words used by Ruby, you should not use these for
|
|
8
|
+
# constants or variables
|
|
9
|
+
RESERVED_WORDS = %w[
|
|
10
|
+
BEGIN END
|
|
11
|
+
alias and
|
|
12
|
+
begin break
|
|
13
|
+
case class
|
|
14
|
+
def defined do
|
|
15
|
+
else elsif end ensure
|
|
16
|
+
false for
|
|
17
|
+
if in
|
|
18
|
+
module
|
|
19
|
+
next nil not
|
|
20
|
+
or
|
|
21
|
+
redo rescue retry return
|
|
22
|
+
self super
|
|
23
|
+
then true
|
|
24
|
+
undef unless until
|
|
25
|
+
when while
|
|
26
|
+
yield
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
Proc = proc do |input|
|
|
30
|
+
bind = Controller.instance.get_binding
|
|
31
|
+
|
|
32
|
+
case input
|
|
33
|
+
when /^((["'`]).*\2)\.([^.]*)$/
|
|
34
|
+
# String
|
|
35
|
+
receiver = $1
|
|
36
|
+
message = Regexp.quote($3)
|
|
37
|
+
|
|
38
|
+
candidates = String.instance_methods.map(&:to_s)
|
|
39
|
+
select_message(receiver, message, candidates)
|
|
40
|
+
|
|
41
|
+
when /^(\/[^\/]*\/)\.([^.]*)$/
|
|
42
|
+
# Regexp
|
|
43
|
+
receiver = $1
|
|
44
|
+
message = Regexp.quote($2)
|
|
45
|
+
|
|
46
|
+
candidates = Regexp.instance_methods.map(&:to_s)
|
|
47
|
+
select_message(receiver, message, candidates)
|
|
48
|
+
|
|
49
|
+
when /^([^\]]*\])\.([^.]*)$/
|
|
50
|
+
# Array
|
|
51
|
+
receiver = $1
|
|
52
|
+
message = Regexp.quote($2)
|
|
53
|
+
|
|
54
|
+
candidates = Array.instance_methods.map(&:to_s)
|
|
55
|
+
select_message(receiver, message, candidates)
|
|
56
|
+
|
|
57
|
+
when /^([^\}]*\})\.([^.]*)$/
|
|
58
|
+
# Proc or Hash
|
|
59
|
+
receiver = $1
|
|
60
|
+
message = Regexp.quote($2)
|
|
61
|
+
|
|
62
|
+
candidates = Proc.instance_methods.map(&:to_s)
|
|
63
|
+
candidates |= Hash.instance_methods.map(&:to_s)
|
|
64
|
+
select_message(receiver, message, candidates)
|
|
65
|
+
|
|
66
|
+
when /^(:[^:.]*)$/
|
|
67
|
+
# Symbol
|
|
68
|
+
if Symbol.respond_to?(:all_symbols)
|
|
69
|
+
sym = $1
|
|
70
|
+
candidates = Symbol.all_symbols.map { |s| ':' + s.id2name }
|
|
71
|
+
candidates.grep(/^#{Regexp.quote(sym)}/)
|
|
72
|
+
else
|
|
73
|
+
[]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
when /^::([A-Z][^:\.\(]*)$/
|
|
77
|
+
# Absolute Constant or class methods
|
|
78
|
+
receiver = $1
|
|
79
|
+
candidates = Object.constants.map(&:to_s)
|
|
80
|
+
candidates.grep(/^#{receiver}/).map { |s| '::' + s }
|
|
81
|
+
|
|
82
|
+
when /^([A-Z].*)::([^:.]*)$/
|
|
83
|
+
# Constant or class methods
|
|
84
|
+
receiver = $1
|
|
85
|
+
message = Regexp.quote($2)
|
|
86
|
+
begin
|
|
87
|
+
candidates = eval("#{receiver}.constants.map(&:to_s)", bind)
|
|
88
|
+
candidates |= eval("#{receiver}.methods.map(&:to_s)", bind)
|
|
89
|
+
rescue Exception
|
|
90
|
+
candidates = []
|
|
91
|
+
end
|
|
92
|
+
select_message(receiver, message, candidates, '::')
|
|
93
|
+
|
|
94
|
+
when /^(:[^:.]+)(\.|::)([^.]*)$/
|
|
95
|
+
# Symbol
|
|
96
|
+
receiver = $1
|
|
97
|
+
sep = $2
|
|
98
|
+
message = Regexp.quote($3)
|
|
99
|
+
|
|
100
|
+
candidates = Symbol.instance_methods.map(&:to_s)
|
|
101
|
+
select_message(receiver, message, candidates, sep)
|
|
102
|
+
|
|
103
|
+
when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)(\.|::)([^.]*)$/
|
|
104
|
+
# Numeric
|
|
105
|
+
receiver = $1
|
|
106
|
+
sep = $5
|
|
107
|
+
message = Regexp.quote($6)
|
|
108
|
+
|
|
109
|
+
begin
|
|
110
|
+
candidates = eval(receiver, bind).methods.map(&:to_s)
|
|
111
|
+
rescue Exception
|
|
112
|
+
candidates = []
|
|
113
|
+
end
|
|
114
|
+
select_message(receiver, message, candidates, sep)
|
|
115
|
+
|
|
116
|
+
when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/
|
|
117
|
+
# Numeric(0xFFFF)
|
|
118
|
+
receiver = $1
|
|
119
|
+
sep = $2
|
|
120
|
+
message = Regexp.quote($3)
|
|
121
|
+
|
|
122
|
+
begin
|
|
123
|
+
candidates = eval(receiver, bind).methods.map(&:to_s)
|
|
124
|
+
rescue Exception
|
|
125
|
+
candidates = []
|
|
126
|
+
end
|
|
127
|
+
select_message(receiver, message, candidates, sep)
|
|
128
|
+
|
|
129
|
+
when /^(\$[^.]*)$/
|
|
130
|
+
# global var
|
|
131
|
+
regmessage = Regexp.new(Regexp.quote($1))
|
|
132
|
+
candidates = global_variables.map(&:to_s).grep(regmessage)
|
|
133
|
+
|
|
134
|
+
when /^([^."].*)(\.|::)([^.]*)$/
|
|
135
|
+
# variable.func or func.func
|
|
136
|
+
receiver = $1
|
|
137
|
+
sep = $2
|
|
138
|
+
message = Regexp.quote($3)
|
|
139
|
+
|
|
140
|
+
gv = eval('global_variables', bind).map(&:to_s)
|
|
141
|
+
lv = eval('local_variables', bind).map(&:to_s)
|
|
142
|
+
iv = eval('instance_variables', bind).map(&:to_s)
|
|
143
|
+
cv = eval('self.class.constants', bind).map(&:to_s)
|
|
144
|
+
|
|
145
|
+
if (gv | lv | iv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
|
|
146
|
+
# foo.func and foo is var. OR
|
|
147
|
+
# foo::func and foo is var. OR
|
|
148
|
+
# foo::Const and foo is var. OR
|
|
149
|
+
# Foo::Bar.func
|
|
150
|
+
begin
|
|
151
|
+
candidates = []
|
|
152
|
+
rec = eval(receiver, bind)
|
|
153
|
+
if sep == '::' and rec.kind_of?(Module)
|
|
154
|
+
candidates = rec.constants.map(&:to_s)
|
|
155
|
+
end
|
|
156
|
+
candidates |= rec.methods.map(&:to_s)
|
|
157
|
+
rescue Exception
|
|
158
|
+
candidates = []
|
|
159
|
+
end
|
|
160
|
+
else
|
|
161
|
+
# func1.func2
|
|
162
|
+
candidates = []
|
|
163
|
+
ObjectSpace.each_object(Module) do |m|
|
|
164
|
+
begin
|
|
165
|
+
name = m.name
|
|
166
|
+
rescue Exception
|
|
167
|
+
name = ''
|
|
168
|
+
end
|
|
169
|
+
begin
|
|
170
|
+
next if name != "IRB::Context" and
|
|
171
|
+
/^(IRB|SLex|RubyLex|RubyToken)/ =~ name
|
|
172
|
+
rescue Exception
|
|
173
|
+
next
|
|
174
|
+
end
|
|
175
|
+
candidates.concat m.instance_methods(false).map(&:to_s)
|
|
176
|
+
end
|
|
177
|
+
candidates.sort!
|
|
178
|
+
candidates.uniq!
|
|
179
|
+
end
|
|
180
|
+
select_message(receiver, message, candidates, sep)
|
|
181
|
+
|
|
182
|
+
when /^\.([^.]*)$/
|
|
183
|
+
# unknown(maybe String)
|
|
184
|
+
receiver = ''
|
|
185
|
+
message = Regexp.quote($1)
|
|
186
|
+
|
|
187
|
+
candidates = String.instance_methods(true).map(&:to_s)
|
|
188
|
+
select_message(receiver, message, candidates)
|
|
189
|
+
|
|
190
|
+
else
|
|
191
|
+
candidates = eval('methods | private_methods | local_variables | instance_variables | self.class.constants | Object.constants | OpenFlow.constants | OpenFlow::Controller.constants', bind).map(&:to_s)
|
|
192
|
+
|
|
193
|
+
(candidates | RESERVED_WORDS).grep(/^#{Regexp.quote(input)}/)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Set of available operators in Ruby
|
|
198
|
+
OPERATORS = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~]
|
|
199
|
+
|
|
200
|
+
def self.select_message(receiver, message, candidates, sep = '.')
|
|
201
|
+
candidates.grep(/^#{message}/).map do |e|
|
|
202
|
+
case e
|
|
203
|
+
when /^[a-zA-Z_]/
|
|
204
|
+
receiver + sep + e
|
|
205
|
+
when /^[0-9]/
|
|
206
|
+
when *OPERATORS
|
|
207
|
+
#receiver + " " + e
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
if Readline.respond_to?('basic_word_break_characters=')
|
|
216
|
+
Readline.basic_word_break_characters = " \t\n`><=;|&{("
|
|
217
|
+
end
|
|
218
|
+
Readline.completion_append_character = nil
|
|
219
|
+
Readline.completion_proc = OpenFlow::Controller::Completion::Proc
|
|
@@ -10,6 +10,7 @@ module OpenFlow
|
|
|
10
10
|
module Controller
|
|
11
11
|
class Controller
|
|
12
12
|
include Protocol
|
|
13
|
+
include PacketProtocols
|
|
13
14
|
|
|
14
15
|
DEFAULT_IP_ADDRESS = '0.0.0.0'
|
|
15
16
|
DEFAULT_TCP_PORT = 6633
|
|
@@ -18,8 +19,12 @@ module OpenFlow
|
|
|
18
19
|
@controller_class = subclass
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
def self.create
|
|
22
|
-
(@controller_class || self).new
|
|
22
|
+
def self.create
|
|
23
|
+
@instance = (@controller_class || self).new
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.instance
|
|
27
|
+
@instance
|
|
23
28
|
end
|
|
24
29
|
|
|
25
30
|
def self.timer_event(handler, options)
|
|
@@ -33,19 +38,23 @@ module OpenFlow
|
|
|
33
38
|
|
|
34
39
|
attr_reader :logger
|
|
35
40
|
|
|
36
|
-
def initialize
|
|
41
|
+
def initialize
|
|
37
42
|
@switches = {}
|
|
38
43
|
@messages = {}
|
|
39
44
|
@logger = Logger.new($stdout).tap do |logger|
|
|
40
45
|
logger.formatter = proc do |severity, datetime, _progname, msg|
|
|
41
46
|
"#{datetime} (#{severity}) -- #{msg}\n"
|
|
42
47
|
end
|
|
43
|
-
logger.level =
|
|
48
|
+
logger.level = Logger::INFO
|
|
44
49
|
end
|
|
45
50
|
end
|
|
46
51
|
|
|
47
|
-
def
|
|
48
|
-
|
|
52
|
+
def set_debug
|
|
53
|
+
@logger.level = Logger::DEBUG
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def get_binding
|
|
57
|
+
binding
|
|
49
58
|
end
|
|
50
59
|
|
|
51
60
|
def run(ip = DEFAULT_IP_ADDRESS, port = DEFAULT_TCP_PORT, *args)
|
data/spec/controller_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openflow-controller
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jérémy Pagé
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-01-
|
|
11
|
+
date: 2016-01-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: openflow-protocol
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - '='
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.1.
|
|
19
|
+
version: 0.1.9
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - '='
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.1.
|
|
26
|
+
version: 0.1.9
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: colored
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -56,16 +56,16 @@ dependencies:
|
|
|
56
56
|
name: rake
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- - "
|
|
59
|
+
- - ">="
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '0'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- - "
|
|
66
|
+
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
68
|
+
version: '0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: rspec
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,6 +80,20 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '3.2'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: coveralls
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
83
97
|
description: An OpenFlow Controller.
|
|
84
98
|
email:
|
|
85
99
|
- contact@jeremypage.me
|
|
@@ -90,6 +104,8 @@ extra_rdoc_files: []
|
|
|
90
104
|
files:
|
|
91
105
|
- bin/ofctl
|
|
92
106
|
- lib/openflow-controller.rb
|
|
107
|
+
- lib/openflow-controller/cli.rb
|
|
108
|
+
- lib/openflow-controller/completion.rb
|
|
93
109
|
- lib/openflow-controller/controller.rb
|
|
94
110
|
- lib/openflow-controller/switch.rb
|
|
95
111
|
- lib/openflow-controller/version.rb
|