aws_tracker 0.0.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 +12 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/README.md +111 -0
- data/Rakefile +9 -0
- data/aws_tracker.gemspec +33 -0
- data/bin/tracker +104 -0
- data/config/database.yml.example +4 -0
- data/db/migrate/20110331145142_create_aws_accounts.rb +16 -0
- data/db/migrate/20110331152735_create_instances.rb +38 -0
- data/db/migrate/20110403041402_create_security_groups.rb +16 -0
- data/db/migrate/20110403060000_create_instance_groups.rb +14 -0
- data/db/migrate/20110404014218_create_ebs_volumes.rb +23 -0
- data/db/migrate/20110408193824_create_tags.rb +17 -0
- data/lib/aws_tracker/models/aws_account.rb +69 -0
- data/lib/aws_tracker/models/ebs_volume.rb +55 -0
- data/lib/aws_tracker/models/instance.rb +71 -0
- data/lib/aws_tracker/models/security_group.rb +34 -0
- data/lib/aws_tracker/models/tag.rb +66 -0
- data/lib/aws_tracker/tracker.rb +64 -0
- data/lib/aws_tracker/version.rb +3 -0
- data/lib/aws_tracker.rb +17 -0
- data/lib/tasks/bundler.rake +1 -0
- data/lib/tasks/database.rake +21 -0
- data/lib/tasks/rspec.rake +6 -0
- data/spec/lib/aws_tracker/models/aws_account_spec.rb +103 -0
- data/spec/lib/aws_tracker/models/ebs_volume_spec.rb +97 -0
- data/spec/lib/aws_tracker/models/instance_spec.rb +96 -0
- data/spec/lib/aws_tracker/models/security_group_spec.rb +71 -0
- data/spec/lib/aws_tracker/models/tag_spec.rb +76 -0
- data/spec/lib/aws_tracker/tracker_spec.rb +50 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/_configure_logging.rb +8 -0
- data/spec/support/create_testing_objects.rb +30 -0
- metadata +178 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
module AWSTracker
|
2
|
+
class Tag < ActiveRecord::Base
|
3
|
+
|
4
|
+
belongs_to :account,
|
5
|
+
:class_name => 'AWSAccount',
|
6
|
+
:foreign_key => "aws_account_id"
|
7
|
+
belongs_to :resource, :polymorphic => true
|
8
|
+
|
9
|
+
validates_presence_of :account, :key, :resource_type, :resource_id
|
10
|
+
validates_uniqueness_of :key, :scope => :resource_id
|
11
|
+
|
12
|
+
# Maps right_aws Tag resource_types to the corresponding
|
13
|
+
# ActiveRecord Class names
|
14
|
+
@@RIGHT_AWS_CLASS_NAMES = {
|
15
|
+
:instance => :Instance,
|
16
|
+
:volume => :EBSVolume
|
17
|
+
}
|
18
|
+
# Maps ActiveRecord Class names to their Amamzon
|
19
|
+
# "primary key" attribute names
|
20
|
+
@@AWS_PK_FIELDS = {
|
21
|
+
:Instance => :instance_id,
|
22
|
+
:EBSVolume => :volume_id
|
23
|
+
}
|
24
|
+
|
25
|
+
def self.refresh_from_account(acc)
|
26
|
+
acc.log.info "Updating tags for account '#{acc.name}'"
|
27
|
+
|
28
|
+
right_aws_array = acc.ec2.describe_tags
|
29
|
+
right_aws_array.each do |rs_tag|
|
30
|
+
# First, dereference the polymorphic association, and
|
31
|
+
# ABORT if the Tag's AWS resource is not found in the current state
|
32
|
+
right_aws_type = rs_tag[:resource_type].to_sym
|
33
|
+
resource_class_name = @@RIGHT_AWS_CLASS_NAMES[right_aws_type]
|
34
|
+
aws_pk_attribute = @@AWS_PK_FIELDS[resource_class_name]
|
35
|
+
collection_name = resource_class_name.to_s.pluralize.underscore
|
36
|
+
tag_resource = acc.send(collection_name).find(:first,
|
37
|
+
:conditions => { aws_pk_attribute => rs_tag[:resource_id]})
|
38
|
+
if (tag_resource == nil)
|
39
|
+
acc.log.warn "Tag #{rs_tag[:key]} references nonexistent "+
|
40
|
+
"#{resource_class_name} #{rs_tag[:resource_id]}. Ignoring this Tag."
|
41
|
+
else
|
42
|
+
# See if this Tag already exists, otherwise create it
|
43
|
+
tag_to_update = tag_resource.tags.find(:first,
|
44
|
+
:conditions => {:key => rs_tag[:key]})
|
45
|
+
tag_to_update ||= Tag.new(:account => acc)
|
46
|
+
|
47
|
+
# Asssociations - link this Tag to its account
|
48
|
+
tag_to_update.account = acc
|
49
|
+
acc.tags << tag_to_update
|
50
|
+
# Asssociations - link this tag to its AWS resource
|
51
|
+
tag_to_update.resource = tag_resource
|
52
|
+
tag_resource.tags << tag_to_update
|
53
|
+
tag_to_update.update_from_right_hash(rs_tag)
|
54
|
+
tag_to_update.save
|
55
|
+
end
|
56
|
+
end
|
57
|
+
acc.log.info "Account '#{acc.name}' reports #{right_aws_array.count} tags"
|
58
|
+
end
|
59
|
+
|
60
|
+
def update_from_right_hash(right_hash)
|
61
|
+
self.key = right_hash[:key]
|
62
|
+
self.value = right_hash[:value]
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module AWSTracker
|
2
|
+
|
3
|
+
# Tracks one or more AwsAccounts in an ActiveRecord database
|
4
|
+
class Tracker
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
attr_accessor :delay # How many seconds to wait between status updates
|
8
|
+
attr_reader :accounts, :log
|
9
|
+
|
10
|
+
# Creates an object for tracking AWS accounts
|
11
|
+
# Tracked info is stored in an ActiveRecord database with config db_config
|
12
|
+
def initialize(options={})
|
13
|
+
@log = options[:logger] || AWSTracker.default_logger
|
14
|
+
@delay = options[:delay] || 300 # default delay is 5 minutes
|
15
|
+
load_aws_acounts
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_aws_acounts
|
19
|
+
@log.debug "Reading AWS accounts from database..."
|
20
|
+
@accounts = AWSAccount.find(:all)
|
21
|
+
if @accounts.empty?
|
22
|
+
@log.warn "No accounts found in database"
|
23
|
+
end
|
24
|
+
@accounts.each {|acc| acc.log = @log } # pass logger to all resources
|
25
|
+
end
|
26
|
+
|
27
|
+
def update_status(selected_accounts = accounts)
|
28
|
+
selected_accounts.each do |account|
|
29
|
+
@log.info "Updating account #{account.name}..."
|
30
|
+
account.update_status
|
31
|
+
@log.info "Status update complete for account #{account.name}..."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def running?
|
36
|
+
@timer != nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def start
|
40
|
+
if not running?
|
41
|
+
@log.info "Tracking for #{accounts.count} accounts..."
|
42
|
+
@timer = Thread.new do
|
43
|
+
while true do
|
44
|
+
update_status
|
45
|
+
sleep @delay
|
46
|
+
end
|
47
|
+
end
|
48
|
+
else
|
49
|
+
@log.info "Automatic status updates already running"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def stop
|
54
|
+
if running?
|
55
|
+
@log.info "Stopping automatic updates"
|
56
|
+
@timer.kill
|
57
|
+
@timer = nil
|
58
|
+
else
|
59
|
+
@log.info "Automatic updates already stopped"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
data/lib/aws_tracker.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
# Load all ruby files from 'aws_tracker' directory
|
5
|
+
Dir[File.join(File.dirname(__FILE__), "aws_tracker/**/*.rb")].each {|f| require f}
|
6
|
+
|
7
|
+
module AWSTracker
|
8
|
+
# Returns a slightly-modified version of the default Ruby Logger
|
9
|
+
def self.default_logger
|
10
|
+
logger = ::Logger.new(STDOUT)
|
11
|
+
logger.sev_threshold = Logger::INFO
|
12
|
+
logger.formatter = proc {|lvl, time, prog, msg|
|
13
|
+
"#{lvl} #{time.strftime '%Y-%m-%d %H:%M:%S %Z'}: #{msg}\n"
|
14
|
+
}
|
15
|
+
logger
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Bundler::GemHelper.install_tasks
|
@@ -0,0 +1,21 @@
|
|
1
|
+
DB_CONFIG_FILE = File.expand_path('../../../config/database.yml', __FILE__)
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
namespace :db do
|
5
|
+
namespace :migrate do
|
6
|
+
|
7
|
+
desc "Conforms the schema of the AWS Tracker database."+
|
8
|
+
"Target specific version with VERSION=x"
|
9
|
+
task :tracker => :db_connect do
|
10
|
+
ActiveRecord::Migrator.migrate(
|
11
|
+
'db/migrate', ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
task :db_connect do
|
16
|
+
ActiveRecord::Base.establish_connection(
|
17
|
+
YAML::load(File.open(DB_CONFIG_FILE)))
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module AWSTracker
|
4
|
+
|
5
|
+
describe AWSAccount do
|
6
|
+
before(:each) do
|
7
|
+
@account = get_memory_resident_account
|
8
|
+
@account.save
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:each) do
|
12
|
+
@account.destroy
|
13
|
+
end
|
14
|
+
|
15
|
+
it "is valid with valid attributes" do
|
16
|
+
@account.should be_valid
|
17
|
+
end
|
18
|
+
|
19
|
+
it "is not valid without an account ID" do
|
20
|
+
@account.account_id = nil
|
21
|
+
@account.should_not be_valid
|
22
|
+
end
|
23
|
+
|
24
|
+
it "is not valid without an access key" do
|
25
|
+
@account.access_key_id = nil
|
26
|
+
@account.should_not be_valid
|
27
|
+
end
|
28
|
+
|
29
|
+
it "is not valid without a secret access key" do
|
30
|
+
@account.secret_access_key = nil
|
31
|
+
@account.should_not be_valid
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#update_instances" do
|
35
|
+
it "fetches an array of Instances from the AWS endpoint" do
|
36
|
+
@account.instances.should be_empty
|
37
|
+
@account.update_instances
|
38
|
+
@account.instances.should_not be_empty
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#update_security_groups" do
|
43
|
+
it "fetches an array of Security Groups from the AWS endpoint" do
|
44
|
+
@account.security_groups.should be_empty
|
45
|
+
@account.update_security_groups
|
46
|
+
@account.security_groups.should_not be_empty
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#update_ebs_volumes" do
|
51
|
+
it "fetches an array of EBS Volumes from the AWS endpoint" do
|
52
|
+
@account.ebs_volumes.should be_empty
|
53
|
+
@account.update_ebs_volumes
|
54
|
+
@account.ebs_volumes.should_not be_empty
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#update_tags" do
|
59
|
+
it "fetches an array of AWS Tags from the AWS endpoint" do
|
60
|
+
@account.tags.should be_empty
|
61
|
+
@account.update_instances
|
62
|
+
@account.update_ebs_volumes
|
63
|
+
@account.update_tags
|
64
|
+
@account.tags.should_not be_empty
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#update_status" do
|
69
|
+
it "populates all AWS entity collections" do
|
70
|
+
@account.update_status
|
71
|
+
@account.security_groups.should_not be_empty
|
72
|
+
@account.instances.should_not be_empty
|
73
|
+
@account.ebs_volumes.should_not be_empty
|
74
|
+
@account.tags.should_not be_empty
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# tests the presence of :dependent => destroy for instances
|
79
|
+
it "destroys its Instances when it is destroyed" do
|
80
|
+
Instance.delete_all
|
81
|
+
Instance.find(:all).should be_empty
|
82
|
+
@account.instances.create({
|
83
|
+
:instance_id => "fake_instance_id",
|
84
|
+
:image_id => "fake_image_id",
|
85
|
+
:instance_state => "fake_instance_state",
|
86
|
+
})
|
87
|
+
Instance.find(:all).should_not be_empty
|
88
|
+
@account.destroy
|
89
|
+
Instance.find(:all).should be_empty
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#from_memory" do
|
93
|
+
it "returns an account based on ENV variables in memory" do
|
94
|
+
account = AWSAccount.from_memory
|
95
|
+
account.account_id.should == ENV['AWS_ACCOUNT_NUMBER']
|
96
|
+
#account.access_key_id.should == ENV['AWS_ACCESS_KEY_ID']
|
97
|
+
#account.secret_access_key.should == ENV['AWS_ACCESS_KEY_SECRET']
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module AWSTracker
|
4
|
+
|
5
|
+
describe EBSVolume do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@account = get_memory_resident_account
|
9
|
+
@account.save!
|
10
|
+
@instance = @account.instances.create({
|
11
|
+
:instance_id => "fake_instance_id",
|
12
|
+
:image_id => "fake_image_id",
|
13
|
+
:instance_state => "fake_instance_state",
|
14
|
+
})
|
15
|
+
@volume = @account.ebs_volumes.create({
|
16
|
+
:volume_id => "fake_volume_id",
|
17
|
+
:size => 5,
|
18
|
+
:status => "fake_ebs_status",
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
after(:each) do
|
23
|
+
@account.destroy
|
24
|
+
end
|
25
|
+
|
26
|
+
it "is valid with valid attributes" do
|
27
|
+
@volume.should be_valid
|
28
|
+
end
|
29
|
+
|
30
|
+
it "is not valid without an account" do
|
31
|
+
@volume.account = nil
|
32
|
+
@volume.should_not be_valid
|
33
|
+
end
|
34
|
+
|
35
|
+
it "is not valid without an volume ID" do
|
36
|
+
@volume.volume_id = nil
|
37
|
+
@volume.should_not be_valid
|
38
|
+
end
|
39
|
+
|
40
|
+
it "is not valid without a size" do
|
41
|
+
@volume.size = nil
|
42
|
+
@volume.should_not be_valid
|
43
|
+
end
|
44
|
+
|
45
|
+
it "is not valid without a status" do
|
46
|
+
@volume.status = nil
|
47
|
+
@volume.should_not be_valid
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#refresh_from_account" do
|
51
|
+
it "should fetch a list of EBS Volumes from AWS" do
|
52
|
+
@account.ebs_volumes.delete_all
|
53
|
+
@account.ebs_volumes.should be_empty
|
54
|
+
EBSVolume.refresh_from_account(@account)
|
55
|
+
@account.ebs_volumes.should_not be_empty
|
56
|
+
@account.ebs_volumes.first.class.name.should == "AWSTracker::EBSVolume"
|
57
|
+
@account.ebs_volumes.first.account.should == @account
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should update existing records rather than overwriting them" do
|
61
|
+
@account.ebs_volumes.delete_all
|
62
|
+
@account.ebs_volumes.should be_empty
|
63
|
+
EBSVolume.refresh_from_account(@account)
|
64
|
+
first_volume = @account.ebs_volumes.first
|
65
|
+
id = first_volume.id
|
66
|
+
original_status = first_volume.status
|
67
|
+
first_volume.status = "XXXXXXXX"
|
68
|
+
first_volume.save
|
69
|
+
EBSVolume.find(id).status.should == "XXXXXXXX"
|
70
|
+
EBSVolume.refresh_from_account(@account)
|
71
|
+
EBSVolume.find(id).status.should == original_status
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should update the instance relationship as well" do
|
75
|
+
@account.instances.delete_all
|
76
|
+
@account.ebs_volumes.delete_all
|
77
|
+
@account.update_instances
|
78
|
+
@account.update_ebs_volumes
|
79
|
+
EBSVolume.refresh_from_account(@account)
|
80
|
+
@account.ebs_volumes.should_not be_empty
|
81
|
+
volume = @account.ebs_volumes.find(:first,
|
82
|
+
:conditions => { :status => "in-use"})
|
83
|
+
volume.instance.should_not be_nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "#update_instance" do
|
88
|
+
it "resets the instance attribute given an AWS instance ID" do
|
89
|
+
@volume.update_instance(["fake_instance_id"])
|
90
|
+
@volume.instance.should_not == nil
|
91
|
+
@volume.instance.instance_id.should == "fake_instance_id"
|
92
|
+
@volume.instance.instance_state.should == "fake_instance_state"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module AWSTracker
|
4
|
+
|
5
|
+
describe Instance do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@account = get_memory_resident_account
|
9
|
+
@account.save!
|
10
|
+
@instance = @account.instances.create!({
|
11
|
+
:account => @account,
|
12
|
+
:instance_id => "fake_instance_id",
|
13
|
+
:image_id => "fake_image_id",
|
14
|
+
:instance_state => "fake_instance_state",
|
15
|
+
})
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:each) do
|
19
|
+
@account.destroy
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is valid with valid attributes" do
|
23
|
+
@instance.should be_valid
|
24
|
+
end
|
25
|
+
|
26
|
+
it "is not valid without an account" do
|
27
|
+
@instance.account = nil
|
28
|
+
@instance.should_not be_valid
|
29
|
+
end
|
30
|
+
|
31
|
+
it "is not valid without an instance ID" do
|
32
|
+
@instance.instance_id = nil
|
33
|
+
@instance.should_not be_valid
|
34
|
+
end
|
35
|
+
|
36
|
+
it "is not valid without a machine image ID" do
|
37
|
+
@instance.image_id = nil
|
38
|
+
@instance.should_not be_valid
|
39
|
+
end
|
40
|
+
|
41
|
+
it "is not valid without a state" do
|
42
|
+
@instance.instance_state = nil
|
43
|
+
@instance.should_not be_valid
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#refresh_from_account" do
|
47
|
+
it "should fetch a list of Instances from AWS" do
|
48
|
+
@account.instances.clear
|
49
|
+
Instance.refresh_from_account(@account)
|
50
|
+
@account.instances.should_not be_empty
|
51
|
+
@account.instances.first.class.name.should == "AWSTracker::Instance"
|
52
|
+
@account.instances.first.account.should == @account
|
53
|
+
end
|
54
|
+
|
55
|
+
# WARNING: This test could fail if an instance changes state during the test
|
56
|
+
it "should update existing records rather than overwriting them" do
|
57
|
+
@account.instances.clear
|
58
|
+
Instance.refresh_from_account(@account)
|
59
|
+
first_instance = @account.instances.first
|
60
|
+
id = first_instance.id
|
61
|
+
original_state = first_instance.instance_state
|
62
|
+
first_instance.instance_state = "XXXXXXXX"
|
63
|
+
first_instance.save
|
64
|
+
Instance.find(id).instance_state.should == "XXXXXXXX"
|
65
|
+
Instance.refresh_from_account(@account)
|
66
|
+
Instance.find(id).instance_state.should == original_state
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should update the security group relationships as well" do
|
70
|
+
@account.instances.clear
|
71
|
+
@account.update_security_groups
|
72
|
+
Instance.refresh_from_account(@account)
|
73
|
+
@account.instances.should_not be_empty
|
74
|
+
instance = @account.instances.find(:first,
|
75
|
+
:conditions => { :instance_state => "running"})
|
76
|
+
instance.security_groups.should_not be_empty
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#update_security_groups" do
|
81
|
+
it "resets the security_groups given a list of group names" do
|
82
|
+
SecurityGroup.delete_all
|
83
|
+
group = @account.security_groups.create!({
|
84
|
+
:name => "fake_name",
|
85
|
+
:owner => "fake_owner",
|
86
|
+
:description => "fake_description",
|
87
|
+
})
|
88
|
+
@instance.update_security_groups(["fake_name"])
|
89
|
+
@instance.security_groups.count.should == 1
|
90
|
+
@instance.security_groups.first.name.should == "fake_name"
|
91
|
+
@instance.security_groups.first.owner.should == "fake_owner"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module AWSTracker
|
4
|
+
|
5
|
+
describe SecurityGroup do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@account = get_memory_resident_account
|
9
|
+
@account.save!
|
10
|
+
@group = @account.security_groups.create!({
|
11
|
+
:name => "fake_name",
|
12
|
+
:owner => "fake_owner",
|
13
|
+
:description => "fake_description",
|
14
|
+
})
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) do
|
18
|
+
@account.destroy
|
19
|
+
end
|
20
|
+
|
21
|
+
it "is valid with valid attributes" do
|
22
|
+
@group.should be_valid
|
23
|
+
end
|
24
|
+
|
25
|
+
it "is not valid without an account" do
|
26
|
+
@group.account = nil
|
27
|
+
@group.should_not be_valid
|
28
|
+
end
|
29
|
+
|
30
|
+
it "is not valid without a name" do
|
31
|
+
@group.name = nil
|
32
|
+
@group.should_not be_valid
|
33
|
+
end
|
34
|
+
|
35
|
+
it "is not valid without an owner" do
|
36
|
+
@group.owner = nil
|
37
|
+
@group.should_not be_valid
|
38
|
+
end
|
39
|
+
|
40
|
+
it "is not valid without a description" do
|
41
|
+
@group.description = nil
|
42
|
+
@group.should_not be_valid
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#refresh_from_account" do
|
46
|
+
it "should fetch a list of Security Groups from AWS" do
|
47
|
+
@account.security_groups.delete_all
|
48
|
+
@account.security_groups.should be_empty
|
49
|
+
SecurityGroup.refresh_from_account(@account)
|
50
|
+
@account.security_groups.should_not be_empty
|
51
|
+
@account.security_groups.first.class.name.should == "AWSTracker::SecurityGroup"
|
52
|
+
@account.security_groups.first.account.should == @account
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should update existing records rather than overwriting them" do
|
56
|
+
@account.security_groups.delete_all
|
57
|
+
@account.security_groups.should be_empty
|
58
|
+
SecurityGroup.refresh_from_account(@account)
|
59
|
+
first_group = @account.security_groups.first
|
60
|
+
id = first_group.id
|
61
|
+
original_description = first_group.description
|
62
|
+
first_group.description = "XXXXXXXX"
|
63
|
+
first_group.save
|
64
|
+
SecurityGroup.find(id).description.should == "XXXXXXXX"
|
65
|
+
SecurityGroup.refresh_from_account(@account)
|
66
|
+
SecurityGroup.find(id).description.should == original_description
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module AWSTracker
|
4
|
+
|
5
|
+
describe Tag do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@account = get_memory_resident_account
|
9
|
+
@account.save!
|
10
|
+
@tag = @account.tags.create({
|
11
|
+
:key => "fake_key",
|
12
|
+
:value => "fake_value",
|
13
|
+
:resource_type => "fake_type",
|
14
|
+
:resource_id => "fake_aws_id",
|
15
|
+
})
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:each) do
|
19
|
+
@account.destroy
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is valid with valid attributes" do
|
23
|
+
@tag.should be_valid
|
24
|
+
end
|
25
|
+
|
26
|
+
it "is not valid without an account" do
|
27
|
+
@tag.account = nil
|
28
|
+
@tag.should_not be_valid
|
29
|
+
end
|
30
|
+
|
31
|
+
it "is not valid without a key" do
|
32
|
+
@tag.key = nil
|
33
|
+
@tag.should_not be_valid
|
34
|
+
end
|
35
|
+
|
36
|
+
it "is not valid without a resource type" do
|
37
|
+
@tag.resource_type = nil
|
38
|
+
@tag.should_not be_valid
|
39
|
+
end
|
40
|
+
|
41
|
+
it "is not valid without a resource ID" do
|
42
|
+
@tag.resource_id = nil
|
43
|
+
@tag.should_not be_valid
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#refresh_from_account" do
|
47
|
+
it "should fetch a list of Tags from AWS" do
|
48
|
+
@account.tags.delete_all
|
49
|
+
@account.tags.should be_empty
|
50
|
+
Instance.refresh_from_account(@account)
|
51
|
+
EBSVolume.refresh_from_account(@account)
|
52
|
+
Tag.refresh_from_account(@account)
|
53
|
+
@account.tags.should_not be_empty
|
54
|
+
@account.tags.first.should be_valid
|
55
|
+
@account.tags.first.account.should == @account
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should update existing records rather than overwriting them" do
|
59
|
+
@account.tags.delete_all
|
60
|
+
@account.tags.should be_empty
|
61
|
+
Instance.refresh_from_account(@account)
|
62
|
+
EBSVolume.refresh_from_account(@account)
|
63
|
+
Tag.refresh_from_account(@account)
|
64
|
+
first_tag = @account.tags.first
|
65
|
+
id = first_tag.id
|
66
|
+
original_value = first_tag.value
|
67
|
+
first_tag.value = "XXXXXXXX"
|
68
|
+
first_tag.save
|
69
|
+
Tag.find(id).value.should == "XXXXXXXX"
|
70
|
+
Tag.refresh_from_account(@account)
|
71
|
+
Tag.find(id).value.should == original_value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module AWSTracker
|
4
|
+
|
5
|
+
describe Tracker do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@account = get_memory_resident_account
|
9
|
+
@account.save!
|
10
|
+
@tracker = Tracker.new(:logger => @account.log)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have a log object for reporting its workings" do
|
14
|
+
@tracker.log.should_not == nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should load AwsAccounts from the database at initialization" do
|
18
|
+
@tracker.accounts.should_not be_empty
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#load_aws_acounts" do
|
22
|
+
it "should load AwsAccounts from the database" do
|
23
|
+
@tracker.load_aws_acounts
|
24
|
+
@tracker.accounts.should_not be_empty
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#update_status" do
|
29
|
+
it "should update the resources for the requested accounts" do
|
30
|
+
@tracker.accounts.should_not be_empty
|
31
|
+
@tracker.update_status
|
32
|
+
@tracker.accounts.each do |account|
|
33
|
+
account.security_groups.should_not be_empty
|
34
|
+
account.instances.should_not be_empty
|
35
|
+
account.ebs_volumes.should_not be_empty
|
36
|
+
account.tags.should_not be_empty
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#describe "#start" do
|
42
|
+
# it "should periodically update the status for all accounts"
|
43
|
+
#end
|
44
|
+
#
|
45
|
+
#describe "#stop" do
|
46
|
+
# it "should stop automatic status updates"
|
47
|
+
#end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|