omf_sfa 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +24 -0
- data/Gemfile +6 -0
- data/README.md +211 -0
- data/Rakefile +23 -0
- data/bin/parse_rspec.rb +167 -0
- data/etc/omf-sfa/omf-sfa-am.yaml +12 -0
- data/examples/exogeni5nodemanifest.rspec +105 -0
- data/examples/instageni5nodemanifest.rspec +150 -0
- data/lib/omf-sfa/am/am-rest/REST_API.md +301 -0
- data/lib/omf-sfa/am/am-rest/account_handler.rb +145 -0
- data/lib/omf-sfa/am/am-rest/am_rest_server.rb +255 -0
- data/lib/omf-sfa/am/am-rest/api_template.html +48 -0
- data/lib/omf-sfa/am/am-rest/config.ru +110 -0
- data/lib/omf-sfa/am/am-rest/resource_handler.rb +178 -0
- data/lib/omf-sfa/am/am-rest/rest_handler.rb +573 -0
- data/lib/omf-sfa/am/am-rest/session_authenticator.rb +130 -0
- data/lib/omf-sfa/am/am-rpc/abstract_rpc_service.rb +60 -0
- data/lib/omf-sfa/am/am-rpc/am_authorizer.rb +161 -0
- data/lib/omf-sfa/am/am-rpc/am_rpc_api.rb +450 -0
- data/lib/omf-sfa/am/am-rpc/am_rpc_service.rb +402 -0
- data/lib/omf-sfa/am/am_liaison.rb +93 -0
- data/lib/omf-sfa/am/am_manager.rb +859 -0
- data/lib/omf-sfa/am/am_runner.rb +108 -0
- data/lib/omf-sfa/am/am_scheduler.rb +146 -0
- data/lib/omf-sfa/am/am_server.rb +194 -0
- data/lib/omf-sfa/am/config.ru +122 -0
- data/lib/omf-sfa/am/credential.rb +145 -0
- data/lib/omf-sfa/am/default_authorizer.rb +44 -0
- data/lib/omf-sfa/am/privilege_credential.rb +76 -0
- data/lib/omf-sfa/am/signature.rb +37 -0
- data/lib/omf-sfa/am/user_credential.rb +56 -0
- data/lib/omf-sfa/am.rb +7 -0
- data/lib/omf-sfa/model/abstract_prop_description.rb +87 -0
- data/lib/omf-sfa/model/model_class_description.rb +145 -0
- data/lib/omf-sfa/model/model_data_prop_description.rb +28 -0
- data/lib/omf-sfa/model/model_obj_prop_description.rb +49 -0
- data/lib/omf-sfa/model/ontology.rb +169 -0
- data/lib/omf-sfa/resource/README.md +24 -0
- data/lib/omf-sfa/resource/channel.rb +49 -0
- data/lib/omf-sfa/resource/comp_group.rb +41 -0
- data/lib/omf-sfa/resource/component_lease.rb +10 -0
- data/lib/omf-sfa/resource/constants.rb +24 -0
- data/lib/omf-sfa/resource/group_component.rb +35 -0
- data/lib/omf-sfa/resource/group_membership.rb +17 -0
- data/lib/omf-sfa/resource/gurn.rb +187 -0
- data/lib/omf-sfa/resource/interface.rb +78 -0
- data/lib/omf-sfa/resource/ip.rb +48 -0
- data/lib/omf-sfa/resource/link.rb +29 -0
- data/lib/omf-sfa/resource/node.rb +75 -0
- data/lib/omf-sfa/resource/oaccount.rb +94 -0
- data/lib/omf-sfa/resource/ocomponent.rb +134 -0
- data/lib/omf-sfa/resource/ogroup.rb +106 -0
- data/lib/omf-sfa/resource/olease.rb +61 -0
- data/lib/omf-sfa/resource/oproperty.rb +178 -0
- data/lib/omf-sfa/resource/oreference.rb +15 -0
- data/lib/omf-sfa/resource/oresource.rb +491 -0
- data/lib/omf-sfa/resource/project.rb +28 -0
- data/lib/omf-sfa/resource/project_membership.rb +13 -0
- data/lib/omf-sfa/resource/sfa_base.rb +544 -0
- data/lib/omf-sfa/resource/user.rb +25 -0
- data/lib/omf-sfa/resource.rb +20 -0
- data/lib/omf-sfa/util/create_sample_testbed.rb +68 -0
- data/lib/omf-sfa/util/load_from_sfa_xml.rb +65 -0
- data/lib/omf-sfa/version.rb +4 -0
- data/lib/omf_sfa.rb +5 -0
- data/omf_sfa.gemspec +46 -0
- data/owl/README +3 -0
- data/owl/ben-6509.rdf +1377 -0
- data/owl/ben-dell.rdf +586 -0
- data/owl/ben-dtn.rdf +1698 -0
- data/owl/ben.rdf +1335 -0
- data/owl/collections.owl +309 -0
- data/owl/compute.owl +1486 -0
- data/owl/domain.owl +444 -0
- data/owl/dtn.owl +1165 -0
- data/owl/ec2.owl +385 -0
- data/owl/ethernet.owl +466 -0
- data/owl/eucalyptus.owl +431 -0
- data/owl/id-mp-Request1.rdf +247 -0
- data/owl/itu-grid.owl +147 -0
- data/owl/kansei.owl +511 -0
- data/owl/layer.owl +645 -0
- data/owl/location.owl +117 -0
- data/owl/mass.rdf +608 -0
- data/owl/nlr.rdf +901 -0
- data/owl/orca.owl +181 -0
- data/owl/planetlab.owl +124 -0
- data/owl/protogeni.owl +467 -0
- data/owl/request-6509-2.rdf +150 -0
- data/owl/request-6509-3.rdf +158 -0
- data/owl/request-6509.rdf +199 -0
- data/owl/request.owl +222 -0
- data/owl/storage.owl +511 -0
- data/owl/topology.owl +608 -0
- data/schema/rspec-v3/ad-common.xsd +269 -0
- data/schema/rspec-v3/ad-reservation.rnc +12 -0
- data/schema/rspec-v3/ad-reservation.rng +28 -0
- data/schema/rspec-v3/ad-reservation.xsd +13 -0
- data/schema/rspec-v3/ad.rnc +151 -0
- data/schema/rspec-v3/ad.xsd +77 -0
- data/schema/rspec-v3/any-extension-schema.xsd +38 -0
- data/schema/rspec-v3/any-extension.rnc +30 -0
- data/schema/rspec-v3/common.rnc +185 -0
- data/schema/rspec-v3/manifest-common.xsd +244 -0
- data/schema/rspec-v3/manifest-request.xsd +95 -0
- data/schema/rspec-v3/manifest.rnc +62 -0
- data/schema/rspec-v3/manifest.xsd +34 -0
- data/schema/rspec-v3/request-common.xsd +219 -0
- data/schema/rspec-v3/request-reservation.rnc +12 -0
- data/schema/rspec-v3/request-reservation.xsd +13 -0
- data/schema/rspec-v3/request.rnc +118 -0
- data/schema/rspec-v3/request.xsd +94 -0
- data/share/assets/css/default.css +147 -0
- data/share/assets/css/rest_api.css +0 -0
- data/share/assets/network.html +28 -0
- data/share/assets/network.js +82 -0
- data/spec/am/am-rest/common.rb +29 -0
- data/spec/am/am-rest/resource_group_handler_XspecX.rb +97 -0
- data/spec/am/am-rest/resource_handler_spec.rb +204 -0
- data/spec/am/am-rpc/sfa_methods_spec.rb +150 -0
- data/spec/am/am_manager_spec.rb +307 -0
- data/spec/am/am_scheduler_spec.rb +57 -0
- data/spec/am/common.rb +24 -0
- data/spec/resource/common.rb +31 -0
- data/spec/resource/node_spec.rb +171 -0
- data/spec/resource/oaccount_spec.rb +92 -0
- data/spec/resource/ocomponent_spec.rb +225 -0
- data/spec/resource/ogroup_spec.rb +93 -0
- data/spec/resource/oresource_spec.rb +208 -0
- data/spec/resource_and_leases_spec.rb +377 -0
- data/test/OLD_FILES/assertion1.xml +117 -0
- data/test/OLD_FILES/greeter_spec.rb +15 -0
- data/test/OLD_FILES/mongo_test.rb +45 -0
- data/test/OLD_FILES/req-sfa-2.xml +6 -0
- data/test/OLD_FILES/req-sfa-g.xml +8 -0
- data/test/OLD_FILES/req-sfa-g2.xml +10 -0
- data/test/OLD_FILES/req-sfa-g3.xml +14 -0
- data/test/OLD_FILES/req-sfa.xml +6 -0
- data/test/OLD_FILES/req1.xml +22 -0
- data/test/OLD_FILES/req1b.xml +15 -0
- data/test/OLD_FILES/rspec-test.xml +1867 -0
- data/test/OLD_FILES/test.rb +67 -0
- data/test/OLD_FILES/test2.rb +32 -0
- data/test/am/am_manager_rspec_tests.rb +378 -0
- data/test/am/am_manager_tests.rb +518 -0
- data/test/am/am_scheduler_tests.rb +173 -0
- data/test/resource/olease_test.rb +74 -0
- data/test/sfa_requests/request.xml +5 -0
- data/test/sfa_requests/request1.xml +5 -0
- data/test/sfa_requests/request2.xml +5 -0
- data/test/sfa_requests/request3.xml +5 -0
- metadata +601 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
|
|
2
|
+
require 'omf-sfa/am'
|
|
3
|
+
require 'thin'
|
|
4
|
+
|
|
5
|
+
# Add code to Thin::Connection to verify peer certificate
|
|
6
|
+
#
|
|
7
|
+
module Thin
|
|
8
|
+
class Connection
|
|
9
|
+
def ssl_verify_peer(cert_s)
|
|
10
|
+
true # will be verified later
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module OMF::SFA::AM
|
|
16
|
+
class Runner < Thin::Runner
|
|
17
|
+
@@instance = nil
|
|
18
|
+
|
|
19
|
+
def self.instance
|
|
20
|
+
@@instance
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(argv, opts = {})
|
|
24
|
+
raise "SINGLETON" if @@instance
|
|
25
|
+
|
|
26
|
+
@argv = argv
|
|
27
|
+
sopts = opts.delete(:ssl) # runner has it's own idea of ssl options
|
|
28
|
+
|
|
29
|
+
# Default options values
|
|
30
|
+
@options = {
|
|
31
|
+
:chdir => Dir.pwd,
|
|
32
|
+
:environment => 'development',
|
|
33
|
+
:address => '0.0.0.0',
|
|
34
|
+
:port => Thin::Server::DEFAULT_PORT,
|
|
35
|
+
:timeout => Thin::Server::DEFAULT_TIMEOUT,
|
|
36
|
+
:log => 'log/thin.log',
|
|
37
|
+
:pid => 'tmp/pids/thin.pid',
|
|
38
|
+
:max_conns => Thin::Server::DEFAULT_MAXIMUM_CONNECTIONS,
|
|
39
|
+
:max_persistent_conns => Thin::Server::DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS,
|
|
40
|
+
:require => [],
|
|
41
|
+
:wait => Thin::Controllers::Cluster::DEFAULT_WAIT_TIME
|
|
42
|
+
}.merge(opts)
|
|
43
|
+
|
|
44
|
+
print_options = false
|
|
45
|
+
p = parser
|
|
46
|
+
p.separator ""
|
|
47
|
+
p.separator "Datamapper options:"
|
|
48
|
+
p.on("--dm-db URL", "Datamapper database [#{@options[:dm_db]}]") do |u| @options[:dm_db] = u end
|
|
49
|
+
p.on("--dm-log FILE", "Datamapper log file [#{@options[:dm_log]}]") do |n| @options[:dm_log] = n end
|
|
50
|
+
p.on("--dm-auto-upgrade", "Run Datamapper's auto upgrade") do |n| @options[:dm_auto_upgrade] = true end
|
|
51
|
+
p.separator ""
|
|
52
|
+
p.separator "Testing options:"
|
|
53
|
+
p.on("--test-load-am", "Load an AM configuration for testing") do |n| @options[:load_test_am] = true end
|
|
54
|
+
p.on("--disable-https", "Run server without SSL") do sopts = nil end
|
|
55
|
+
p.on("--print-options", "Print option settings after parsing command lines args") do print_options = true end
|
|
56
|
+
p.separator ""
|
|
57
|
+
p.separator "Common options:"
|
|
58
|
+
|
|
59
|
+
parse!
|
|
60
|
+
|
|
61
|
+
if sopts
|
|
62
|
+
@options[:ssl] = true
|
|
63
|
+
@options[:ssl_key_file] ||= sopts[:key_file]
|
|
64
|
+
@options[:ssl_cert_file] ||= sopts[:cert_file]
|
|
65
|
+
@options[:ssl_verify] ||= sopts[:verify_peer]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
if print_options
|
|
69
|
+
require 'pp'
|
|
70
|
+
pp @options
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
@@instance = self
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def init_data_mapper
|
|
77
|
+
|
|
78
|
+
# Configure the data store
|
|
79
|
+
#
|
|
80
|
+
#DataMapper::Logger.new(@options[:dm_log] || $stdout, :debug)
|
|
81
|
+
DataMapper::Logger.new($stdout, :info)
|
|
82
|
+
#DataMapper::Logger.new(STDOUT, :debug)
|
|
83
|
+
|
|
84
|
+
#DataMapper.setup(:default, config[:data_mapper] || {:adapter => 'yaml', :path => '/tmp/am_test2'})
|
|
85
|
+
DataMapper.setup(:default, @options[:dm_db])
|
|
86
|
+
|
|
87
|
+
require 'omf-sfa/resource'
|
|
88
|
+
DataMapper::Model.raise_on_save_failure = true
|
|
89
|
+
DataMapper.finalize
|
|
90
|
+
|
|
91
|
+
# require 'dm-migrations'
|
|
92
|
+
# DataMapper.auto_migrate!
|
|
93
|
+
|
|
94
|
+
DataMapper.auto_upgrade! if @options[:dm_auto_upgrade]
|
|
95
|
+
|
|
96
|
+
load_test_am if @options[:load_test_am]
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def run!
|
|
101
|
+
init_data_mapper
|
|
102
|
+
super
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
|
|
2
|
+
require 'omf_base/lobject'
|
|
3
|
+
require 'omf-sfa/resource'
|
|
4
|
+
require 'omf-sfa/resource/comp_group'
|
|
5
|
+
require 'omf-sfa/am/am_manager'
|
|
6
|
+
require 'omf-sfa/am/am_liaison'
|
|
7
|
+
require 'active_support/inflector'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
module OMF::SFA::AM
|
|
11
|
+
|
|
12
|
+
extend OMF::SFA::AM
|
|
13
|
+
|
|
14
|
+
# This class implements a default resource scheduler
|
|
15
|
+
#
|
|
16
|
+
class AMScheduler < OMF::Base::LObject
|
|
17
|
+
|
|
18
|
+
# Create a resource of specific type given its description in a hash. If the type
|
|
19
|
+
# or the resource is physical then we create a clone of itself and assign it to
|
|
20
|
+
# the user who asked for it (conceptually a physical resource even though it is exclusive,
|
|
21
|
+
# is never given to the user but instead we provide him a clone of the resource).
|
|
22
|
+
# If the type is a 'lease' then we normally create a lease object.
|
|
23
|
+
#
|
|
24
|
+
# @param [Hash] resource_descr contains the properties of the new resource
|
|
25
|
+
# @param [String] The type of the resource we want to create
|
|
26
|
+
# @param [Hash] oproperties is a hash with all the OProperty values of the new resource
|
|
27
|
+
# @param [Authorizer] Defines context for authorization decisions
|
|
28
|
+
# @return [OResource] Returns the created resource
|
|
29
|
+
#
|
|
30
|
+
def create_resource(resource_descr, type_to_create, oproperties, authorizer)
|
|
31
|
+
debug "create_resource: resource_descr:'#{resource_descr}' type_to_create:'#{type_to_create}' oproperties:'#{oproperties}' authorizer:'#{authorizer.inspect}'"
|
|
32
|
+
if type_to_create.eql?('node')
|
|
33
|
+
desc = resource_descr.dup
|
|
34
|
+
desc[:account] = get_nil_account()
|
|
35
|
+
|
|
36
|
+
type = type_to_create.camelize
|
|
37
|
+
|
|
38
|
+
base_resource = eval("OMF::SFA::Resource::#{type}").first(desc)
|
|
39
|
+
|
|
40
|
+
if base_resource.nil? || !base_resource.available
|
|
41
|
+
raise UnknownResourceException.new "Resource '#{desc.inspect}' is not available or doesn't exist"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# create a clone
|
|
45
|
+
vr = base_resource.clone
|
|
46
|
+
|
|
47
|
+
vr.account = authorizer.account
|
|
48
|
+
vr.provided_by = base_resource
|
|
49
|
+
vr.save
|
|
50
|
+
|
|
51
|
+
base_resource.provides << vr
|
|
52
|
+
base_resource.save
|
|
53
|
+
|
|
54
|
+
return vr
|
|
55
|
+
elsif type_to_create.eql?('OLease')
|
|
56
|
+
resource_descr[:resource_type] = type_to_create
|
|
57
|
+
lease = OMF::SFA::Resource::OLease.create(resource_descr)
|
|
58
|
+
lease.valid_from = oproperties[:valid_from]
|
|
59
|
+
lease.valid_until = oproperties[:valid_until]
|
|
60
|
+
#lease.status = :pending
|
|
61
|
+
raise UnavailableResourceException.new "Cannot create '#{resource_descr.inspect}'" unless lease.save
|
|
62
|
+
return lease
|
|
63
|
+
else
|
|
64
|
+
raise "Uknown type of resource '#{type_to_create}'. Expected one of 'Node' or 'OLease'"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Releases/destroys the given resource
|
|
69
|
+
#
|
|
70
|
+
# @param [OResource] The actual resource we want to destroy
|
|
71
|
+
# @param [Authorizer] Defines context for authorization decisions
|
|
72
|
+
# @return [Boolean] Returns true for success otherwise false
|
|
73
|
+
#
|
|
74
|
+
def release_resource(resource, authorizer)
|
|
75
|
+
debug "release_resource: resource-> '#{resource.to_json}'"
|
|
76
|
+
unless resource.is_a? OMF::SFA::Resource::OResource
|
|
77
|
+
raise "Expected OResource but got '#{resource.inspect}'"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
base = resource.provided_by
|
|
81
|
+
|
|
82
|
+
unless resource.leases.empty?
|
|
83
|
+
base.leases.each do |l|
|
|
84
|
+
if (l.id == resource.leases.first.id)
|
|
85
|
+
time = Time.now
|
|
86
|
+
if (l.valid_until <= time)
|
|
87
|
+
l.status = "past"
|
|
88
|
+
else
|
|
89
|
+
l.status = "cancelled"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
msg = resource.leases.first.component_leases.destroy!
|
|
94
|
+
raise "Failed to destroy component_leases" unless msg
|
|
95
|
+
end
|
|
96
|
+
resource = resource.destroy!
|
|
97
|
+
raise "Failed to destroy resource" unless resource
|
|
98
|
+
resource
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Accept or reject the reservation of the component
|
|
102
|
+
#
|
|
103
|
+
# @param [OLease] lease contains the corresponding reservation window
|
|
104
|
+
# @param [OComponent] component is the resource we want to reserve
|
|
105
|
+
# @return [Boolean] returns true or false depending on the outcome of the request
|
|
106
|
+
#
|
|
107
|
+
def lease_component(lease, component)
|
|
108
|
+
# TODO: Implement a basic FCFS for the competing leases of a component.
|
|
109
|
+
# Basic Component provides itself(clones) so many times as the accepted leases on it.
|
|
110
|
+
debug "lease_component: lease:'#{lease.name}' to component:'#{component.name}'"
|
|
111
|
+
|
|
112
|
+
base = component.provided_by
|
|
113
|
+
base.leases.each do |l|
|
|
114
|
+
if (lease.valid_from >= l.valid_until || lease.valid_until <= l.valid_from)
|
|
115
|
+
#all ok, do nothing
|
|
116
|
+
elsif (lease.valid_from <= l.valid_from && lease.valid_until > l.valid_from)#overlapping time
|
|
117
|
+
raise UnavailableResourceException.new "Cannot lease '#{component.name}', because it is unavailable for the requested time."
|
|
118
|
+
elsif (lease.valid_from >= l.valid_from && lease.valid_from <= l.valid_until)#overlapping time
|
|
119
|
+
raise UnavailableResourceException.new "Cannot lease '#{component.name}', because it is unavailable for the requested time."
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
lease.status = "accepted"
|
|
123
|
+
base.leases << lease
|
|
124
|
+
base.save
|
|
125
|
+
component.leases << lease
|
|
126
|
+
component.save
|
|
127
|
+
#@am_liaison.enable_lease(lease, component)
|
|
128
|
+
return true
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# It returns the default account, normally used for admin account.
|
|
132
|
+
#
|
|
133
|
+
# @return [OAccount] returns the default account object
|
|
134
|
+
#
|
|
135
|
+
def get_nil_account()
|
|
136
|
+
@nil_account
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def initialize()
|
|
140
|
+
@nil_account = OMF::SFA::Resource::OAccount.new(:name => '__default__', :valid_until => Time.now + 1E10)
|
|
141
|
+
@am_liaison = OMF::SFA::AM::AMLiaison.new
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
end # OMFManager
|
|
145
|
+
|
|
146
|
+
end # OMF::SFA::AM
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rack'
|
|
3
|
+
require 'rack/showexceptions'
|
|
4
|
+
require 'thin'
|
|
5
|
+
require 'dm-migrations'
|
|
6
|
+
require 'omf_base/lobject'
|
|
7
|
+
require 'omf_base/load_yaml'
|
|
8
|
+
|
|
9
|
+
require 'omf-sfa/am/am_runner'
|
|
10
|
+
require 'omf-sfa/am/am_manager'
|
|
11
|
+
require 'omf-sfa/am/am_scheduler'
|
|
12
|
+
require 'omf-sfa/am/am_liaison'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
module OMF::SFA::AM
|
|
16
|
+
|
|
17
|
+
class AMServer
|
|
18
|
+
# Don't use LObject as we haveb't initialized the logging system yet. Happens in 'init_logger'
|
|
19
|
+
include OMF::Base::Loggable
|
|
20
|
+
extend OMF::Base::Loggable
|
|
21
|
+
|
|
22
|
+
@@config = OMF::Base::YAML.load('omf-sfa-am', :path => [File.dirname(__FILE__) + '/../../../etc/omf-sfa'])[:omf_sfa_am]
|
|
23
|
+
@@rpc = @@config[:endpoints].select { |v| v[:type] == 'xmlrpc' }.first
|
|
24
|
+
|
|
25
|
+
def self.rpc_config
|
|
26
|
+
@@rpc
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def init_logger
|
|
30
|
+
OMF::Base::Loggable.init_log 'am_server', :searchPath => File.join(File.dirname(__FILE__), 'am_server')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def check_dependencies
|
|
34
|
+
raise "xmlsec1 is not installed!" unless system('which xmlsec1 > /dev/null 2>&1')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def load_trusted_cert_roots
|
|
38
|
+
|
|
39
|
+
trusted_roots = File.expand_path(@@rpc[:trusted_roots])
|
|
40
|
+
certs = Dir.entries(trusted_roots)
|
|
41
|
+
certs.delete("..")
|
|
42
|
+
certs.delete(".")
|
|
43
|
+
certs.each do |fn|
|
|
44
|
+
fne = File.join(trusted_roots, fn)
|
|
45
|
+
if File.readable?(fne)
|
|
46
|
+
begin
|
|
47
|
+
trusted_cert = OpenSSL::X509::Certificate.new(File.read(fne))
|
|
48
|
+
OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE.add_cert(trusted_cert)
|
|
49
|
+
rescue OpenSSL::X509::StoreError => e
|
|
50
|
+
if e.message == "cert already in hash table"
|
|
51
|
+
warn "X509 cert '#{fne}' already registered in X509 store"
|
|
52
|
+
else
|
|
53
|
+
raise e
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
warn "Can't find trusted root cert '#{trusted_roots}/#{fne}'"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def init_data_mapper(options)
|
|
63
|
+
#@logger = OMF::Base::Loggable::_logger('am_server')
|
|
64
|
+
#OMF::Base::Loggable.debug "options: #{options}"
|
|
65
|
+
debug "options: #{options}"
|
|
66
|
+
|
|
67
|
+
# Configure the data store
|
|
68
|
+
#
|
|
69
|
+
DataMapper::Logger.new(options[:dm_log] || $stdout, :info)
|
|
70
|
+
#DataMapper::Logger.new($stdout, :info)
|
|
71
|
+
|
|
72
|
+
#DataMapper.setup(:default, config[:data_mapper] || {:adapter => 'yaml', :path => '/tmp/am_test2'})
|
|
73
|
+
DataMapper.setup(:default, options[:dm_db])
|
|
74
|
+
|
|
75
|
+
require 'omf-sfa/resource'
|
|
76
|
+
DataMapper::Model.raise_on_save_failure = true
|
|
77
|
+
DataMapper.finalize
|
|
78
|
+
|
|
79
|
+
# require 'dm-migrations'
|
|
80
|
+
# DataMapper.auto_migrate!
|
|
81
|
+
|
|
82
|
+
DataMapper.auto_upgrade! if options[:dm_auto_upgrade]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def load_test_am(options)
|
|
87
|
+
require 'dm-migrations'
|
|
88
|
+
DataMapper.auto_migrate!
|
|
89
|
+
|
|
90
|
+
am = options[:am][:manager]
|
|
91
|
+
if am.is_a? Proc
|
|
92
|
+
am = am.call
|
|
93
|
+
options[:am][:manager] = am
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
require 'omf-sfa/resource/oaccount'
|
|
97
|
+
#account = am.find_or_create_account(:name => 'foo')
|
|
98
|
+
account = OMF::SFA::Resource::OAccount.new(:name => 'foo')
|
|
99
|
+
|
|
100
|
+
require 'omf-sfa/resource/link'
|
|
101
|
+
require 'omf-sfa/resource/node'
|
|
102
|
+
require 'omf-sfa/resource/interface'
|
|
103
|
+
# nodes = {}
|
|
104
|
+
# 3.times do |i|
|
|
105
|
+
# name = "n#{i}"
|
|
106
|
+
# nodes[name] = n = OMF::SFA::Resource::Node.create(:name => name)
|
|
107
|
+
# am.manage_resource(n)
|
|
108
|
+
# end
|
|
109
|
+
|
|
110
|
+
r = []
|
|
111
|
+
r << l = OMF::SFA::Resource::Link.create(:name => 'l')
|
|
112
|
+
r << OMF::SFA::Resource::Channel.create(:number => 1, :frequency => "2.412GHZ")
|
|
113
|
+
lease = OMF::SFA::Resource::OLease.create(:name => 'l1', :valid_from => Time.now, :valid_until => Time.now + 3600)
|
|
114
|
+
2.times do |i|
|
|
115
|
+
r << n = OMF::SFA::Resource::Node.create(:name => "node#{i}")
|
|
116
|
+
ifr = OMF::SFA::Resource::Interface.create(name: "node#{i}:if0", node: n, channel: l)
|
|
117
|
+
ip = OMF::SFA::Resource::Ip.create(address: "10.0.1.#{i}", netmask: "255.255.255.0", ip_type: "ipv4", interface: ifr)
|
|
118
|
+
n.interfaces << ifr
|
|
119
|
+
l.interfaces << ifr
|
|
120
|
+
n.leases << lease
|
|
121
|
+
end
|
|
122
|
+
r.last.leases << OMF::SFA::Resource::OLease.create(:name => 'l2', :valid_from => Time.now + 3600, :valid_until => Time.now + 7200)
|
|
123
|
+
|
|
124
|
+
am.manage_resources(r)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def init_am_manager(opts = {})
|
|
128
|
+
@am_manager = OMF::SFA::AM::AMManager.new(OMF::SFA::AM::AMScheduler.new)
|
|
129
|
+
(opts[:am] ||= {})[:manager] = @am_manager
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def run(opts)
|
|
133
|
+
@am_manager = nil
|
|
134
|
+
|
|
135
|
+
# alice = OpenSSL::X509::Certificate.new(File.read('/Users/max/.gcf/alice-cert.pem'))
|
|
136
|
+
# puts "ALICE::: #{OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE.verify(alice)}"
|
|
137
|
+
opts[:handlers] = {
|
|
138
|
+
# Should be done in a better way
|
|
139
|
+
:pre_rackup => lambda {
|
|
140
|
+
},
|
|
141
|
+
:pre_parse => lambda do |p, options|
|
|
142
|
+
p.on("--test-load-am", "Load an AM configuration for testing") do |n| options[:load_test_am] = true end
|
|
143
|
+
p.separator ""
|
|
144
|
+
p.separator "Datamapper options:"
|
|
145
|
+
p.on("--dm-db URL", "Datamapper database [#{options[:dm_db]}]") do |u| options[:dm_db] = u end
|
|
146
|
+
p.on("--dm-log FILE", "Datamapper log file [#{options[:dm_log]}]") do |n| options[:dm_log] = n end
|
|
147
|
+
p.on("--dm-auto-upgrade", "Run Datamapper's auto upgrade") do |n| options[:dm_auto_upgrade] = true end
|
|
148
|
+
p.separator ""
|
|
149
|
+
end,
|
|
150
|
+
:pre_run => lambda do |opts|
|
|
151
|
+
puts "OPTS: #{opts.inspect}"
|
|
152
|
+
init_logger()
|
|
153
|
+
check_dependencies()
|
|
154
|
+
load_trusted_cert_roots()
|
|
155
|
+
init_data_mapper(opts)
|
|
156
|
+
init_am_manager(opts)
|
|
157
|
+
load_test_am(opts) if opts[:load_test_am]
|
|
158
|
+
end
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
#Thin::Logging.debug = true
|
|
163
|
+
require 'omf_base/thin/runner'
|
|
164
|
+
OMF::Base::Thin::Runner.new(ARGV, opts).run!
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
end # class
|
|
168
|
+
end # module
|
|
169
|
+
|
|
170
|
+
# Configure the web server
|
|
171
|
+
#
|
|
172
|
+
rpc = OMF::SFA::AM::AMServer.rpc_config()
|
|
173
|
+
opts = {
|
|
174
|
+
:app_name => 'am_server',
|
|
175
|
+
:port => 8001,
|
|
176
|
+
:am => {
|
|
177
|
+
#:manager => lambda { OMF::SFA::AM::AMManager.new(OMF::SFA::AM::AMScheduler.new) },
|
|
178
|
+
:liaison => OMF::SFA::AM::AMLiaison.new
|
|
179
|
+
},
|
|
180
|
+
:ssl => {
|
|
181
|
+
:cert_file => File.expand_path(rpc[:ssl][:cert_chain_file]),
|
|
182
|
+
:key_file => File.expand_path(rpc[:ssl][:private_key_file]),
|
|
183
|
+
:verify_peer => true
|
|
184
|
+
#:verify_peer => false
|
|
185
|
+
},
|
|
186
|
+
#:log => '/tmp/am_server.log',
|
|
187
|
+
:dm_db => 'sqlite:///tmp/am_test.db',
|
|
188
|
+
:dm_log => '/tmp/am_server-dm.log',
|
|
189
|
+
:rackup => File.dirname(__FILE__) + '/config.ru',
|
|
190
|
+
}
|
|
191
|
+
OMF::SFA::AM::AMServer.new.run(opts)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
#RPC_URL = '/rpc'
|
|
4
|
+
RPC_URL = '/RPC2'
|
|
5
|
+
|
|
6
|
+
REQUIRE_LOGIN = false
|
|
7
|
+
|
|
8
|
+
require 'rack/file'
|
|
9
|
+
class MyFile < Rack::File
|
|
10
|
+
def call(env)
|
|
11
|
+
c, h, b = super
|
|
12
|
+
#h['Access-Control-Allow-Origin'] = '*'
|
|
13
|
+
[c, h, b]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# There seem to be some issues with teh sfi.py tool
|
|
19
|
+
#use Rack::Lint
|
|
20
|
+
|
|
21
|
+
#am_mgr = opts[:am][:manager]
|
|
22
|
+
#sleep 10
|
|
23
|
+
opts = OMF::Base::Thin::Runner.instance.options
|
|
24
|
+
#puts self.methods.sort.inspect
|
|
25
|
+
am_mgr = opts[:am][:manager]
|
|
26
|
+
if am_mgr.is_a? Proc
|
|
27
|
+
am_mgr = am_mgr.call()
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
require 'omf-sfa/am/am-rest/session_authenticator'
|
|
31
|
+
use OMF::SFA::AM::Rest::SessionAuthenticator, #:expire_after => 10,
|
|
32
|
+
:login_url => (REQUIRE_LOGIN ? '/login' : nil),
|
|
33
|
+
:no_session => ['^/$', "^#{RPC_URL}", '^/login', '^/logout', '^/readme', '^/assets']
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
map RPC_URL do
|
|
37
|
+
require 'omf-sfa/am/am-rpc/am_rpc_service'
|
|
38
|
+
service = OMF::SFA::AM::RPC::AMService.new({:manager => am_mgr, :liaison => opts[:am][:liaison]})
|
|
39
|
+
|
|
40
|
+
app = lambda do |env|
|
|
41
|
+
[404, {"Content-Type" => "text/plain"}, ["Not found"]]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
run Rack::RPC::Endpoint.new(app, service, :path => '')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
map '/slices' do
|
|
48
|
+
require 'omf-sfa/am/am-rest/account_handler'
|
|
49
|
+
run OMF::SFA::AM::Rest::AccountHandler.new(opts[:am][:manager], opts)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
map "/resources" do
|
|
54
|
+
require 'omf-sfa/am/am-rest/resource_handler'
|
|
55
|
+
# account = opts[:am_mgr].get_default_account() # TODO: Is this still needed?
|
|
56
|
+
# run OMF::SFA::AM::Rest::ResourceHandler.new(opts[:am][:manager], opts.merge({:account => account}))
|
|
57
|
+
run OMF::SFA::AM::Rest::ResourceHandler.new(opts[:am][:manager], opts)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
if REQUIRE_LOGIN
|
|
61
|
+
map '/login' do
|
|
62
|
+
require 'omf-sfa/am/am-rest/login_handler'
|
|
63
|
+
run OMF::SFA::AM::Rest::LoginHandler.new(opts[:am][:manager], opts)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
map "/readme" do
|
|
68
|
+
require 'bluecloth'
|
|
69
|
+
s = File::read(File.dirname(__FILE__) + '/am-rest/REST_API.md')
|
|
70
|
+
frag = BlueCloth.new(s).to_html
|
|
71
|
+
wrapper = %{
|
|
72
|
+
<html>
|
|
73
|
+
<head>
|
|
74
|
+
<title>AM REST API</title>
|
|
75
|
+
<link href="/assets/css/default.css" media="screen" rel="stylesheet" type="text/css">
|
|
76
|
+
<style type="text/css">
|
|
77
|
+
circle.node {
|
|
78
|
+
stroke: #fff;
|
|
79
|
+
stroke-width: 1.5px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
line.link {
|
|
83
|
+
stroke: #999;
|
|
84
|
+
stroke-opacity: .6;
|
|
85
|
+
stroke-width: 2px;
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
</style>
|
|
89
|
+
</head>
|
|
90
|
+
<body>
|
|
91
|
+
%s
|
|
92
|
+
</body>
|
|
93
|
+
</html>
|
|
94
|
+
}
|
|
95
|
+
p = lambda do |env|
|
|
96
|
+
puts "#{env.inspect}"
|
|
97
|
+
|
|
98
|
+
return [200, {"Content-Type" => "text/html"}, [wrapper % frag]]
|
|
99
|
+
end
|
|
100
|
+
run p
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
map '/assets' do
|
|
104
|
+
run MyFile.new(File.dirname(__FILE__) + '/../../../../share/assets')
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
map "/" do
|
|
108
|
+
handler = Proc.new do |env|
|
|
109
|
+
req = ::Rack::Request.new(env)
|
|
110
|
+
case req.path_info
|
|
111
|
+
when '/'
|
|
112
|
+
[301, {'Location' => '/readme', "Content-Type" => ""}, ['Next window!']]
|
|
113
|
+
when '/favicon.ico'
|
|
114
|
+
[301, {'Location' => '/assets/image/favicon.ico', "Content-Type" => ""}, ['Next window!']]
|
|
115
|
+
else
|
|
116
|
+
OMF::Base::Loggable.logger('rack').warn "Can't handle request '#{req.path_info}'"
|
|
117
|
+
[401, {"Content-Type" => ""}, "Sorry!"]
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
run handler
|
|
121
|
+
end
|
|
122
|
+
|