forj 0.0.34 → 0.0.35

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/lib/forj-config.rb CHANGED
@@ -21,8 +21,8 @@
21
21
  require 'rubygems'
22
22
  require 'yaml'
23
23
 
24
- require_relative 'log.rb'
25
- include Logging
24
+ #require_relative 'log.rb'
25
+ #include Logging
26
26
 
27
27
  class ForjDefault
28
28
 
@@ -38,6 +38,8 @@ class ForjDefault
38
38
  if not $LIB_PATH
39
39
  raise 'Internal $LIB_PATH was not set.'
40
40
  end
41
+
42
+ Logging.info ('Reading default configuration...')
41
43
 
42
44
  @sDefaultsName=File.join($LIB_PATH,'defaults.yaml')
43
45
 
@@ -50,10 +52,10 @@ class ForjConfig
50
52
 
51
53
  # Internal variables:
52
54
  # @sConfigName='config.yaml'
55
+ # @yRuntime = data in memory.
53
56
  # @yLocal = config.yaml file data hash.
54
57
  # @yConfig = defaults.yaml + local_config data hash
55
58
 
56
-
57
59
  attr_reader :yLocal
58
60
  attr_reader :yConfig
59
61
  attr_reader :sConfigName
@@ -69,14 +71,13 @@ class ForjConfig
69
71
 
70
72
  sConfigDefaultName='config.yaml'
71
73
 
72
- # binding.pry
73
74
  if sConfigName
74
75
  if File.dirname(sConfigName) == '.'
75
76
  sConfigName= File.join($FORJ_DATA_PATH,sConfigName)
76
77
  end
77
78
  sConfigName = File.expand_path(sConfigName)
78
79
  if not File.exists?(sConfigName)
79
- Logging.error('Config file %s doesn\'t exists. Using default one.')
80
+ Logging.warning("Config file '%s' doesn't exists. Using default one." % [sConfigName] )
80
81
  @sConfigName=File.join($FORJ_DATA_PATH,sConfigDefaultName)
81
82
  else
82
83
  @sConfigName=sConfigName
@@ -98,12 +99,14 @@ class ForjConfig
98
99
  if not File.exists?($FORJ_DATA_PATH)
99
100
  Dir.mkdir($FORJ_DATA_PATH)
100
101
  end
101
- puts ('INFO: Creating your default configuration file ...')
102
+ Logging.info ('Creating your default configuration file ...')
102
103
  self.SaveConfig()
103
104
  end
104
105
  end
105
106
 
106
107
  BuildConfig()
108
+
109
+ @yRuntime={}
107
110
  end
108
111
 
109
112
 
@@ -113,14 +116,14 @@ class ForjConfig
113
116
  YAML.dump(@yLocal, out)
114
117
  end
115
118
  rescue => e
116
- Logging.error(e.message)
119
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
117
120
  return false
118
121
  end
119
- # puts ('INFO: Configuration file "%s" updated.' % @sConfigName)
122
+ Logging.info ('Configuration file "%s" updated.' % @sConfigName)
120
123
  return true
121
124
  end
122
125
 
123
- def ConfigSet(key, value, section = 'default')
126
+ def LocalSet(key, value, section = 'default')
124
127
  if not key or not value
125
128
  return false
126
129
  end
@@ -136,7 +139,7 @@ class ForjConfig
136
139
  return true
137
140
  end
138
141
 
139
- def ConfigDel(key,section = 'default')
142
+ def LocalDel(key,section = 'default')
140
143
  if not key
141
144
  return false
142
145
  end
@@ -148,6 +151,35 @@ class ForjConfig
148
151
  return true
149
152
  end
150
153
 
