antfarm-core 0.5.0.beta1

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.
@@ -0,0 +1,151 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ module Antfarm
33
+ module Model
34
+ class LayerThreeNetwork
35
+ include DataMapper::Resource
36
+
37
+ storage_names[:default] = 'layer_three_networks'
38
+
39
+ property :id, Serial
40
+ property :certainty_factor, Float, :required => true, :default => 0.8
41
+ property :protocol, String
42
+ property :custom, String
43
+
44
+ has n, :layer_three_interfaces, :constraint => :destroy
45
+ has 1, :ip_network, :constraint => :destroy
46
+
47
+ validates_present :certainty_factor
48
+
49
+ before :save, :clamp_certainty_factor
50
+
51
+ # Take the given network and merge with it
52
+ # any sub_networks of the given network.
53
+ def self.merge(network, merge_certainty_factor = Antfarm::CF_PROVEN_TRUE)
54
+ unless network
55
+ raise(ArgumentError, 'nil argument supplied to LayerThreeNetwork#merge', caller)
56
+ end
57
+
58
+ unless network.is_a?(Antfarm::Model::LayerThreeNetwork)
59
+ raise(ArgumentError, 'argument supplied to LayerThreeNetwork#merge must be LayerThreeNetwork', caller)
60
+ end
61
+
62
+ for sub_network in self.networks_contained_within(network.ip_network.address)
63
+ unless sub_network == network
64
+ unless merge_certainty_factor
65
+ merge_certainty_factor = Antfarm::CF_LACK_OF_PROOF
66
+ end
67
+
68
+ merge_certainty_factor = Antfarm::Helpers.clamp(merge_certainty_factor)
69
+
70
+ sub_network.layer_three_interfaces.each { |interface| network.layer_three_interfaces << interface }
71
+ network.layer_three_interfaces.uniq!
72
+
73
+ # Clear out the layer 3 interfaces on the network to
74
+ # be destroyed such that they aren't destroyed too.
75
+ sub_network.layer_three_interfaces.clear
76
+
77
+ # TODO: update network's certainty factor using sub_network's certainty factor.
78
+
79
+ network.save
80
+
81
+ # Because of :constraint => :destroy above, calling destroy
82
+ # here will also cause destroy to be called on ip_network.
83
+ # Calling destroy here should NOT destroy any layer 3 interface
84
+ # since they were all moved over to the network being merged to.
85
+ sub_network.destroy
86
+ end
87
+ end
88
+ end
89
+
90
+ # Find the Layer3Network with the given address.
91
+ def self.network_addressed(ip_net_str)
92
+ unless ip_net_str
93
+ raise(ArgumentError, 'nil argument supplied to LayerThreeNetwork#network_addressed', caller)
94
+ end
95
+
96
+ # Calling network_containing here because if a network already exists that encompasses
97
+ # the given network, we want to automatically use that network instead.
98
+ # TODO: figure out how to use alias with class methods
99
+ self.network_containing(ip_net_str)
100
+ end
101
+
102
+ # Find the network the given network is a sub_network of, if one exists.
103
+ def self.network_containing(ip_net_str)
104
+ unless ip_net_str
105
+ raise(ArgumentError, 'nil argument supplied to LayerThreeNetwork#network_containing', caller)
106
+ end
107
+
108
+ # Don't want to require a Layer3Network to be passed in case
109
+ # a check is being performed before a Layer3Network is created.
110
+ network = Antfarm::IPAddrExt.new(ip_net_str)
111
+
112
+ ip_nets = IpNetwork.all
113
+ for ip_net in ip_nets
114
+ if Antfarm::IPAddrExt.new(ip_net.address).network_in_network?(network)
115
+ return ip_net.layer_three_network
116
+ end
117
+ end
118
+
119
+ return nil
120
+ end
121
+
122
+ # Find any Layer3Networks that are sub_networks of the given network.
123
+ def self.networks_contained_within(ip_net_str)
124
+ unless ip_net_str
125
+ raise(ArgumentError, 'nil argument supplied to LayerThreeNetwork#networks_contained_within', caller)
126
+ end
127
+
128
+ # Don't want to require a Layer3Network to be passed in case
129
+ # a check is being performed before a Layer3Network is created.
130
+ network = Antfarm::IPAddrExt.new(ip_net_str)
131
+ sub_networks = Array.new
132
+
133
+ ip_nets = IpNetwork.all
134
+ for ip_net in ip_nets
135
+ sub_networks << ip_net.layer_three_network if network.network_in_network?(ip_net.address)
136
+ end
137
+
138
+ return sub_networks
139
+ end
140
+
141
+ #######
142
+ private
143
+ #######
144
+
145
+ def clamp_certainty_factor
146
+ Antfarm::Helpers.log :debug, '[PRIVATE METHOD CALLED] LayerThreeNetwork#clamp_certainty_factor'
147
+ self.certainty_factor = Antfarm::Helpers.clamp(self.certainty_factor)
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,96 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ module Antfarm
33
+ module Model
34
+ class LayerTwoInterface
35
+ include DataMapper::Resource
36
+
37
+ storage_names[:default] = 'layer_two_interfaces'
38
+
39
+ property :id, Serial
40
+ property :certainty_factor, Float, :required => true, :default => 0.8
41
+ property :media_type, String
42
+ property :custom, String
43
+
44
+ # has n, :layer3_interfaces
45
+ # has 1, :ethernet_interface, :child_key => :id, :constraint => :destroy
46
+ has 1, :ethernet_interface, :constraint => :destroy
47
+ belongs_to :node, :required => true
48
+
49
+ validates_present :certainty_factor
50
+
51
+ # Need to do this before validation
52
+ # since :required => true is specified
53
+ # on the node association above.
54
+ before :valid?, :create_node
55
+ before :save, :clamp_certainty_factor
56
+ # after :save, :destroy_orphaned_nodes # TODO: be sure to write test if used!
57
+
58
+ #######
59
+ private
60
+ #######
61
+
62
+ # If a hash is passed into the node variable,
63
+ # parameters matching variables on the node
64
+ # class will be used to create a new node object.
65
+ def create_node
66
+ Antfarm::Helpers.log :debug, '[PRIVATE METHOD CALLED] Layer2Interface#create_node'
67
+
68
+ # Only create a new node if a node model
69
+ # isn't already associated with this model.
70
+ # This protects against new nodes being
71
+ # created when one is already provided or
72
+ # when this model is being saved rather
73
+ # than created (since a node will be
74
+ # automatically created and associated with
75
+ # this model on creation).
76
+ self.node ||= Antfarm::Model::Node.create
77
+ end
78
+
79
+ def clamp_certainty_factor
80
+ Antfarm::Helpers.log :debug, '[PRIVATE METHOD CALLED] LayerTwoInterface#clamp_certainty_factor'
81
+ self.certainty_factor = Antfarm::Helpers.clamp(self.certainty_factor)
82
+ end
83
+
84
+ def destroy_orphaned_nodes
85
+ Antfarm::Helpers.log :debug, '[PRIVATE METHOD CALLED] LayerTwoInterface#destroy_orphaned_nodes'
86
+
87
+ Node.all.each do |n|
88
+ if n.layer2_interfaces.empty?
89
+ Antfarm::Helpers.log :debug, "LayerTwoInterface - destroying orphaned node #{node}"
90
+ n.destroy
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,61 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ module Antfarm
33
+ module Model
34
+ class Node
35
+ include DataMapper::Resource
36
+
37
+ storage_names[:default] = 'nodes'
38
+
39
+ property :id, Serial
40
+ property :certainty_factor, Float, :required => true, :default => 0.8
41
+ property :name, String
42
+ property :device_type, String
43
+ property :custom, String
44
+
45
+ has n, :layer_two_interfaces, :constraint => :destroy
46
+
47
+ validates_present :certainty_factor
48
+
49
+ before :save, :clamp_certainty_factor
50
+
51
+ #######
52
+ private
53
+ #######
54
+
55
+ def clamp_certainty_factor
56
+ Antfarm::Helpers.log :debug, '[PRIVATE METHOD CALLED] Node#clamp_certainty_factor'
57
+ self.certainty_factor = Antfarm::Helpers.clamp(self.certainty_factor)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,177 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ require 'find'
33
+
34
+ module Antfarm
35
+ class PluginExistanceError < Antfarm::AntfarmError; end
36
+ class PluginInheritanceError < Antfarm::AntfarmError; end
37
+ class PluginOptionsError < Antfarm::AntfarmError; end
38
+
39
+ module Plugin
40
+ attr_accessor :name
41
+
42
+ PLUGIN_ROOTS = ["#{File.dirname(__FILE__)}/plugins"]
43
+ PLUGIN_ROOTS << Antfarm::Helpers.user_plugins_dir
44
+
45
+ # perform a quick discovery of plugins that exist
46
+ # TODO <scrapcoder>: add 'custom/' to the front of
47
+ # plugins that don't originate in the 'root plugins'
48
+ # directory.
49
+ def self.discover
50
+ PLUGIN_ROOTS.each do |root|
51
+ Find.find("#{root}/") do |path|
52
+ unless File.directory?(path)
53
+ if File.file?(path) && path =~ /rb$/
54
+ path.sub! /.rb/, ''
55
+ yield path.sub /^.*#{root}\//, ''
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ def self.load(plugin = nil)
63
+ if plugin.nil? # load them all!
64
+ plugins = Hash.new
65
+
66
+ PLUGIN_ROOTS.each do |root|
67
+ # dive into the root directory to look for plugins
68
+ Find.find("#{root}/") do |path|
69
+ # don't operate on directories directly
70
+ unless File.directory?(path)
71
+ # only proceed if the file looks like a ruby file
72
+ if path =~ /rb$/ and File.file?(path)
73
+ instance = self.load_single_plugin(path, root)
74
+ plugins[instance.name] = instance unless instance.nil?
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ return plugins
81
+ else
82
+ begin
83
+ found = false
84
+
85
+ PLUGIN_ROOTS.each do |root|
86
+ path = "#{root}/#{plugin}.rb"
87
+
88
+ if File.file?(path)
89
+ instance = self.load_single_plugin(path, root)
90
+ return instance unless instance.nil?
91
+ end
92
+ end
93
+
94
+ # If we get here, a plugin was never
95
+ # loaded and returned.
96
+ raise Antfarm::PluginExistanceError, message
97
+ rescue Exception => e
98
+ raise Antfarm::AntfarmError, e.message
99
+ end
100
+ end
101
+ end
102
+
103
+ # TODO <scrapcoder>: check to see if module is already defined.
104
+ # If so, raise an error, passing the name of the created plugin
105
+ # object so a note can be presented to the user with the name/author
106
+ # of the plugin already created.
107
+ def self.load_single_plugin(path, root)
108
+ begin
109
+ # remove .rb from the end of the path
110
+ path.sub! /.rb/, ''
111
+ # the name of the plugin is the full file name (directories included)
112
+ # without everything up to and including the 'root plugins' directory
113
+ #
114
+ # NOTE at this point name now == plugin variable passed to 'load()'
115
+ name = path.sub /^.*#{root}\//, ''
116
+ require path.untaint
117
+ # capitalize each of the directory names since they signify modules
118
+ # remove underscore and capitalize first letter after underscore/hyphen
119
+ # taken from ActiveSupport's Inflector#camelize method
120
+ camelized_name = name.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_|-)(.)/) { $2.upcase }
121
+ # create class object for plugin
122
+ plugin_class = eval("Antfarm::Plugin::#{camelized_name}")
123
+ # make sure plugin inherits from this class
124
+ unless plugin_class < self
125
+ raise Antfarm::PluginInheritanceError, "#{name} does not inherit from Antfarm::Plugin - this plugin will be unavailable"
126
+ return nil
127
+ end
128
+ # create a new plugin object
129
+ plugin = plugin_class.new
130
+ # tell the plugin what its name is
131
+ plugin.name = name
132
+ # return the plugin
133
+ return plugin
134
+ rescue LoadError
135
+ raise Antfarm::AntfarmError, "An error occurred while trying to load #{name} - this plugin will be unavailable"
136
+ return nil
137
+ rescue Exception => ex
138
+ Antfarm::Helpers.log :error, ex.message
139
+ raise Antfarm::AntfarmError, "An error occurred while initializing #{name} - this plugin will be unavailable"
140
+ return nil
141
+ end
142
+ end
143
+
144
+ ALLOWED_INFO = [:name, :author, :desc ]
145
+ ALLOWED_OPTIONS = [:name, :desc, :long, :short, :type, :default, :required]
146
+
147
+ attr_reader :info
148
+ attr_reader :options
149
+
150
+ def initialize(info = nil, options = nil)
151
+ @info = info
152
+ @options = [options].flatten
153
+
154
+ if @info
155
+ @info.reject! { |k,v| !ALLOWED_INFO.include?(k) }
156
+ end
157
+
158
+ if @options
159
+ for option in @options
160
+ raise Antfarm::PluginOptionsError, 'Each option must specify a name' unless option[:name]
161
+ raise Antfarm::PluginOptionsError, 'Each option must specify a description' unless option[:desc]
162
+ option.reject! { |k,v| !ALLOWED_OPTIONS.include?(k) }
163
+ option[:type] = :flag unless option.key?(:type)
164
+ option[:default] = false if option[:type] == :flag
165
+ end
166
+ end
167
+ end
168
+
169
+ def print_message(message)
170
+ Antfarm::Helpers.output "Message: #{message}"
171
+ end
172
+
173
+ def print_error(message)
174
+ Antfarm::Helpers.output "Error: #{message}"
175
+ end
176
+ end
177
+ end