fog_tracker 0.1.3 → 0.1.4
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 +1 -0
- data/.yardopts +1 -0
- data/Guardfile +4 -2
- data/fog_tracker.gemspec +2 -2
- data/lib/fog/core/model.rb +21 -0
- data/lib/fog_tracker/account_tracker.rb +26 -26
- data/lib/fog_tracker/{resource_tracker.rb → collection_tracker.rb} +12 -12
- data/lib/fog_tracker/query/query_processor.rb +13 -15
- data/lib/fog_tracker/tracker.rb +26 -27
- data/lib/fog_tracker/version.rb +1 -1
- data/lib/fog_tracker.rb +1 -1
- data/spec/lib/fog_tracker/account_tracker_spec.rb +33 -27
- data/spec/lib/fog_tracker/query/query_processor_spec.rb +23 -12
- data/spec/lib/fog_tracker/resource_tracker_spec.rb +6 -7
- data/spec/support/_mocks.rb +4 -49
- metadata +25 -23
- data/lib/fog_tracker/model.rb +0 -20
data/.gitignore
CHANGED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--no-private --protected lib/**/*.rb
|
data/Guardfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# A sample Guardfile
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
3
|
|
4
|
-
guard '
|
5
|
-
watch(%r{
|
4
|
+
guard 'rspec', :version => 2, :cli => "--color --format documentation" do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
6
8
|
end
|
data/fog_tracker.gemspec
CHANGED
@@ -27,8 +27,8 @@ Gem::Specification.new do |s|
|
|
27
27
|
# Development / Test dependencies
|
28
28
|
s.add_development_dependency "rake"
|
29
29
|
s.add_development_dependency "rspec"
|
30
|
-
s.add_development_dependency "
|
30
|
+
s.add_development_dependency "yard"
|
31
31
|
s.add_development_dependency "guard"
|
32
|
-
s.add_development_dependency "guard-
|
32
|
+
s.add_development_dependency "guard-rspec"
|
33
33
|
s.add_development_dependency "ruby_gntp"
|
34
34
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Fog
|
2
|
+
|
3
|
+
# Adds an accessor and a method to decorate Fog::Model instances
|
4
|
+
# with tracker account information
|
5
|
+
class Model
|
6
|
+
|
7
|
+
# a FogTracker::CollectionTracker
|
8
|
+
attr_accessor :_fog_collection_tracker
|
9
|
+
|
10
|
+
# Returns a cleaned copy of the resource's account information
|
11
|
+
# from the its collection tracker (credentials are removed).
|
12
|
+
def tracker_account
|
13
|
+
if _fog_collection_tracker
|
14
|
+
_fog_collection_tracker.clean_account_data
|
15
|
+
else
|
16
|
+
Hash.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -4,25 +4,24 @@ module FogTracker
|
|
4
4
|
class AccountTracker
|
5
5
|
require 'fog'
|
6
6
|
|
7
|
-
|
8
|
-
attr_reader :
|
7
|
+
# The name (String) of the account this tracker is polling
|
8
|
+
attr_reader :name
|
9
|
+
# A Hash of account-specific configuration data
|
10
|
+
attr_reader :account
|
11
|
+
# A Logger-compatible object
|
12
|
+
attr_reader :log
|
13
|
+
# How long to wait between successive polling of this account (Integer)
|
14
|
+
attr_reader :delay
|
9
15
|
|
10
16
|
# Creates an object for tracking all collections in a single Fog account
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
# * +:delay+ - Default time between polling of accounts
|
21
|
-
# * +:callback+ - A Method or Proc to call each time an account is polled.
|
22
|
-
# It should take the name of the account as its only required parameter
|
23
|
-
# * +:error_callback+ - A Proc to call if polling errors occur.
|
24
|
-
# It should take a single Exception as its only required parameter
|
25
|
-
# * +:logger+ - a Ruby Logger-compatible object
|
17
|
+
# @param [String] account_name a human-readable name for the account
|
18
|
+
# @param [Hash] options optional additional parameters:
|
19
|
+
# - :delay (Integer) - Default time between polling of accounts
|
20
|
+
# - :callback (Proc) - A Method or Proc to call each time an account is polled.
|
21
|
+
# (should take the name of the account as its only required parameter)
|
22
|
+
# - :error_callback (Proc) - A Method or Proc to call if polling errors occur.
|
23
|
+
# (should take a single Exception as its only required parameter)
|
24
|
+
# - :logger - a Ruby Logger-compatible object
|
26
25
|
def initialize(account_name, account, options={})
|
27
26
|
@name = account_name
|
28
27
|
@account = account
|
@@ -32,10 +31,11 @@ module FogTracker
|
|
32
31
|
FogTracker::DEFAULT_POLLING_TIME
|
33
32
|
@error_proc = options[:error_callback]
|
34
33
|
@log.debug "Creating tracker for account #{@name}."
|
35
|
-
|
34
|
+
create_collection_trackers
|
36
35
|
end
|
37
36
|
|
38
|
-
# Starts a background thread, which
|
37
|
+
# Starts a background thread, which periodically polls for all the
|
38
|
+
# resource collections for this tracker's account
|
39
39
|
def start
|
40
40
|
if not running?
|
41
41
|
@log.debug "Starting tracking for account #{@name}..."
|
@@ -43,7 +43,7 @@ module FogTracker
|
|
43
43
|
begin
|
44
44
|
while true do
|
45
45
|
@log.info "Polling account #{@name}..."
|
46
|
-
@
|
46
|
+
@collection_trackers.each {|tracker| tracker.update}
|
47
47
|
@callback.call(all_resources) if @callback
|
48
48
|
sleep @delay
|
49
49
|
end
|
@@ -60,7 +60,7 @@ module FogTracker
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
# Stops
|
63
|
+
# Stops polling this tracker's account
|
64
64
|
def stop
|
65
65
|
if running?
|
66
66
|
@log.info "Stopping tracker for #{name}..."
|
@@ -89,18 +89,18 @@ module FogTracker
|
|
89
89
|
|
90
90
|
# Returns an Array of all this Account's currently tracked Resources
|
91
91
|
def all_resources
|
92
|
-
(@
|
92
|
+
(@collection_trackers.collect do |tracker|
|
93
93
|
tracker.collection
|
94
94
|
end).flatten
|
95
95
|
end
|
96
96
|
|
97
97
|
private
|
98
98
|
|
99
|
-
# Creates and returns an Array of
|
99
|
+
# Creates and returns an Array of CollectionTracker objects -
|
100
100
|
# one for each resource type associated with this account's service
|
101
|
-
def
|
102
|
-
@
|
103
|
-
FogTracker::
|
101
|
+
def create_collection_trackers
|
102
|
+
@collection_trackers = tracked_types.map do |fog_collection_name|
|
103
|
+
FogTracker::CollectionTracker.new(fog_collection_name.to_s, self)
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module FogTracker
|
2
2
|
|
3
|
-
# Tracks a single Fog collection in a single account
|
4
|
-
|
3
|
+
# Tracks a single Fog collection in a single account.
|
4
|
+
# Each {CollectionTracker} instance is tightly bound to an {AccountTracker}.
|
5
|
+
class CollectionTracker
|
5
6
|
|
7
|
+
# An Array of Fog::Model objects, all of the same resource type (class)
|
6
8
|
attr_accessor :collection
|
7
9
|
|
8
10
|
# Creates an object for tracking a single Fog collection in a single account
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# * +resource_type+ - the Fog collection name (String) for this resource type
|
13
|
-
# * +account_tracker+ - the AccountTracker for this tracker's @collection
|
11
|
+
# @param [String] resource_type the Fog collection name for this resource type
|
12
|
+
# @param [AccountTracker] account_tracker the AccountTracker for this tracker's
|
13
|
+
# account. Usually the AccountTracker that created this object
|
14
14
|
def initialize(resource_type, account_tracker)
|
15
15
|
@type = resource_type
|
16
16
|
@account_tracker = account_tracker
|
@@ -21,8 +21,8 @@ module FogTracker
|
|
21
21
|
@log.debug "Created tracker for #{@type} on #{@account_name}."
|
22
22
|
end
|
23
23
|
|
24
|
-
# Polls the
|
25
|
-
# instances of
|
24
|
+
# Polls the {AccountTracker}'s connection for updated info on all existing
|
25
|
+
# instances of this tracker's resource_type
|
26
26
|
def update
|
27
27
|
@log.info "Polling #{@type} on #{@account_name}..."
|
28
28
|
fog_collection = @account_tracker.connection.send(@type) || Array.new
|
@@ -31,15 +31,15 @@ module FogTracker
|
|
31
31
|
# Here's where most of the network overhead is actually incurred
|
32
32
|
fog_collection.each do |resource|
|
33
33
|
@log.debug "Fetching resource: #{resource.class} #{resource.identity}"
|
34
|
-
resource.
|
34
|
+
resource._fog_collection_tracker = self
|
35
35
|
new_collection << resource
|
36
36
|
@log.debug "Got resource: #{resource.inspect}"
|
37
37
|
end
|
38
38
|
@collection = new_collection
|
39
39
|
end
|
40
40
|
|
41
|
-
#
|
42
|
-
#
|
41
|
+
# @return [Hash] a Hash of account information, slighly modified:
|
42
|
+
# a :name parameter is added, and the :credentials are removed
|
43
43
|
def clean_account_data
|
44
44
|
@clean_data ||= @account # generate this data only once per res
|
45
45
|
@clean_data[:name] = @account_name
|
@@ -1,25 +1,25 @@
|
|
1
1
|
module FogTracker
|
2
2
|
module Query
|
3
|
+
# A class for gathering all Fog resources for a set of {AccountTracker}s,
|
4
|
+
# and filtering them based on a regular-expression-based query
|
3
5
|
class QueryProcessor
|
4
6
|
|
7
|
+
# The Regular Expression which all resource queries must match
|
5
8
|
QUERY_PATTERN = %r{(.*)::(.*)::(.*)::(.*)}
|
6
9
|
|
7
10
|
# Creates an object for filtering Resources from a set of AccountTrackers
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# * +trackers+ - a Hash of AccountTrackers, indexed by Account name
|
12
|
-
# * +options+ - Hash of optional parameters
|
13
|
-
#
|
14
|
-
# ==== Options
|
15
|
-
#
|
16
|
-
# * +:logger+ - a Ruby Logger-compatible object
|
11
|
+
# @param [Hash] trackers a Hash of AccountTrackers, indexed by account name
|
12
|
+
# @param [Hash] options optional additional parameters:
|
13
|
+
# - :logger - a Ruby Logger-compatible object
|
17
14
|
def initialize(trackers, options={})
|
18
15
|
@trackers = trackers
|
19
16
|
@log = options[:logger] || FogTracker.default_logger
|
20
17
|
end
|
21
18
|
|
22
|
-
#
|
19
|
+
# Uses the query string to filter this account's resources
|
20
|
+
# for a desired subset
|
21
|
+
# @param [String] query a string used to filter for matching resources
|
22
|
+
# @return [Array <Fog::Model>] an Array of Resources, filtered by query
|
23
23
|
def execute(query)
|
24
24
|
acct_pattern, svc_pattern, prov_pattern, col_pattern = parse_query(query)
|
25
25
|
filter_by_collection(
|
@@ -48,20 +48,18 @@ module FogTracker
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
# Converts a String
|
51
|
+
# Converts a String token into a RegEx for matching query values
|
52
52
|
def regex_from_token(token)
|
53
53
|
token = '.*' if token == '*' # a single wildcard is a special case
|
54
54
|
%r{^\s*#{token}\s*$}i # otherwise, interpret as a RegEx
|
55
55
|
end
|
56
56
|
|
57
|
-
# Returns a subset of all Resources, filtered only by
|
57
|
+
# Returns a subset of all Resources, filtered only by acct_name_pattern
|
58
58
|
def get_results_by_account(acct_name_pattern)
|
59
59
|
results = Array.new
|
60
60
|
@trackers.each do |account_name, account_tracker|
|
61
61
|
if account_name.match acct_name_pattern
|
62
|
-
account_tracker.
|
63
|
-
results += resource_tracker.collection
|
64
|
-
end
|
62
|
+
results += account_tracker.all_resources
|
65
63
|
end
|
66
64
|
end
|
67
65
|
results
|
data/lib/fog_tracker/tracker.rb
CHANGED
@@ -1,25 +1,21 @@
|
|
1
1
|
module FogTracker
|
2
2
|
|
3
|
-
# Tracks one or more Fog accounts and exposes a query
|
3
|
+
# Tracks one or more Fog accounts and exposes a {#query} on the results
|
4
4
|
class Tracker
|
5
5
|
|
6
|
+
#a Hash of account information (see accounts.yml.example)
|
6
7
|
attr_accessor :accounts
|
7
8
|
|
8
|
-
# Creates an object for tracking Fog accounts
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# * +:callback+ - A Proc to call each time an account is polled.
|
19
|
-
# It should take the name of the account as its only required parameter
|
20
|
-
# * +:error_callback+ - A Proc to call if polling errors occur.
|
21
|
-
# It should take a single Exception as its only required parameter
|
22
|
-
# * +:logger+ - a Ruby Logger-compatible object
|
9
|
+
# Creates an object for tracking multiple Fog accounts
|
10
|
+
# @param [Hash] accounts a Hash of account information
|
11
|
+
# (see accounts.yml.example)
|
12
|
+
# @param [Hash] options optional additional parameters:
|
13
|
+
# - :delay (Integer) - Default time between polling of accounts
|
14
|
+
# - :callback (Proc) - A Method or Proc to call each time an account is polled.
|
15
|
+
# (should take the name of the account as its only required parameter)
|
16
|
+
# - :error_callback (Proc) - A Method or Proc to call if polling errors occur.
|
17
|
+
# (should take a single Exception as its only required parameter)
|
18
|
+
# - :logger - a Ruby Logger-compatible object
|
23
19
|
def initialize(accounts = {}, options = {})
|
24
20
|
@accounts = accounts
|
25
21
|
@delay = options[:delay]
|
@@ -28,9 +24,11 @@ module FogTracker
|
|
28
24
|
@error_proc = options[:error_callback]
|
29
25
|
# Create a Hash that maps account names to AccountTrackers
|
30
26
|
create_trackers
|
27
|
+
@running = false
|
31
28
|
end
|
32
29
|
|
33
|
-
#
|
30
|
+
# Starts periodically polling all this tracker's accounts
|
31
|
+
# for all their Fog resource collections
|
34
32
|
def start
|
35
33
|
if not running?
|
36
34
|
@log.info "Tracking #{@trackers.keys.count} accounts..."
|
@@ -41,7 +39,7 @@ module FogTracker
|
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
44
|
-
#
|
42
|
+
# Stops polling for all this tracker's accounts
|
45
43
|
def stop
|
46
44
|
if running?
|
47
45
|
@log.info "Stopping tracker..."
|
@@ -52,21 +50,22 @@ module FogTracker
|
|
52
50
|
end
|
53
51
|
end
|
54
52
|
|
55
|
-
# Returns true or false
|
53
|
+
# Returns true or false, depending on whether this tracker is polling
|
54
|
+
# @return [true, false]
|
56
55
|
def running? ; @running end
|
57
56
|
|
58
|
-
# Returns an
|
57
|
+
# Returns an Array of resource types for a given account
|
58
|
+
# @param [String] name the name of the account
|
59
|
+
# @return [Array<String>] an array of Resource types
|
59
60
|
def types_for_account(account_name)
|
60
61
|
@trackers[account_name].tracked_types
|
61
62
|
end
|
62
63
|
|
63
|
-
# Returns an array of Resources matching the
|
64
|
-
# Calls any block passed for each resulting resource
|
65
|
-
#
|
66
|
-
# ==== Attributes
|
67
|
-
#
|
68
|
-
# * +query_string+ - a String used to filter the discovered Resources
|
64
|
+
# Returns an array of Resources matching the {query_string}.
|
65
|
+
# Calls any block passed for each resulting resource.
|
66
|
+
# @param [String] query_string a string used to filter for matching resources
|
69
67
|
# it might look like: "Account Name::Compute::AWS::servers"
|
68
|
+
# @return [Array <Fog::Model>] an Array of Resources, filtered by query
|
70
69
|
def query(query_string)
|
71
70
|
results = FogTracker::Query::QueryProcessor.new(
|
72
71
|
@trackers, :logger => @log
|
@@ -89,7 +88,7 @@ module FogTracker
|
|
89
88
|
@accounts.each do |name, account|
|
90
89
|
@log.debug "Setting up tracker for account #{name}"
|
91
90
|
@trackers[name] = AccountTracker.new(name, account,
|
92
|
-
{:delay => @delay, :callback => @callback,
|
91
|
+
{:delay => @delay, :callback => @callback,
|
93
92
|
:error_callback => @error_proc, :logger => @log})
|
94
93
|
end
|
95
94
|
end
|
data/lib/fog_tracker/version.rb
CHANGED
data/lib/fog_tracker.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
3
|
# Load all ruby files from the 'fog' and 'fog_tracker' directories
|
4
|
-
Dir[File.join(File.dirname(__FILE__), "fog/**/*.rb")].each {|f| require f}
|
5
4
|
Dir[File.join(File.dirname(__FILE__), "fog_tracker/**/*.rb")].each {|f| require f}
|
5
|
+
Dir[File.join(File.dirname(__FILE__), "fog/**/*.rb")].each {|f| require f}
|
6
6
|
|
7
7
|
module FogTracker
|
8
8
|
|
@@ -5,8 +5,18 @@ module FogTracker
|
|
5
5
|
describe AccountTracker do
|
6
6
|
|
7
7
|
before(:each) do
|
8
|
+
@account_receiver = double "account callback object"
|
9
|
+
@account_receiver.stub(:callback)
|
10
|
+
@error_receiver = double "error callback object"
|
11
|
+
@error_receiver.stub(:callback)
|
8
12
|
@tracker = AccountTracker.new(
|
9
|
-
FAKE_ACCOUNT_NAME, FAKE_ACCOUNT,
|
13
|
+
FAKE_ACCOUNT_NAME, FAKE_ACCOUNT, #:logger => LOG, # uncomment to debug
|
14
|
+
:callback => Proc.new do |resources|
|
15
|
+
@account_receiver.callback(resources)
|
16
|
+
end,
|
17
|
+
:error_callback => Proc.new do |exception|
|
18
|
+
@error_receiver.callback(exception)
|
19
|
+
end
|
10
20
|
)
|
11
21
|
end
|
12
22
|
|
@@ -22,45 +32,33 @@ module FogTracker
|
|
22
32
|
it "exposes the connection to its logger" do
|
23
33
|
@tracker.log.should_not == nil
|
24
34
|
end
|
25
|
-
it "exposes a collection of ResourceTrackers" do
|
26
|
-
@tracker.resource_trackers.size.should be > 0
|
27
|
-
end
|
28
35
|
|
29
36
|
context "when it encounters an Exception while updating" do
|
30
37
|
context "when initialized with an error callback" do
|
31
38
|
it "should fire the callback" do
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
tracker = AccountTracker.new(
|
36
|
-
FAKE_ACCOUNT_NAME, FAKE_ACCOUNT, {
|
37
|
-
:error_callback => Proc.new {|err| receiver.callback(err)}
|
38
|
-
}
|
39
|
-
)
|
40
|
-
receiver.should_receive(:callback).exactly(:once)
|
41
|
-
tracker.start
|
39
|
+
CollectionTracker.any_instance.stub(:update).and_raise
|
40
|
+
@error_receiver.should_receive(:callback).exactly(:once)
|
41
|
+
@tracker.start
|
42
42
|
sleep THREAD_STARTUP_DELAY
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
describe '#start' do
|
48
|
-
it "sends update() to its
|
49
|
-
|
50
|
-
|
48
|
+
it "sends update() to its CollectionTrackers" do
|
49
|
+
update_catcher = double "mock for catching CollectionTracker::update"
|
50
|
+
update_catcher.stub(:update)
|
51
|
+
CollectionTracker.any_instance.stub(:update) do
|
52
|
+
update_catcher.update
|
51
53
|
end
|
54
|
+
update_catcher.should_receive(:update)
|
52
55
|
@tracker.start
|
53
56
|
sleep THREAD_STARTUP_DELAY # wait for background thread to start
|
54
57
|
end
|
55
58
|
it "invokes its callback Proc when its account is updated" do
|
56
|
-
|
57
|
-
|
58
|
-
tracker
|
59
|
-
FAKE_ACCOUNT_NAME, FAKE_ACCOUNT, :logger => LOG,
|
60
|
-
:callback => Proc.new {|resources| receiver.callback(resources)}
|
61
|
-
)
|
62
|
-
receiver.should_receive(:callback).exactly(FAKE_ACCOUNTS.size).times
|
63
|
-
tracker.start
|
59
|
+
@account_receiver.should_receive(:callback).
|
60
|
+
exactly(FAKE_ACCOUNTS.size).times
|
61
|
+
@tracker.start
|
64
62
|
sleep THREAD_STARTUP_DELAY
|
65
63
|
end
|
66
64
|
end
|
@@ -72,7 +70,7 @@ module FogTracker
|
|
72
70
|
end
|
73
71
|
it "kills its timer thread" do
|
74
72
|
@tracker.start ; @tracker.stop
|
75
|
-
@
|
73
|
+
@account_receiver.should_not_receive(:callback)
|
76
74
|
sleep THREAD_STARTUP_DELAY # wait to make sure no update()s are sent
|
77
75
|
end
|
78
76
|
end
|
@@ -94,6 +92,14 @@ module FogTracker
|
|
94
92
|
end
|
95
93
|
end
|
96
94
|
|
97
|
-
|
95
|
+
describe '#all_resources' do
|
96
|
+
it "returns a flattened Array of all its CollectionTrackers collections" do
|
97
|
+
COLLECTION = [ 1, 2, 3 ]
|
98
|
+
NUM_TYPES = @tracker.tracked_types.size
|
99
|
+
CollectionTracker.any_instance.stub(:collection).and_return(COLLECTION)
|
100
|
+
@tracker.all_resources.should == ((1..NUM_TYPES).map {COLLECTION}).flatten
|
101
|
+
end
|
102
|
+
end
|
98
103
|
|
104
|
+
end
|
99
105
|
end
|
@@ -23,7 +23,9 @@ module FogTracker
|
|
23
23
|
QUERY.each do |name, query|
|
24
24
|
it "should return an empty Array for a query #{name}" do
|
25
25
|
QueryProcessor.new(
|
26
|
-
{FAKE_ACCOUNT_NAME =>
|
26
|
+
{FAKE_ACCOUNT_NAME => AccountTracker.new(
|
27
|
+
FAKE_ACCOUNT_NAME, FAKE_ACCOUNT, :logger => LOG
|
28
|
+
)}, :logger => LOG
|
27
29
|
).execute(query).should == []
|
28
30
|
end
|
29
31
|
end
|
@@ -31,15 +33,24 @@ module FogTracker
|
|
31
33
|
|
32
34
|
context "with a pre-populated, diverse set of Resources" do
|
33
35
|
# Create a prepopulated QueryProcessor
|
34
|
-
NUMBER_OF_ACCOUNTS
|
35
|
-
|
36
|
-
|
36
|
+
NUMBER_OF_ACCOUNTS = 8
|
37
|
+
NUMBER_OF_COLLECTIONS = [5, NUMBER_OF_FAKE_RESOURCE_TYPES].min
|
38
|
+
RESOURCES_PER_COLLECTION = 10
|
37
39
|
before(:each) do
|
38
40
|
account_trackers =
|
39
41
|
(1..NUMBER_OF_ACCOUNTS).inject({}) do |t, account_index|
|
40
|
-
|
41
|
-
|
42
|
-
)
|
42
|
+
account_tracker = AccountTracker.new(
|
43
|
+
FAKE_ACCOUNT_NAME, FAKE_ACCOUNT, :logger => LOG
|
44
|
+
)
|
45
|
+
account_tracker.stub(:all_resources).and_return(
|
46
|
+
((1..NUMBER_OF_COLLECTIONS).map do |collection_index|
|
47
|
+
(1..RESOURCES_PER_COLLECTION).collect do |resource|
|
48
|
+
create_resource(collection_index)
|
49
|
+
end
|
50
|
+
end).flatten
|
51
|
+
)
|
52
|
+
t["Fake Account #{account_index}"] = account_tracker
|
53
|
+
t
|
43
54
|
end
|
44
55
|
@processor = QueryProcessor.new(account_trackers, :logger => LOG)
|
45
56
|
end
|
@@ -47,34 +58,34 @@ module FogTracker
|
|
47
58
|
context "when running the query matching all Resources" do
|
48
59
|
it "should return all Resources" do
|
49
60
|
@processor.execute(QUERY['matching all Resources']).size.should ==
|
50
|
-
NUMBER_OF_ACCOUNTS * NUMBER_OF_COLLECTIONS
|
61
|
+
NUMBER_OF_ACCOUNTS * NUMBER_OF_COLLECTIONS* RESOURCES_PER_COLLECTION
|
51
62
|
end
|
52
63
|
end
|
53
64
|
context "when running a query by account name" do
|
54
65
|
it "should return all Resources for that account only" do
|
55
66
|
@processor.execute(QUERY['by account name']).size.should ==
|
56
|
-
NUMBER_OF_ACCOUNTS * NUMBER_OF_COLLECTIONS
|
67
|
+
NUMBER_OF_ACCOUNTS * NUMBER_OF_COLLECTIONS* RESOURCES_PER_COLLECTION
|
57
68
|
@processor.execute('wrong account::*::*::*').size.should == 0
|
58
69
|
end
|
59
70
|
end
|
60
71
|
context "when running a query by Fog service name" do
|
61
72
|
it "should return all Resources for that service only" do
|
62
73
|
@processor.execute(QUERY['by Fog Service']).size.should ==
|
63
|
-
NUMBER_OF_ACCOUNTS * NUMBER_OF_COLLECTIONS
|
74
|
+
NUMBER_OF_ACCOUNTS * NUMBER_OF_COLLECTIONS* RESOURCES_PER_COLLECTION
|
64
75
|
@processor.execute('*::wrong service::*::*').size.should == 0
|
65
76
|
end
|
66
77
|
end
|
67
78
|
context "when running a query by Fog provider name" do
|
68
79
|
it "should return all Resources for that provider only" do
|
69
80
|
@processor.execute(QUERY['by Fog Provider']).size.should ==
|
70
|
-
NUMBER_OF_ACCOUNTS * NUMBER_OF_COLLECTIONS
|
81
|
+
NUMBER_OF_ACCOUNTS * NUMBER_OF_COLLECTIONS* RESOURCES_PER_COLLECTION
|
71
82
|
@processor.execute('*::*::wrong provider::*').size.should == 0
|
72
83
|
end
|
73
84
|
end
|
74
85
|
context "when running a query by Fog collection name" do
|
75
86
|
it "should return all Resources for that collection only" do
|
76
87
|
@processor.execute(QUERY['by Fog collection name']).size.should ==
|
77
|
-
NUMBER_OF_ACCOUNTS *
|
88
|
+
NUMBER_OF_ACCOUNTS * RESOURCES_PER_COLLECTION
|
78
89
|
@processor.execute('*::*::*::wrong collection').size.should == 0
|
79
90
|
true
|
80
91
|
end
|
@@ -2,13 +2,13 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module FogTracker
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe CollectionTracker do
|
6
6
|
|
7
7
|
before(:each) do
|
8
8
|
@account_tracker = AccountTracker.new(
|
9
9
|
FAKE_ACCOUNT_NAME, FAKE_ACCOUNT, :logger => LOG
|
10
10
|
)
|
11
|
-
@tracker =
|
11
|
+
@tracker = CollectionTracker.new(
|
12
12
|
FAKE_COLLECTION, @account_tracker
|
13
13
|
)
|
14
14
|
end
|
@@ -18,15 +18,14 @@ module FogTracker
|
|
18
18
|
end
|
19
19
|
|
20
20
|
describe '#update' do
|
21
|
-
it "refreshes its resource collection
|
21
|
+
it "refreshes its resource collection "+
|
22
|
+
"from its AccountTracker's connection" do
|
22
23
|
@account_tracker.connection.should_receive(FAKE_COLLECTION)
|
23
24
|
@tracker.update
|
24
25
|
end
|
25
26
|
it "attaches account information to all resources" do
|
26
|
-
|
27
|
-
tracker
|
28
|
-
tracker.update
|
29
|
-
tracker.collection.each do |resource|
|
27
|
+
@tracker.update
|
28
|
+
@tracker.collection.each do |resource|
|
30
29
|
resource.tracker_account[:name].should == FAKE_ACCOUNT_NAME
|
31
30
|
resource.tracker_account[:credentials].should == {}
|
32
31
|
end
|
data/spec/support/_mocks.rb
CHANGED
@@ -15,27 +15,12 @@ module FogTracker
|
|
15
15
|
},
|
16
16
|
:exclude_resources => [
|
17
17
|
:spot_requests, # No Fog mocks for this resource
|
18
|
-
#:account,
|
19
|
-
#:flavors,
|
20
|
-
#:images,
|
21
|
-
#:addresses,
|
22
|
-
#:volumes,
|
23
|
-
#:snapshots,
|
24
|
-
#:tags,
|
25
|
-
#:servers,
|
26
|
-
#:security_groups,
|
27
|
-
#:key_pairs,
|
28
|
-
#:spot_instance_requests
|
29
18
|
],
|
30
19
|
}
|
31
20
|
FAKE_ACCOUNTS = {FAKE_ACCOUNT_NAME => FAKE_ACCOUNT}
|
32
21
|
module Query
|
33
22
|
QUERY = {} # Used in query_processor_spec.rb
|
34
23
|
end
|
35
|
-
class MockFogResource < Fog::Model
|
36
|
-
#attr_accessor :tracker_account
|
37
|
-
def identity ; "random-resource-id-#{rand 65536}" end
|
38
|
-
end
|
39
24
|
end
|
40
25
|
|
41
26
|
# Create some fake Fog Resource and Collection Classes
|
@@ -55,38 +40,8 @@ module Fog
|
|
55
40
|
end
|
56
41
|
end
|
57
42
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
fake_account_tracker.stub(:log).and_return(LOG)
|
63
|
-
fake_account_tracker.stub(:all_resources).and_return(Array.new)
|
64
|
-
fake_account_tracker.stub(:connection).and_return(mock_fog_connection)
|
65
|
-
# create an array of mock ResourceTrackers
|
66
|
-
trackers = (1..num_collections).map do |class_index|
|
67
|
-
mock_resource_tracker(
|
68
|
-
Fog::FakeService::FakeProvider.const_get("FakeResourceType#{class_index}"),
|
69
|
-
resources_per_collection
|
70
|
-
)
|
71
|
-
end
|
72
|
-
fake_account_tracker.stub(:resource_trackers).and_return(trackers)
|
73
|
-
fake_account_tracker
|
74
|
-
end
|
75
|
-
|
76
|
-
def mock_fog_connection
|
77
|
-
fake_fog_connection = double('mock_fog_connection')
|
78
|
-
fake_fog_connection.stub(FogTracker::FAKE_COLLECTION).and_return(
|
79
|
-
[ FogTracker::MockFogResource.new, FogTracker::MockFogResource.new ]
|
80
|
-
)
|
81
|
-
fake_fog_connection
|
82
|
-
end
|
83
|
-
|
84
|
-
def mock_resource_tracker(resource_class, number_of_resources = 0)
|
85
|
-
fake_resource_tracker = double("mock_resource_tracker")
|
86
|
-
resources = Array.new
|
87
|
-
number_of_resources.times do
|
88
|
-
resources << resource_class.new
|
89
|
-
end
|
90
|
-
fake_resource_tracker.stub(:collection).and_return(resources)
|
91
|
-
fake_resource_tracker
|
43
|
+
def create_resource(type_index = (rand NUMBER_OF_FAKE_RESOURCE_TYPES)+1)
|
44
|
+
Fog::FakeService::FakeProvider.const_get(
|
45
|
+
"FakeResourceType#{type_index}"
|
46
|
+
).new
|
92
47
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fog_tracker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-29 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
16
|
-
requirement: &
|
16
|
+
requirement: &70093896997020 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70093896997020
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70093896996120 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70093896996120
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70093896994520 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70093896994520
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
49
|
-
requirement: &
|
48
|
+
name: yard
|
49
|
+
requirement: &70093896993060 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70093896993060
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: guard
|
60
|
-
requirement: &
|
60
|
+
requirement: &70093896991540 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70093896991540
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name: guard-
|
71
|
-
requirement: &
|
70
|
+
name: guard-rspec
|
71
|
+
requirement: &70093896989420 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70093896989420
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: ruby_gntp
|
82
|
-
requirement: &
|
82
|
+
requirement: &70093896987000 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70093896987000
|
91
91
|
description: This gem peridically polls mutiple cloud computing services using the
|
92
92
|
fog gem, asynchronously updating the state of the resulting collections of Fog Resources.
|
93
93
|
email:
|
@@ -98,6 +98,7 @@ extensions: []
|
|
98
98
|
extra_rdoc_files: []
|
99
99
|
files:
|
100
100
|
- .gitignore
|
101
|
+
- .yardopts
|
101
102
|
- Gemfile
|
102
103
|
- Guardfile
|
103
104
|
- README.md
|
@@ -105,11 +106,11 @@ files:
|
|
105
106
|
- bin/tracker
|
106
107
|
- config/accounts.yml.example
|
107
108
|
- fog_tracker.gemspec
|
109
|
+
- lib/fog/core/model.rb
|
108
110
|
- lib/fog_tracker.rb
|
109
111
|
- lib/fog_tracker/account_tracker.rb
|
110
|
-
- lib/fog_tracker/
|
112
|
+
- lib/fog_tracker/collection_tracker.rb
|
111
113
|
- lib/fog_tracker/query/query_processor.rb
|
112
|
-
- lib/fog_tracker/resource_tracker.rb
|
113
114
|
- lib/fog_tracker/tracker.rb
|
114
115
|
- lib/fog_tracker/util/string_underscore.rb
|
115
116
|
- lib/fog_tracker/version.rb
|
@@ -136,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
137
|
version: '0'
|
137
138
|
segments:
|
138
139
|
- 0
|
139
|
-
hash:
|
140
|
+
hash: 589883015526840149
|
140
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
142
|
none: false
|
142
143
|
requirements:
|
@@ -145,10 +146,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
146
|
version: '0'
|
146
147
|
segments:
|
147
148
|
- 0
|
148
|
-
hash:
|
149
|
+
hash: 589883015526840149
|
149
150
|
requirements: []
|
150
151
|
rubyforge_project: fog_tracker
|
151
|
-
rubygems_version: 1.8.
|
152
|
+
rubygems_version: 1.8.10
|
152
153
|
signing_key:
|
153
154
|
specification_version: 3
|
154
155
|
summary: Tracks the state of cloud computing resources across multiple accounts with
|
@@ -162,3 +163,4 @@ test_files:
|
|
162
163
|
- spec/support/_configure_logging.rb
|
163
164
|
- spec/support/_mocks.rb
|
164
165
|
- spec/support/_threading_support.rb
|
166
|
+
has_rdoc:
|
data/lib/fog_tracker/model.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# add an accessor and a method to decorate Fog::Model instances
|
2
|
-
# with tracker account information
|
3
|
-
module Fog
|
4
|
-
class Model
|
5
|
-
|
6
|
-
# a FogTracker::CollectionTracker
|
7
|
-
attr_accessor :fog_collection_tracker
|
8
|
-
|
9
|
-
# returns a clean copy of the resource's account information
|
10
|
-
# from the its collection tracker
|
11
|
-
def tracker_account
|
12
|
-
if fog_collection_tracker
|
13
|
-
fog_collection_tracker.clean_account_data
|
14
|
-
else
|
15
|
-
Hash.new
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|