154
+ def setDefault(key, value)
155
+ if not key
156
+ return false
157
+ end
158
+ if not @yRuntime[key]
159
+ @yRuntime[key] = value
160
+ end
161
+ return true
162
+ end
163
+
164
+ def set(key, value)
165
+ if not key
166
+ return false
167
+ end
168
+ if value
169
+ @yRuntime[key] = value
170
+ else
171
+ @yRuntime.delete(key)
172
+ end
173
+ return true
174
+ end
175
+
176
+ def get(key, default = @yConfig['default'][key])
177
+ if @yRuntime.has_key?(key)
178
+ @yRuntime[key]
179
+ else
180
+ default
181
+ end
182
+ end
151
183
 
152
184
  def BuildConfig()
153
185
  # This function implements the logic to get defaults, superseed by local config.
data/lib/log.rb CHANGED
@@ -26,41 +26,140 @@ require 'require_relative'
26
26
  require_relative 'helpers.rb'
27
27
  include Helpers
28
28
 
29
+
29
30
  #
30
31
  # Logging module
31
32
  #
32
33
  module Logging
33
- def info(message)
34
- home = Helpers.get_home_path
35
- d = '%s/.forj/' % [home]
36
- Helpers.create_directory(d)
37
-
38
- log = '%s/.forj/forj.log' % [home]
39
- log = Logger.new(log)
40
- log.level = Logger::DEBUG
41
34
 
42
- log.formatter = proc do |severity, datetime, progname, msg|
43
- "#{progname} : #{datetime}: #{severity}: #{msg} \n"
35
+ class SSLErrorMgt
36
+
37
+ def initialize()
38
+ @iRetry=0
39
+ end
40
+
41
+ def ErrorDetected(message,backtrace)
42
+ if message.match('SSLv2/v3 read server hello A: unknown protocol')
43
+ if @iRetry <5
44
+ sleep(2)
45
+ @iRetry+=1
46
+ print "%s/5 try...\r" % @iRetry if $FORJ_LOGGER.level == 0
47
+ return false
48
+ else
49
+ Logging.error('Too many retry. %s' % message)
50
+ return true
51
+ end
52
+ else
53
+ Logging.error("%s\n%s" % [message,backtrace.join("\n")])
54
+ return true
55
+ end
44
56
  end
45
57
 
46
- log.info(message)
58
+ end
59
+
60
+ class ForjLog
61
+ # Class used to create 2 log object, in order to keep track of error in a log file and change log output to OUTPUT on needs (option flags).
62
+
63
+ attr_reader :level
64
+
65
+ def initialize(sLogFile = 'forj.log', level = Logger::WARN)
66
+ if not $FORJ_DATA_PATH
67
+ raise "Internal Error: Unable to initialize ForjLog - global FORJ_DATA_PATH not set"
68
+ end
69
+ @oFileLogger = Logger.new(File.join($FORJ_DATA_PATH, sLogFile), 'weekly')
70
+ @oFileLogger.level = Logger::DEBUG
71
+ @oFileLogger.formatter = proc do |severity, datetime, progname, msg|
72
+ "#{progname} : #{datetime}: #{severity}: #{msg} \n"
73
+ end
74
+
75
+ @oOutLogger = Logger.new(STDOUT)
76
+ @level = level
77
+ @oOutLogger.level = @level
78
+ @oOutLogger.formatter = proc do |severity, datetime, progname, msg|
79
+ severity == 'ANY'?"#{msg} \n":"#{severity}: #{msg} \n"
80
+ end
81
+ end
82
+
83
+ def info?
84
+ return(@oOutLogger.info?)
85
+ end
86
+ def debug?
87
+ return(@oOutLogger.debug?)
88
+ end
89
+ def error?
90
+ return(@oOutLogger.error?)
91
+ end
92
+ def fatal?
93
+ return(@oOutLogger.fatal?)
94
+ end
95
+
96
+ def info(message)
97
+ @oOutLogger.info(message + ANSI.clear_line)
98
+ @oFileLogger.info(message)
99
+ end
100
+ def debug(message)
101
+ @oOutLogger.debug(message + ANSI.clear_line)
102
+ @oFileLogger.debug(message)
103
+ end
104
+ def error(message)
105
+ @oOutLogger.error(message + ANSI.clear_line)
106
+ @oFileLogger.error(message)
107
+ end
108
+ def fatal(message)
109
+ @oOutLogger.fatal(message + ANSI.clear_line)
110
+ @oFileLogger.fatal(message)
111
+ end
112
+
113
+ def warn(message)
114
+ @oOutLogger.warn(message + ANSI.clear_line)
115
+ @oFileLogger.warn(message)
116
+ end
117
+
118
+ def set_level(level)
119
+ @level = level
120
+ @oOutLogger.level = level
121
+ end
122
+
123
+ def unknown(message)
124
+ @oOutLogger.unknown(message + ANSI.clear_line)
125
+ end
126
+
127
+ end
128
+
129
+ def message(message)
130
+ $FORJ_LOGGER.unknown(message)
131
+ end
132
+
133
+ def info(message)
134
+ $FORJ_LOGGER.info(message)
135
+ end
136
+
137
+ def debug(message)
138
+ $FORJ_LOGGER.debug(message)
139
+ end
140
+
141
+ def warning(message)
142
+ $FORJ_LOGGER.warn(message)
47
143
  end
