sfpagent 0.1.14 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sfpagent might be problematic. Click here for more details.
- data/VERSION +1 -1
- data/lib/sfpagent/agent.rb +91 -52
- data/lib/sfpagent/bsig.rb +54 -39
- data/lib/sfpagent/helper.rb +96 -0
- data/lib/sfpagent/runtime.rb +5 -1
- data/lib/sfpagent/sfplanner.rb +32 -1
- data/lib/sfpagent.rb +1 -1
- metadata +4 -4
- data/lib/sfpagent/net_helper.rb +0 -56
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.3
|
data/lib/sfpagent/agent.rb
CHANGED
@@ -11,7 +11,7 @@ require 'digest/md5'
|
|
11
11
|
|
12
12
|
module Sfp
|
13
13
|
module Agent
|
14
|
-
NetHelper = Object.new.extend(Sfp::Net
|
14
|
+
NetHelper = Object.new.extend(Sfp::Helper::Net)
|
15
15
|
|
16
16
|
CacheDir = (Process.euid == 0 ? '/var/sfpagent' : File.expand_path('~/.sfpagent'))
|
17
17
|
Dir.mkdir(CacheDir, 0700) if not File.exist?(CacheDir)
|
@@ -42,7 +42,7 @@ module Sfp
|
|
42
42
|
|
43
43
|
@@runtime_lock = Mutex.new
|
44
44
|
|
45
|
-
@@agents_database =
|
45
|
+
@@agents_database = {}
|
46
46
|
@@agents_database_modified_time = nil
|
47
47
|
|
48
48
|
def self.logger
|
@@ -53,6 +53,10 @@ module Sfp
|
|
53
53
|
@@config
|
54
54
|
end
|
55
55
|
|
56
|
+
def self.runtime
|
57
|
+
@@runtime
|
58
|
+
end
|
59
|
+
|
56
60
|
# Start the agent.
|
57
61
|
#
|
58
62
|
# options:
|
@@ -511,6 +515,16 @@ module Sfp
|
|
511
515
|
end
|
512
516
|
end
|
513
517
|
|
518
|
+
def self.delete_agents
|
519
|
+
File.open(AgentsDataFile, File::RDWR|File::CREAT, 0644) { |f|
|
520
|
+
f.flock(File::LOCK_EX)
|
521
|
+
f.rewind
|
522
|
+
f.write('{}')
|
523
|
+
f.flush
|
524
|
+
f.truncate(f.pos)
|
525
|
+
}
|
526
|
+
end
|
527
|
+
|
514
528
|
# parameter:
|
515
529
|
# :data => To delete an agent: { "agent_name" => nil }
|
516
530
|
# To add/modify an agent: { "agent_name" => { "sfpAddress" => "10.0.0.1", "sfpPort" => 1314 } }
|
@@ -528,6 +542,7 @@ module Sfp
|
|
528
542
|
json = f.read
|
529
543
|
agents = (json == '' ? {} : JSON[json])
|
530
544
|
current_hash = agents.hash
|
545
|
+
|
531
546
|
data.each { |k,v|
|
532
547
|
if !agents.has_key?(k) or v.nil? or agents[k].hash != v.hash
|
533
548
|
agents[k] = v
|
@@ -544,16 +559,18 @@ module Sfp
|
|
544
559
|
end
|
545
560
|
}
|
546
561
|
|
547
|
-
if updated
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
562
|
+
if updated
|
563
|
+
Thread.new {
|
564
|
+
# if updated then broadcast to other agents
|
565
|
+
http_data = {'agents' => JSON.generate(data)}
|
566
|
+
agents.each { |name,agent|
|
567
|
+
begin
|
568
|
+
code, _ = NetHelper.put_data(agent['sfpAddress'], agent['sfpPort'], '/agents', http_data, 5, 20)
|
569
|
+
raise Exception if code != '200'
|
570
|
+
rescue Exception => e
|
571
|
+
Sfp::Agent.logger.warn "Push agents list to #{agent['sfpAddress']}:#{agent['sfpPort']} [Failed]"
|
572
|
+
end
|
573
|
+
}
|
557
574
|
}
|
558
575
|
end
|
559
576
|
|
@@ -563,6 +580,7 @@ module Sfp
|
|
563
580
|
def self.get_agents
|
564
581
|
return {} if not File.exist?(AgentsDataFile)
|
565
582
|
return @@agents_database if File.mtime(AgentsDataFile) == @@agents_database_modified_time
|
583
|
+
@@agents_database_modified_time = File.mtime(AgentsDataFile)
|
566
584
|
@@agents_database = JSON[File.read(AgentsDataFile)]
|
567
585
|
end
|
568
586
|
|
@@ -677,21 +695,25 @@ module Sfp
|
|
677
695
|
path = (request.path[-1,1] == '/' ? ryyequest.path.chop : request.path)
|
678
696
|
|
679
697
|
if path == '/model' and request.query.has_key?('model')
|
680
|
-
status, content_type, body = self.set_model({:
|
698
|
+
status, content_type, body = self.set_model({:model => request.query['model']})
|
681
699
|
|
682
700
|
elsif path =~ /\/model\/cache\/.+/ and request.query.length > 0
|
683
|
-
status, content_type, body = self.
|
684
|
-
|
701
|
+
status, content_type, body = self.manage_cache_model({:set => true,
|
702
|
+
:name => path[13, path.length-13],
|
703
|
+
:model => request.query['model']})
|
685
704
|
|
686
705
|
elsif path =~ /\/modules\/.+/ and request.query.length > 0
|
687
|
-
status, content_type, body = self.manage_modules({:
|
688
|
-
:
|
706
|
+
status, content_type, body = self.manage_modules({:install => true,
|
707
|
+
:name => path[9, path.length-9],
|
708
|
+
:module => request.query['module']})
|
689
709
|
|
690
710
|
elsif path == '/modules' and request.query.length > 0
|
691
|
-
status, content_type, body = self.manage_modules({:
|
711
|
+
status, content_type, body = self.manage_modules({:install => true,
|
712
|
+
:modules => request.query})
|
692
713
|
|
693
714
|
elsif path == '/agents' and request.query.has_key?('agents')
|
694
|
-
status, content_type, body = self.
|
715
|
+
status, content_type, body = self.manage_agents({:set => true,
|
716
|
+
:agents => request.query['agents']})
|
695
717
|
|
696
718
|
elsif path == '/bsig' and request.query.has_key?('bsig')
|
697
719
|
status, content_type, body = self.set_bsig({:query => request.query})
|
@@ -707,14 +729,17 @@ module Sfp
|
|
707
729
|
response.body = body
|
708
730
|
end
|
709
731
|
|
710
|
-
# Handle HTTP
|
732
|
+
# Handle HTTP Delete request
|
711
733
|
#
|
712
734
|
# uri:
|
713
|
-
# /model
|
714
|
-
#
|
715
|
-
#
|
716
|
-
# /
|
717
|
-
#
|
735
|
+
# /model => delete existing model
|
736
|
+
# /model/cache => delete all cache models
|
737
|
+
# /model/cache/name => delete cache model of agent "name"
|
738
|
+
# /modules => delete all modules from module database
|
739
|
+
# /modules/name => delete module "name" from module database
|
740
|
+
# /agents => delete all agents from agent database
|
741
|
+
# /agents/name => delete "name" from agent database
|
742
|
+
# /bsig => delete existing BSig model
|
718
743
|
#
|
719
744
|
def do_DELETE(request, response)
|
720
745
|
status = 400
|
@@ -728,19 +753,19 @@ module Sfp
|
|
728
753
|
status, content_type, body = self.set_model
|
729
754
|
|
730
755
|
elsif path == '/model/cache'
|
731
|
-
status, content_type, body = self.
|
756
|
+
status, content_type, body = self.manage_cache_model({:delete => true, :name => :all})
|
732
757
|
|
733
758
|
elsif path =~ /\/model\/cache\/.+/
|
734
|
-
status, content_type, body = self.
|
759
|
+
status, content_type, body = self.manage_cache_model({:delete => true, :name => path[13, path.length-13]})
|
735
760
|
|
736
761
|
elsif path == '/modules'
|
737
|
-
status, content_type, body = self.manage_modules({:
|
762
|
+
status, content_type, body = self.manage_modules({:uninstall => true, :name => :all})
|
738
763
|
|
739
764
|
elsif path =~ /\/modules\/.+/
|
740
|
-
status, content_type, body = self.manage_modules({:name => path[9, path.length-9]})
|
765
|
+
status, content_type, body = self.manage_modules({:uninstall => true, :name => path[9, path.length-9]})
|
741
766
|
|
742
767
|
elsif path == '/agents'
|
743
|
-
status, content_type, body = self.
|
768
|
+
status, content_type, body = self.manage_agents({:delete => true, :name => :all})
|
744
769
|
|
745
770
|
elsif path == '/bsig'
|
746
771
|
status, content_type, body = self.set_bsig
|
@@ -750,12 +775,18 @@ module Sfp
|
|
750
775
|
end
|
751
776
|
end
|
752
777
|
|
753
|
-
def
|
778
|
+
def manage_agents(p={})
|
754
779
|
begin
|
755
|
-
if p[:
|
756
|
-
|
757
|
-
|
758
|
-
|
780
|
+
if p[:delete]
|
781
|
+
if p[:name] == :all
|
782
|
+
return [200, '', ''] if Sfp::Agent.delete_agents
|
783
|
+
elsif p[:name] != ''
|
784
|
+
return [200, '', ''] if Sfp::Agent.set_agents({p[:name] => nil})
|
785
|
+
else
|
786
|
+
return [400, '', '']
|
787
|
+
end
|
788
|
+
elsif p[:set]
|
789
|
+
return [200, '', ''] if Sfp::Agent.set_agents(JSON[p[:agents]])
|
759
790
|
end
|
760
791
|
rescue Exception => e
|
761
792
|
@logger.error "Saving agents list [Failed]\n#{e}\n#{e.backtrace.join("\n")}"
|
@@ -764,18 +795,23 @@ module Sfp
|
|
764
795
|
end
|
765
796
|
|
766
797
|
def manage_modules(p={})
|
767
|
-
if p[:
|
768
|
-
if p[:
|
769
|
-
return [200, '', ''] if Sfp::Agent.install_module(p[:name], p[:
|
798
|
+
if p[:install]
|
799
|
+
if p[:name] and p[:module]
|
800
|
+
return [200, '', ''] if Sfp::Agent.install_module(p[:name], p[:module])
|
801
|
+
elsif p[:modules]
|
802
|
+
return [200, '', ''] if Sfp::Agent.install_modules(p[:modules])
|
770
803
|
else
|
804
|
+
return [400, '', '']
|
805
|
+
end
|
806
|
+
elsif p[:uninstall]
|
807
|
+
if p[:name] == :all
|
808
|
+
return [200, '', ''] if Sfp::Agent.uninstall_all_modules
|
809
|
+
elsif p[:name] != ''
|
771
810
|
return [200, '', ''] if Sfp::Agent.uninstall_module(p[:name])
|
811
|
+
else
|
812
|
+
return [400, '', '']
|
772
813
|
end
|
773
|
-
elsif p[:query].length > 0
|
774
|
-
return [200, '', ''] if Sfp::Agent.install_modules(p[:query])
|
775
|
-
else
|
776
|
-
return [200, '', ''] if Sfp::Agent.uninstall_all_modules
|
777
814
|
end
|
778
|
-
|
779
815
|
[500, '', '']
|
780
816
|
end
|
781
817
|
|
@@ -788,19 +824,22 @@ module Sfp
|
|
788
824
|
end
|
789
825
|
end
|
790
826
|
|
791
|
-
def
|
792
|
-
|
793
|
-
|
794
|
-
if p[:name]
|
827
|
+
def manage_cache_model(p={})
|
828
|
+
if p[:set] and p[:name] and p[:model]
|
829
|
+
p[:model] = JSON[p[:model]]
|
795
830
|
return [200, '', ''] if Sfp::Agent.set_cache_model(p)
|
831
|
+
elsif p[:delete] and p[:name]
|
832
|
+
if p[:name] == :all
|
833
|
+
return [200, '', ''] if Sfp::Agent.set_cache_model
|
834
|
+
else
|
835
|
+
return [200, '', ''] if Sfp::Agent.set_cache_model({:name => p[:name]})
|
836
|
+
end
|
796
837
|
else
|
797
|
-
return [
|
838
|
+
return [400, '', '']
|
798
839
|
end
|
799
|
-
|
800
840
|
[500, '', '']
|
801
841
|
end
|
802
842
|
|
803
|
-
|
804
843
|
def get_sfp(p={})
|
805
844
|
begin
|
806
845
|
module_name, _ = p[:module].split('/', 2)
|
@@ -827,9 +866,9 @@ module Sfp
|
|
827
866
|
end
|
828
867
|
|
829
868
|
def set_model(p={})
|
830
|
-
if p[:
|
869
|
+
if p[:model]
|
831
870
|
# If setting the model was success, then return '200' status.
|
832
|
-
return [200, '', ''] if Sfp::Agent.set_model(JSON[p[:
|
871
|
+
return [200, '', ''] if Sfp::Agent.set_model(JSON[p[:model]])
|
833
872
|
else
|
834
873
|
# Removing the existing model by setting an empty model, if it's success then return '200' status.
|
835
874
|
return [200, '', ''] if Sfp::Agent.set_model({})
|
data/lib/sfpagent/bsig.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'thread'
|
2
2
|
|
3
3
|
class Sfp::BSig
|
4
|
-
include Sfp::Net
|
4
|
+
include Sfp::Helper::Net
|
5
5
|
|
6
6
|
SleepTime = 5
|
7
7
|
MaxTries = 5
|
@@ -108,8 +108,8 @@ class Sfp::BSig
|
|
108
108
|
operator = select_operator(flaws, operators, pi)
|
109
109
|
return :failure if operator.nil?
|
110
110
|
|
111
|
-
# debugging
|
112
|
-
#Sfp::Agent.logger.info "[#{mode}] Flaws: #{JSON.generate(flaws)}"
|
111
|
+
# debugging
|
112
|
+
#Sfp::Agent.logger.info "[#{mode}] Flaws: #{JSON.generate(flaws)}"
|
113
113
|
|
114
114
|
return :ongoing if not lock_operator(operator)
|
115
115
|
|
@@ -118,8 +118,8 @@ class Sfp::BSig
|
|
118
118
|
next_pi = operator['pi'] + 1
|
119
119
|
pre_local, pre_remote = split_preconditions(operator)
|
120
120
|
|
121
|
-
# debugging
|
122
|
-
#Sfp::Agent.logger.info "[#{mode}] local-flaws: #{JSON.generate(pre_local)}, remote-flaws: #{JSON.generate(pre_remote)}"
|
121
|
+
# debugging
|
122
|
+
#Sfp::Agent.logger.info "[#{mode}] local-flaws: #{JSON.generate(pre_local)}, remote-flaws: #{JSON.generate(pre_remote)}"
|
123
123
|
|
124
124
|
status = nil
|
125
125
|
tries = MaxTries
|
@@ -149,7 +149,6 @@ class Sfp::BSig
|
|
149
149
|
end
|
150
150
|
|
151
151
|
def achieve_remote_goal(id, goal, pi, mode)
|
152
|
-
|
153
152
|
if goal.length > 0
|
154
153
|
agents = Sfp::Agent.get_agents
|
155
154
|
split_goal_by_agent(goal).each do |agent_name,agent_goal|
|
@@ -161,6 +160,7 @@ class Sfp::BSig
|
|
161
160
|
end
|
162
161
|
end
|
163
162
|
end
|
163
|
+
|
164
164
|
true
|
165
165
|
end
|
166
166
|
|
@@ -178,7 +178,6 @@ class Sfp::BSig
|
|
178
178
|
return false if not @enabled
|
179
179
|
|
180
180
|
bsig = Sfp::Agent.get_bsig
|
181
|
-
|
182
181
|
return false if bsig.nil? or id < bsig['id']
|
183
182
|
|
184
183
|
status = nil
|
@@ -242,38 +241,67 @@ class Sfp::BSig
|
|
242
241
|
end
|
243
242
|
|
244
243
|
def split_goal_by_agent(goal)
|
245
|
-
#agents = Sfp::Agent.get_agents
|
246
244
|
agent_goal = {}
|
247
245
|
goal.each { |var,val|
|
248
246
|
_, agent_name, _ = var.split('.', 3)
|
249
|
-
#fail "Agent #{agent_name} is not in database!" if not agents.has_key?(agent_name)
|
250
247
|
agent_goal[agent_name] = {} if not agent_goal.has_key?(agent_name)
|
251
248
|
agent_goal[agent_name][var] = val
|
252
249
|
}
|
253
250
|
agent_goal
|
254
251
|
end
|
255
252
|
|
256
|
-
def send_goal_to_agent(agent, id,
|
253
|
+
def send_goal_to_agent(agent, id, goal, pi, agent_name='', mode)
|
257
254
|
begin
|
258
255
|
data = {'id' => id,
|
259
|
-
'goal' => JSON.generate(
|
256
|
+
'goal' => JSON.generate(goal),
|
260
257
|
'pi' => pi}
|
261
|
-
|
262
258
|
Sfp::Agent.logger.info "[#{mode}] Request goal to: #{agent_name} [WAIT]"
|
263
|
-
|
264
259
|
code, _ = put_data(agent['sfpAddress'], agent['sfpPort'], SatisfierPath, data)
|
265
|
-
|
266
260
|
Sfp::Agent.logger.info "[#{mode}] Request goal to: #{agent_name} - status: #{code}"
|
267
|
-
|
268
261
|
(code == '200')
|
269
262
|
rescue
|
263
|
+
return true if check_not_created_agent(agent_name, goal)
|
270
264
|
false
|
271
265
|
end
|
272
266
|
end
|
273
267
|
|
268
|
+
def check_not_created_agent(agent_name, goal)
|
269
|
+
state = Sfp::Agent.get_state
|
270
|
+
vms = {}
|
271
|
+
Sfp::Agent.runtime.cloudfinder.clouds.each { |cloud|
|
272
|
+
cloud.sub!(/^\$\./, '')
|
273
|
+
cloud_ref = "$.#{Sfp::Agent.whoami?}.#{cloud}"
|
274
|
+
ref = "#{cloud_ref}.vms"
|
275
|
+
vms = state.at?(ref)
|
276
|
+
vms.each { |name,status| vms[name] = {'created' => true} } if vms.is_a?(Hash)
|
277
|
+
}
|
278
|
+
if not vms.has_key?(agent_name)
|
279
|
+
state = {agent_name => {'created' => false, 'in_cloud' => nil}}
|
280
|
+
goal.each { |var,val| return false if state.at?(var) != val }
|
281
|
+
return true
|
282
|
+
end
|
283
|
+
false
|
284
|
+
end
|
285
|
+
|
274
286
|
def get_current_state
|
275
287
|
state = Sfp::Agent.get_state
|
276
288
|
fail "BSig engine cannot get current state" if state == false
|
289
|
+
|
290
|
+
Sfp::Agent.runtime.cloudfinder.clouds.each { |cloud|
|
291
|
+
cloud.sub!(/^\$\./, '')
|
292
|
+
cloud_ref = "$.#{Sfp::Agent.whoami?}.#{cloud}"
|
293
|
+
ref = "#{cloud_ref}.vms"
|
294
|
+
vms = state.at?(ref)
|
295
|
+
if vms.is_a?(Hash)
|
296
|
+
vms.each { |name,status|
|
297
|
+
state[name] = { 'created' => true,
|
298
|
+
'in_cloud' => cloud_ref,
|
299
|
+
'sfpAddress' => status['ip'],
|
300
|
+
'sfpPort' => Sfp::Agent::DefaultPort }
|
301
|
+
}
|
302
|
+
end
|
303
|
+
}
|
304
|
+
|
277
305
|
state
|
278
306
|
end
|
279
307
|
|
@@ -281,13 +309,14 @@ class Sfp::BSig
|
|
281
309
|
return goal.clone if current.nil?
|
282
310
|
flaws = {}
|
283
311
|
goal.each { |var,val|
|
284
|
-
|
285
|
-
if
|
286
|
-
|
287
|
-
|
288
|
-
|
312
|
+
current_value = current.at?(var)
|
313
|
+
if current_value.is_a?(Sfp::Unknown)
|
314
|
+
_, agent_name, _ = var.split('.', 3)
|
315
|
+
if agent_name != Sfp::Agent.whoami?
|
316
|
+
s = {agent_name => {'created' => false, 'in_cloud' => nil}}
|
317
|
+
current_value = s.at?(var)
|
318
|
+
end
|
289
319
|
end
|
290
|
-
|
291
320
|
if current_value.is_a?(Sfp::Undefined)
|
292
321
|
flaws[var] = val if not val.is_a?(Sfp::Undefined)
|
293
322
|
else
|
@@ -359,7 +388,7 @@ class Sfp::BSig
|
|
359
388
|
@lock_postprocess.synchronize {
|
360
389
|
_, agent_name, _ = operator['name'].split('.', 3)
|
361
390
|
|
362
|
-
Sfp::Agent.logger.info "Postprocess delete VM #{agent_name}"
|
391
|
+
Sfp::Agent.logger.info "Postprocess delete VM #{agent_name}"
|
363
392
|
|
364
393
|
# update agents database (automatically broadcast to other agents)
|
365
394
|
Sfp::Agent.set_agents({agent_name => nil})
|
@@ -373,7 +402,7 @@ Sfp::Agent.logger.info "Postprocess delete VM #{agent_name}"
|
|
373
402
|
|
374
403
|
_, agent_name, _ = operator['parameters']['$.vm'].split('.', 3)
|
375
404
|
|
376
|
-
Sfp::Agent.logger.info "Postprocess create VM #{agent_name}"
|
405
|
+
Sfp::Agent.logger.info "Postprocess create VM #{agent_name}"
|
377
406
|
|
378
407
|
# update proxy component's state
|
379
408
|
state = Sfp::Agent.get_state
|
@@ -390,6 +419,8 @@ Sfp::Agent.logger.info "Postprocess create VM #{agent_name}"
|
|
390
419
|
# get new agent's model and BSig model from cache database
|
391
420
|
model = Sfp::Agent.get_cache_model(agent_name)
|
392
421
|
model['model']['in_cloud'] = refs[0..-2].join('.')
|
422
|
+
model['model']['sfpAddress'] = vms[agent_name]['ip']
|
423
|
+
model['model']['sfpPort'] = Sfp::Agent::DefaultPort
|
393
424
|
|
394
425
|
if not model.nil?
|
395
426
|
address = data[agent_name]['sfpAddress']
|
@@ -467,20 +498,4 @@ Sfp::Agent.logger.info "Postprocess create VM #{agent_name}"
|
|
467
498
|
|
468
499
|
end
|
469
500
|
|
470
|
-
module Sfp::Helper
|
471
|
-
end
|
472
|
-
|
473
|
-
class Sfp::Helper::SchemaCollector
|
474
|
-
attr_reader :schemata
|
475
|
-
def initialize
|
476
|
-
@schemata = []
|
477
|
-
end
|
478
|
-
|
479
|
-
def visit(name, value, parent)
|
480
|
-
if value.is_a?(Hash) and value.has_key?('_classes')
|
481
|
-
value['_classes'].each { |s| @schemata << s }
|
482
|
-
end
|
483
|
-
true
|
484
|
-
end
|
485
|
-
end
|
486
501
|
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Sfp::Helper
|
2
|
+
end
|
3
|
+
|
4
|
+
module Sfp::Helper::Net
|
5
|
+
def post_data(address, port, path, data, open_timeout=5, read_timeout=1800)
|
6
|
+
uri = create_uri(address, port, path)
|
7
|
+
req = Net::HTTP::Post.new(uri.path)
|
8
|
+
req.set_form_data(data)
|
9
|
+
http_request(uri, req, open_timeout, read_timeout)
|
10
|
+
end
|
11
|
+
|
12
|
+
def put_data(address, port, path, data, open_timeout=5, read_timeout=1800)
|
13
|
+
uri = create_uri(address, port, path)
|
14
|
+
req = Net::HTTP::Put.new(uri.path)
|
15
|
+
req.set_form_data(data)
|
16
|
+
http_request(uri, req, open_timeout, read_timeout)
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_data(address, port, path, open_timeout=5, read_timeout=1800)
|
20
|
+
uri = create_uri(address, port, path)
|
21
|
+
req = Net::HTTP::Get.new(uri.path)
|
22
|
+
http_request(uri, req, open_timeout, read_timeout)
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete_data(address, port, path, open_timeout=5, read_timeout=1800)
|
26
|
+
uri = create_uri(address, port, path)
|
27
|
+
req = Net::HTTP::Delete.new(uri.path)
|
28
|
+
http_request(uri, req, open_timeout, read_timeout)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def create_uri(address, port, path)
|
33
|
+
address = address.to_s.strip
|
34
|
+
port = port.to_s.strip
|
35
|
+
path = path.to_s.strip
|
36
|
+
raise Exception, "Invalid parameters [address:#{address},port:#{port},path:#{path}]" if
|
37
|
+
address.length <= 0 or port.length <= 0 or path.length <= 0
|
38
|
+
path.sub!(/^\/+/, '')
|
39
|
+
URI.parse("http://#{address}:#{port}/#{path}")
|
40
|
+
end
|
41
|
+
|
42
|
+
def use_http_proxy?(uri)
|
43
|
+
ENV['no_proxy'].to_s.split(',').each { |pattern|
|
44
|
+
pattern.chop! if pattern[-1] == '*'
|
45
|
+
return false if uri.host[0,pattern.length] == pattern
|
46
|
+
}
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
def http_request(uri, request, open_timeout=5, read_timeout=1800)
|
51
|
+
if ENV['http_proxy'].to_s.strip != '' and use_http_proxy?(uri)
|
52
|
+
proxy = URI.parse(ENV['http_proxy'])
|
53
|
+
http = Net::HTTP::Proxy(proxy.host, proxy.port).new(uri.host, uri.port)
|
54
|
+
else
|
55
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
56
|
+
end
|
57
|
+
http.open_timeout = open_timeout
|
58
|
+
http.read_timeout = read_timeout
|
59
|
+
http.start
|
60
|
+
http.request(request) { |res| return [res.code, res.body] }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Sfp::Helper::SchemaCollector
|
65
|
+
attr_reader :schemata
|
66
|
+
def initialize
|
67
|
+
@schemata = []
|
68
|
+
end
|
69
|
+
|
70
|
+
def visit(name, value, parent)
|
71
|
+
if value.is_a?(Hash) and value.has_key?('_classes')
|
72
|
+
value['_classes'].each { |s| @schemata << s }
|
73
|
+
end
|
74
|
+
true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class Sfp::Helper::CloudFinder
|
79
|
+
CloudSchema = '$.Cloud'
|
80
|
+
attr_accessor :clouds
|
81
|
+
|
82
|
+
def reset
|
83
|
+
@clouds = []
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
def visit(name, value, parent)
|
88
|
+
if value.is_a?(Hash)
|
89
|
+
if value['_context'] == 'object'
|
90
|
+
@clouds << parent.ref.push(name) if value.has_key?('_classes') and value['_classes'].index(CloudSchema)
|
91
|
+
return true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
false
|
95
|
+
end
|
96
|
+
end
|
data/lib/sfpagent/runtime.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'thread'
|
2
2
|
|
3
3
|
class Sfp::Runtime
|
4
|
-
attr_reader :root
|
4
|
+
attr_reader :root, :cloudfinder
|
5
5
|
|
6
6
|
def initialize(model)
|
7
7
|
@mutex_procedure = Mutex.new
|
8
8
|
@mutex_get_state = Mutex.new
|
9
9
|
@root = nil
|
10
|
+
@cloudfinder = Sfp::Helper::CloudFinder.new
|
10
11
|
set_model(model)
|
11
12
|
end
|
12
13
|
|
@@ -48,6 +49,9 @@ class Sfp::Runtime
|
|
48
49
|
root_model.accept(ParentEliminator)
|
49
50
|
@root = update_model(root_model, root_model, '$')
|
50
51
|
@root.accept(ParentGenerator)
|
52
|
+
|
53
|
+
@cloudfinder.clouds = []
|
54
|
+
@model.accept(@cloudfinder.reset)
|
51
55
|
end
|
52
56
|
}
|
53
57
|
end
|
data/lib/sfpagent/sfplanner.rb
CHANGED
@@ -57,6 +57,34 @@ class Planner
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def to_image(p={})
|
60
|
+
def self.dot2image(dot, image_file)
|
61
|
+
dot_file = "/tmp/#{Time.now.getutc.to_i}.dot"
|
62
|
+
File.open(dot_file, 'w') { |f|
|
63
|
+
f.write(dot)
|
64
|
+
f.flush
|
65
|
+
}
|
66
|
+
!!system("dot -Tpng -o #{image_file} #{dot_file}")
|
67
|
+
ensure
|
68
|
+
File.delete(dot_file) if File.exist?(dot_file)
|
69
|
+
end
|
70
|
+
|
71
|
+
dot = "digraph {\n"
|
72
|
+
@variables.each do |sym,var|
|
73
|
+
name = var.name.gsub(/[\s\.\$]/, '_')
|
74
|
+
dot += "#{name} [label=\"#{var.name}\", shape=rect];\n"
|
75
|
+
end
|
76
|
+
@variables.each do |sym,var|
|
77
|
+
name = var.name.gsub(/[\s\.\$]/, '_')
|
78
|
+
var.dependencies.each { |sym,operators|
|
79
|
+
var2 = @variables[sym]
|
80
|
+
name2 = var2.name.gsub(/[\s\.\$]/, '_')
|
81
|
+
dot += "#{name} -> #{name2} ;\n"
|
82
|
+
}
|
83
|
+
end
|
84
|
+
dot += "}"
|
85
|
+
puts dot
|
86
|
+
|
87
|
+
dot2image(dot, p[:file])
|
60
88
|
end
|
61
89
|
|
62
90
|
class Variable < Array
|
@@ -214,4 +242,7 @@ class Planner
|
|
214
242
|
end
|
215
243
|
end
|
216
244
|
|
217
|
-
|
245
|
+
if $0 == __FILE__ and ARGV.length > 0
|
246
|
+
planner = Planner.new(:sas => File.read(ARGV[0]))
|
247
|
+
planner.to_image(:file => 'domain.png')
|
248
|
+
end
|
data/lib/sfpagent.rb
CHANGED
@@ -12,7 +12,7 @@ end
|
|
12
12
|
# internal dependencies
|
13
13
|
libdir = File.expand_path(File.dirname(__FILE__))
|
14
14
|
|
15
|
-
require libdir + '/sfpagent/
|
15
|
+
require libdir + '/sfpagent/helper.rb'
|
16
16
|
require libdir + '/sfpagent/runtime.rb'
|
17
17
|
require libdir + '/sfpagent/module.rb'
|
18
18
|
require libdir + '/sfpagent/bsig.rb'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sfpagent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2013-08-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sfp
|
16
|
-
requirement: &
|
16
|
+
requirement: &14891600 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 0.3.12
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *14891600
|
25
25
|
description: A Ruby implementation of SFP agent.
|
26
26
|
email: herry13@gmail.com
|
27
27
|
executables:
|
@@ -39,8 +39,8 @@ files:
|
|
39
39
|
- lib/sfpagent.rb
|
40
40
|
- lib/sfpagent/agent.rb
|
41
41
|
- lib/sfpagent/bsig.rb
|
42
|
+
- lib/sfpagent/helper.rb
|
42
43
|
- lib/sfpagent/module.rb
|
43
|
-
- lib/sfpagent/net_helper.rb
|
44
44
|
- lib/sfpagent/runtime.rb
|
45
45
|
- lib/sfpagent/sfplanner.rb
|
46
46
|
- sfpagent.gemspec
|
data/lib/sfpagent/net_helper.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'uri'
|
2
|
-
require 'net/http'
|
3
|
-
|
4
|
-
module Sfp::Net
|
5
|
-
end
|
6
|
-
|
7
|
-
module Sfp::Net::Helper
|
8
|
-
def http_request(uri, request, open_timeout=5, read_timeout=1800)
|
9
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
10
|
-
http.open_timeout = open_timeout
|
11
|
-
http.read_timeout = read_timeout
|
12
|
-
http.start
|
13
|
-
http.request(request) { |res| return [res.code, res.body] }
|
14
|
-
end
|
15
|
-
|
16
|
-
def post_data(address, port, path, data, open_timeout=5, read_timeout=1800)
|
17
|
-
address = address.to_s.strip
|
18
|
-
port = port.to_s.strip
|
19
|
-
path = path.to_s.strip
|
20
|
-
raise Exception, "Invalid parameters [address:#{address},port:#{port},path:#{path}]" if
|
21
|
-
address.length <= 0 or port.length <= 0 or path.length <= 0
|
22
|
-
|
23
|
-
path.sub!(/^\/+/, '')
|
24
|
-
url = URI.parse("http://#{address}:#{port}/#{path}")
|
25
|
-
req = Net::HTTP::Post.new(url.path)
|
26
|
-
req.set_form_data(data)
|
27
|
-
http_request(url, req, open_timeout, read_timeout)
|
28
|
-
end
|
29
|
-
|
30
|
-
def put_data(address, port, path, data, open_timeout=5, read_timeout=1800)
|
31
|
-
address = address.to_s.strip
|
32
|
-
port = port.to_s.strip
|
33
|
-
path = path.to_s.strip
|
34
|
-
raise Exception, "Invalid parameters [address:#{address},port:#{port},path:#{path}]" if
|
35
|
-
address.length <= 0 or port.length <= 0 or path.length <= 0
|
36
|
-
|
37
|
-
path.sub!(/^\/+/, '')
|
38
|
-
url = URI.parse("http://#{address}:#{port}/#{path}")
|
39
|
-
req = Net::HTTP::Put.new(url.path)
|
40
|
-
req.set_form_data(data)
|
41
|
-
http_request(url, req, open_timeout, read_timeout)
|
42
|
-
end
|
43
|
-
|
44
|
-
def get_data(address, port, path, open_timeout=5, read_timeout=1800)
|
45
|
-
address = address.to_s.strip
|
46
|
-
port = port.to_s.strip
|
47
|
-
path = path.to_s.strip
|
48
|
-
raise Exception, "Invalid parameters [address:#{address},port:#{port},path:#{path}]" if
|
49
|
-
address.length <= 0 or port.length <= 0 or path.length <= 0
|
50
|
-
|
51
|
-
path.sub!(/^\/+/, '')
|
52
|
-
url = URI.parse("http://#{address}:#{port}/#{path}")
|
53
|
-
req = Net::HTTP::Get.new(url.path)
|
54
|
-
http_request(url, req, open_timeout, read_timeout)
|
55
|
-
end
|
56
|
-
end
|