48
144
 
49
145
  def error(message)
50
- home = Helpers.get_home_path
51
- d = '%s/.forj/' % [home]
52
- Helpers.create_directory(d)
53
-
54
- log = '%s/.forj/forj.log' % [home]
55
- log = Logger.new(log)
56
- log.level = Logger::ERROR
57
-
58
- log.formatter = proc do |severity, datetime, progname, msg|
59
- "#{progname} : #{datetime}: #{severity}: #{msg} \n"
60
- end
146
+ $FORJ_LOGGER.error(message)
147
+ end
148
+
149
+ def fatal(rc, message)
150
+ $FORJ_LOGGER.fatal(message)
151
+ puts 'Issues found. Please fix it and retry. Process aborted.'
152
+ exit rc
153
+ end
61
154
 
62
- log.error(message)
155
+ def set_level(level)
156
+ $FORJ_LOGGER.set_level(level)
63
157
  end
64
- end
158
+
159
+ def state(message)
160
+ print("%s%s ...\r" % [message, ANSI.clear_line]) if $FORJ_LOGGER.level == Logger::INFO
161
+ end
162
+
65
163
 
66
164
 
165
+ end
data/lib/network.rb CHANGED
@@ -19,149 +19,311 @@ require 'rubygems'
19
19
  require 'require_relative'
20
20
 
21
21
  require_relative 'connection.rb'
22
- include Connection
23
- require_relative 'log.rb'
24
- include Logging
22
+
25
23
 
26
24
  #
27
25
  # Network module
28
26
  #
29
27
  module Network
30
- def get_or_create_network(name)
31
- network = get_network(name)
32
- if network == nil
33
- network = create_network(name)
28
+
29
+ # Network management
30
+ def get_or_create_network(oFC, name)
31
+ Logging.state("Searching for network '%s'" % [name])
32
+ network = get_network(oFC, name)
33
+ if not network
34
+ network = create_network(oFC, name)
34
35
  end
35
36
  network
36
37
  end
37
38
 
38
- def get_network(name)
39
+ def get_network(oFC, name)
39
40
  begin
40
- info = 'getting network %s' % [name]
41
- Logging.info(info)
42
- Connection.network.networks.all(:name => name)[0]
41
+ networks = oFC.oNetwork.networks.all(:name => name)
42
+ case networks.length()
43
+ when 0
44
+ Logging.debug("No network found")
45
+ nil
46
+ when 1
47
+ Logging.debug("Found network '%s'" % [networks[0].name])
48
+ networks[0]
49
+ else
50
+ Logging.warning("Several network was found with '%s'. Selecting the first one '%s'." % [name, networks[0].name])
51
+ networks[0]
52
+ end
43
53
  rescue => e
44
- puts e.message
45
- Logging.error(e.message)
54
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
46
55
  end
47
56
  end
48
57
 
49
- def create_network(name)
58
+ def create_network(oFC, name)
50
59
  begin
51
- info = 'creating network %s' % [name]
52
- Logging.info(info)
53
- Connection.network.networks.create(:name => name)
60
+ Logging.debug('creating network %s' % [name])
61
+ oFC.oNetwork.networks.create(:name => name)
54
62
  rescue => e
55
- Logging.error(e.message)
63
+ Logging.fatal(1, "%s\n%s" % [e.inspect, e.message])
56
64
  end
57
65
  end
58
66
 
59
- def delete_network(network_name)
67
+ def delete_network(oFC, network_name)
60
68
  begin
61
- network = get_network(network_name)
62
- Connection.network.networks.get(network.id).destroy
69
+ network = get_network(oFC, network_name)
70
+ oFC.oNetwork.networks.get(network.id).destroy
63
71
  rescue => e
64
- Logging.error(e.message)
72
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
65
73
  end
66
74
  end
67
75
 
68
- def get_or_create_subnet(network_id, name)
76
+
77
+ # Subnet management
78
+ def get_or_create_subnet(oFC, network_id, name)
79
+ Logging.state("Searching for sub-network attached '%s'." % [name])
69
80
  begin
70
- subnet = get_subnet(name)
71
- if subnet == nil
72
- subnet = create_subnet(network_id, name)
73
- end
74
- subnet
81
+ subnets = oFC.oNetwork.subnets.all(:network_id => network_id)
75
82
  rescue => e
76
- Logging.error(e.message)
83
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
84
+ end
85
+ if subnets
86
+ case subnets.length()
87
+ when 0
88
+ Logging.debug("No subnet found from '%s' network" % [name])
89
+ subnet = nil
90
+ when 1
91
+ Logging.debug("Found '%s' subnet from '%s' network" % [subnets[0].name, name])
92
+ subnet = subnets[0]
93
+ else
94
+ Logging.warning("Several subnet was found on '%s'. Choosing the first one = '%s'" % [name, subnets[0].name])
95
+ subnet = subnets[0]
96
+ end
97
+ end
98
+ if not subnet
99
+ # Create the subnet with 'sub-' prefixing the network name.
100
+ begin
101
+ subnet = create_subnet(oFC, network_id, 'sub-%s' % [name])
102
+ rescue => e
103
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
104
+ end
77
105
  end
106
+ return subnet
78
107
  end
79
108
 
80
- def create_subnet(network_id, name)
109
+ def create_subnet(oFC, network_id, name)
110
+ Logging.debug("Creating subnet '%s'" % [name])
81
111
  begin
82
- Connection.network.subnets.create(
112
+ oFC.oNetwork.subnets.create(
83
113
  :network_id => network_id,
84
114
  :name => name,
85
- :cidr => get_next_subnet,
115
+ :cidr => get_next_subnet(oFC),
86
116
  :ip_version => '4'
87
117
  )
88
118
  rescue => e
89
- Logging.error(e.message)
119
+ Logging.fatal(1, "%s\n%s" % [e.class.name, e.message])
90
120
  end
91
121
  end
92
122
 
93
- def delete_subnet(subnet_id)
123
+ def delete_subnet(oFC, subnet)
124
+ Logging.debug("Deleting subnet '%s'" % [subnet.name])
94
125
  begin
95
- Connection.network.subnets.get(subnet_id).destroy
126
+ oFC.oNetwork.subnets.get(subnet.id).destroy
96
127
  rescue => e
97
- Logging.error(e.message)
128
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
98
129
  end
99
130
  end
100
131
 
101
- def get_subnet(name)
132
+ def get_subnet(oFC, name)
102
133
  begin
103
- Connection.network.subnets.all(:name => name)[0]
134
+ oFC.oNetwork.subnets.all(:name => name)[0]
104
135
  rescue => e
105
- Logging.error(e.message)
136
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
106
137
  end
107
138
  end
108
139
 
109
- def get_router(name)
110
- begin
111
- routers = Connection.network.routers.all({:name => name})
112
- router = nil
113
140
 
114
- routers.each do|r|
115
- router = r
141
+ # Router management
142
+ def get_or_create_router(oFC, network, subnet)
143
+ port = get_router_interface_attached(oFC, network)
144
+ if not port
145
+ # Trying to get router
146
+ router = get_router(oFC, 'router-%s' % network.name)
147
+ router = create_router(oFC, 'router-%s' % network.name) if not router
148
+ create_router_interface(subnet, router) if router
149
+ else
150
+ routers = oFC.oNetwork.routers.all({:id => port.device_id})
151
+ if routers.length() == 1
152
+ if routers[0].external_gateway_info
153
+ Logging.debug("Found router '%s' attached to an external gateway." % [ routers[0].name ] )
154
+ else
155
+ Logging.debug("Found router '%s' but need to be attached to an external gateway. Attaching..." % [ routers[0].name ] )
156
+ netty=search_gateway(oFC)
157
+ if netty
158
+ routers[0].external_gateway_info = { 'network_id' => netty.id }
159
+ routers[0].save
160
+ Logging.debug("Router '%s' attached to the external network '%s'." % [ routers[0].name, netty.name ] )
161
+ else
162
+ Logging.fatal(1, "Unable to attach router '%s' to an external gateway. Required for boxes to get internet access. " % [ routers[0].name ] )
163
+ end
164
+ end
165
+ router = routers[0]
166
+ else
167
+ Logging.warning("Unable to found the router id '%s'" % [ port.device_id ])
168
+ router = nil
169
+ end
170
+ end
171
+ router
172
+ end
173
+
174
+ def get_router(oFC, name)
175
+ Logging.state("Searching for router '%s'..." % [name] )
176
+ begin
177
+ routers = oFC.oNetwork.routers.all({:name => name})
178
+ if routers.length() == 1
179
+ if routers[0].external_gateway_info.has_key?('id')
180
+ Logging.debug("Found router '%s' attached to an external gateway." % [ routers[0].name ] )
181
+ else
182
+ Logging.warning("Found router '%s' but not attached to an external." % [ routers[0].name ] )
183
+ end
184
+ routers[0]
185
+ else
186
+ Logging.debug("Router '%s' not found." % [ name ] )
187
+ nil
116
188
  end
189
+ rescue => e
190
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
191
+ end
192
+ end
117
193
 
118
- router
194
+ def create_router(oFC, name)
195
+
196
+ netty = search_gateway(oFC)
197
+
198
+ begin
199
+ if netty
200
+ Logging.debug("Creating router '%s' attached to the external Network '%s'." % [name, netty.name])
201
+ oFC.oNetwork.routers.create(
202
+ :name => name,
203
+ :admin_state_up => true,
204
+ :external_gateway_info => { 'network_id' => netty.id }
205
+ )
206
+ else
207
+ Logging.debug("Creating router '%s' without external Network." % [name])
208
+ oFC.oNetwork.routers.create(
209
+ :name => name,
210
+ :admin_state_up => true
211
+ )
212
+ end
119
213
  rescue => e
120
- Logging.error(e.message)
214
+ Logging.fatal(1, "%s\n%s" % [e.inspect, e.message])
121
215
  end
122
216
  end
123
217
 
124
- def create_router_interface(subnet_id, router)
218
+ def delete_router(oFC, router_id)
219
+ Logging.debug("Deleting router '%s'" % [router.name])
125
220
  begin
126
- router.add_interface(subnet_id, nil)
221
+ oFC.oNetwork.routers.get(router.id).destroy
127
222
  rescue => e
128
- Logging.error(e.message)
223
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
224
+ end
225
+ end
226
+
227
+
228
+ # Router interface to connect to the network
229
+ def create_router_interface(subnet, router)
230
+ raise "Internal Error: subnet/router object not passed." if not subnet or not router
231
+
232
+ Logging.debug("Attaching subnet '%s' to router '%s'" % [subnet.name, router.name])
233
+ begin
234
+ router.add_interface(subnet.id, nil)
235
+ rescue => e
236
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
129
237
  end
130
238
  end
131
239
 
132
240
  def delete_router_interface(subnet_id, router)
241
+ Logging.debug("Removing subnet '%s' from router '%s'" % [subnet.name, router.name])
133
242
  begin
134
243
  router.remove_interface(subnet_id)
135
244
  rescue => e
136
- Logging.error(e.message)
245
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
137
246
  end
138
247
  end
139
-
140
- def create_router(name)
248
+
249
+ def get_router_interface(oFC, network_id, device_id)
141
250
  begin
142
- Connection.network.routers.create(
143
- :name => name,
144
- :admin_state_up => true
145
- )
251
+ # Searching for router port attached
252
+ ports=oFC.oNetwork.ports.all({:network_id => network_id, :device_id => device_id})
253
+ case ports.length()
254
+ when 0
255
+ nil
256
+ else
257
+ port[0]
258
+ end
146
259
  rescue => e
147
- Logging.error(e.message)
260
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
148
261
  end
149
262
  end
150
263
 
151
- def delete_router(router_id)
264
+ def get_router_interface_attached(oFC, network)
265
+ Logging.state("Searching for router port attached to the network '%s'" % [network.name] )
152
266
  begin
153
- Connection.network.routers.get(router_id).destroy
267
+ # Searching for router port attached
268
+ ports=oFC.oNetwork.ports.all({:network_id => network.id, :device_type => 'network:router_interface'})
269
+ case ports.length()
270
+ when 0
271
+ Logging.debug("No router port attached to the network '%s'" % [network.name] )
272
+ nil
273
+ else
274
+ Logging.debug("Found a router port attached to the network '%s' " % [network.name] )
275
+ ports[0]
276
+ end
154
277
  rescue => e
155
- Logging.error(e.message)
278
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
156
279
  end
157
280
  end
281
+
282
+ # Gateway management
283
+ def get_gateway(oFC, name)
284
+
285
+ return nil if not name or not oFC
286
+
287
+ Logging.state("Getting gateway '%s'" % [name])
288
+ networks = oFC.oNetwork
289
+ begin
290
+ netty = networks.get(name)
291
+ rescue => e
292
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
293
+ end
294
+ Logging.state("Found gateway '%s'" % [name]) if netty
295
+ Logging.state("Unable to found gateway '%s'" % [name]) if not netty
296
+ return netty
297
+ end
298
+
299
+ def search_gateway(oFC)
300
+ Logging.state("Identifying External gateway ...")
301
+ begin
302
+ # Searching for router port attached
303
+ networks=oFC.oNetwork.networks.all({ :router_external => true })
304
+ case networks.length()
305
+ when 0
306
+ Logging.debug("No external network")
307
+ nil
308
+ when 1
309
+ Logging.debug("Found external network '%s'." % [networks[0].name] )
310
+ networks[0]
311
+ else
312
+ Logging.debug("Found several external networks. Selecting the first one '%s'" % [networks[0].name] )
313
+ networks[0]
314
+ end
315
+ rescue => e
316
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
317
+ end
318
+ end
319
+
158
320
  end
159
321
 
160
322
 
161
- def get_next_subnet
323
+ def get_next_subnet(oFC)
162
324
  begin
163
325
  subnet_values = Array.new
164
- subnets = Connection.network.subnets.all
326
+ subnets = oFC.oNetwork.subnets.all
165
327
 
166
328
  subnets.each do|s|
167
329
  subnet_values.push(s.cidr)
@@ -198,6 +360,6 @@ def get_next_subnet
198
360
  end
199
361
  new_cidr
200
362
  rescue => e
201
- Logging.error(e.message)
363
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
202
364
  end
203
365
  end