aws_tracker 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -7,6 +7,7 @@ pkg/*
7
7
  *.tmproj
8
8
  config/database.yml
9
9
  config/tracker_db.yml
10
+ config/accounts.yml
10
11
  db/*.sqlite3
11
12
  log/*.log
12
13
  tmp/**/*
data/README.md CHANGED
@@ -41,18 +41,25 @@ Usage [from the command line]
41
41
 
42
42
  2) Create the database to contain the data. This is not necessary if using sqlite.
43
43
 
44
- 3) To store your AWS account information in the database, export the credentials as environment variables. This is only needed the first time you run.
44
+ 3) The AWS Account information is stored in a (YAML) configuration file. Name this `accounts.yml` and store it alongside the above `tracker_db.yml` file.
45
45
 
46
- export AWS_ACCOUNT_NUMBER=[your AWS account number]
47
- export AWS_ACCESS_KEY_ID=[your EC2 access key ID]
48
- export AWS_ACCESS_KEY_SECRET=[your EC2 access key secret]
46
+ development account:
47
+ account_id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
48
+ access_key_id: xxxxxxxxxxxxxxxxxxxx
49
+ secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
50
+
51
+ testing account:
52
+ account_id: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
53
+ access_key_id: xxxxxxxxxxxxxxxxxxxx
54
+ secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
55
+
56
+ When the tracker command-line program runs, these accounts are written into the database, but without the secret information. This allows external processes to read the AWS state database safely.
49
57
 
50
58
  4) Run the tracker, and point it at the database config file
51
59
 
52
- tracker tracker_db.yml --migrate --create-account
60
+ tracker tracker_db.yml --migrate
53
61
 
54
- * The `--migrate` argument updates the database to the latest version of the schema, and is only necessary for new databases, or when upgrading to a new version of the Tracker gem.
55
- * The `--create-account` argument stores the above environment values as an AWSAccount object in the tracker database.
62
+ The `--migrate` argument updates the database to the latest version of the schema, and is only necessary for new databases, or when upgrading to a new version of the Tracker gem.
56
63
 
57
64
 
58
65
  ----------------
@@ -77,14 +84,14 @@ Usage [from within Ruby]
77
84
  * AWSTracker::Instance
78
85
  * AWSTracker::EBSVolume
79
86
 
80
- But first, you need to create an AWSAccount, and use a Tracker object to fetch its status from AWS:
87
+ 4) Then load your AWSAccounts from YAML, and use a Tracker object to fetch their status from AWS:
81
88
 
82
- include AWSTracker # Load model class names into namespace
83
- a = AWSAccount.from_memory # Create an account (see command-line usage)
84
- a.save! # Save it in the database
85
- t = Tracker.new # A Tracker updates all accounts in the DB
86
- t.delay = 15 # Update every 15 seconds
87
- t.start # Runs in the background. Call 'stop' later
89
+ include AWSTracker # Load model class names into namespace
90
+ accounts = AWSAccount.from_yaml_file('config/accounts.yml')
91
+ accounts.each {|a| a.save!} # Save them in the database
92
+ t = Tracker.new # A Tracker updates all accounts in the DB
93
+ t.delay = 15 # Update every 15 seconds
94
+ t.start # Runs in the background. Call 'stop' later
88
95
 
89
96
 
90
97
  ----------------
data/aws_tracker.gemspec CHANGED
@@ -29,5 +29,6 @@ Gem::Specification.new do |s|
29
29
  # Development / Test dependencies
30
30
  s.add_development_dependency "rake"
31
31
  s.add_development_dependency "rspec"
32
+ s.add_development_dependency "bundler"
32
33
 
33
34
  end
data/bin/tracker CHANGED
@@ -4,7 +4,7 @@
4
4
  # Monitors one or more AWS accounts and pushes their status into a database.
5
5
  #
6
6
  # == Usage
7
- # tracker.rb [options] DB_CONFIG_FILE.YML
7
+ # tracker.rb [options] DB_CONFIG_FILE.YML [ACCOUNTS.YML]
8
8
  #
9
9
  # == Options (all options can be put into the config file)
10
10
  # -d, --delay [INTEGER] Seconds between status updates. default = 180
@@ -36,11 +36,11 @@ class AWSTrackerConsoleApp
36
36
  }
37
37
  parse_options
38
38
  (@log.error "A database config file must be specified" ; exit) if ARGV.empty?
39
- db_config_file = ARGV.first
40
- @log.info "Loading database configuration from #{db_config_file}"
41
- db_config = YAML::load(File.open(db_config_file))
39
+ @db_config_file = ARGV.first
40
+ @log.info "Loading database configuration from #{@db_config_file}"
41
+ db_config = YAML::load(File.open(@db_config_file))
42
42
  connect_to_database(db_config)
43
- create_account if @opts[:create_account]
43
+ sync_accounts
44
44
  go
45
45
  end
46
46
 
@@ -52,6 +52,23 @@ class AWSTrackerConsoleApp
52
52
  require 'aws_tracker'
53
53
  end
54
54
 
55
+ def sync_accounts
56
+ new_accounts = accounts_from_yaml
57
+ if @opts[:create_account]
58
+ new_accounts << AWSTracker::AWSAccount.from_memory
59
+ end
60
+ existing_accounts = AWSTracker::AWSAccount.all
61
+ new_accounts.each do |a|
62
+ @log.info "Syncing account #{a.name} into database..."
63
+ write_account =
64
+ AWSTracker::AWSAccount.find_or_initialize_by_account_id(a.account_id)
65
+ write_account.name = a.name
66
+ write_account.access_key_id = a.access_key_id
67
+ write_account.secret_access_key = a.secret_access_key
68
+ write_account.save!
69
+ end
70
+ end
71
+
55
72
  def go
56
73
  @tracker = AWSTracker::Tracker.new(:logger => @log)
57
74
  @tracker.delay = @opts[:delay]
@@ -92,11 +109,11 @@ class AWSTrackerConsoleApp
92
109
  ActiveRecord::Migrator.migrate migration_dir
93
110
  end
94
111
 
95
- def create_account
96
- @log.info "Creating account from environment..."
97
- a = AWSTracker::AWSAccount.from_memory
98
- a.log.info "Loaded account #'#{a.account_id}' from memory"
99
- a.save!
112
+ def accounts_from_yaml
113
+ accounts_file = ARGV[1] || File.expand_path(
114
+ File.join(File.dirname(@db_config_file), 'accounts.yml'))
115
+ @log.info "Loading accounts from #{accounts_file}..."
116
+ AWSTracker::AWSAccount.from_yaml_file accounts_file
100
117
  end
101
118
 
102
119
  end
@@ -0,0 +1,9 @@
1
+ development account:
2
+ account_id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3
+ access_key_id: xxxxxxxxxxxxxxxxxxxx
4
+ secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
5
+
6
+ testing account:
7
+ account_id: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8
+ access_key_id: xxxxxxxxxxxxxxxxxxxx
9
+ secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -0,0 +1,14 @@
1
+ class RemoveAwsCreds < ActiveRecord::Migration
2
+ def self.up
3
+ change_table :aws_accounts do |t|
4
+ t.remove :access_key_id, :secret_access_key
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ change_table :aws_accounts do |t|
10
+ t.string :access_key_id
11
+ t.string :secret_access_key
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module AWSTracker
2
+ module Taggable
3
+
4
+ # returns the collection of AWSTracker::Tags as a Hash
5
+ def tag_hash
6
+ Tag.where(:resource_id => self).inject({}) do |hash, tag|
7
+ hash[tag.key] = tag.value
8
+ hash
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -1,15 +1,19 @@
1
1
  require 'right_aws'
2
+ require 'yaml'
2
3
 
3
4
  module AWSTracker
4
5
  class AWSAccount < ActiveRecord::Base
5
6
 
7
+ # Credentials - these must be loaded from YAML or set programmatically
8
+ attr_accessor :access_key_id, :secret_access_key
9
+
6
10
  # Relationships
7
11
  has_many :instances, :dependent => :destroy
8
12
  has_many :security_groups, :dependent => :destroy
9
13
  has_many :ebs_volumes, {:dependent => :destroy, :class_name => 'EBSVolume'}
10
14
  has_many :tags, :dependent => :destroy
11
15
  # Validations
12
- validates_presence_of :account_id, :access_key_id, :secret_access_key
16
+ validates_presence_of :account_id
13
17
  validates_uniqueness_of :name, :account_id
14
18
 
15
19
  # Configure logging
@@ -65,5 +69,18 @@ module AWSTracker
65
69
  end
66
70
  end
67
71
 
72
+ # Returns an Array of AWSAccount objects created from a YAML file
73
+ def self.from_yaml_file(yaml_file)
74
+ account_hash = YAML::load(File.open(yaml_file)).to_hash
75
+ account_hash.map do |name, hash|
76
+ AWSAccount.new({
77
+ :name => name,
78
+ :account_id => hash["account_id"],
79
+ :access_key_id => hash["access_key_id"],
80
+ :secret_access_key => hash["secret_access_key"],
81
+ })
82
+ end
83
+ end
84
+
68
85
  end
69
86
  end
@@ -6,6 +6,7 @@ module AWSTracker
6
6
  :foreign_key => "aws_account_id"
7
7
  belongs_to :instance
8
8
  has_many :tags, :as => :resource, :dependent => :destroy
9
+ include AWSTracker::Taggable
9
10
 
10
11
  validates_presence_of :account, :volume_id, :size, :status
11
12
  validates_uniqueness_of :volume_id
@@ -7,6 +7,7 @@ module AWSTracker
7
7
  has_and_belongs_to_many :security_groups
8
8
  has_many :ebs_volumes, :class_name => 'EBSVolume'
9
9
  has_many :tags, :as => :resource, :dependent => :destroy
10
+ include AWSTracker::Taggable
10
11
 
11
12
  validates_presence_of :account, :instance_id, :image_id, :instance_state
12
13
  validates_uniqueness_of :instance_id
@@ -1,3 +1,3 @@
1
1
  module AwsTracker
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -21,14 +21,13 @@ module AWSTracker
21
21
  @account.should_not be_valid
22
22
  end
23
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
24
+ describe "#from_yaml_file" do
25
+ it "creates an Array of AWSAccounts from a YAML file" do
26
+ yaml_path = '../../../../../config/accounts.yml.example'
27
+ accounts = AWSAccount.from_yaml_file File.expand_path(yaml_path,__FILE__)
28
+ accounts.should_not be_empty
29
+ accounts.first.should be_an_instance_of AWSAccount
30
+ end
32
31
  end
33
32
 
34
33
  describe "#update_instances" do
@@ -47,6 +47,18 @@ module AWSTracker
47
47
  @volume.should_not be_valid
48
48
  end
49
49
 
50
+ describe "#tag_hash" do
51
+ it "should return its Tags as a Hash" do
52
+ @volume.tags.create!({
53
+ :key => "TAG_KEY", :value => "TAG_VALUE",
54
+ :account => @account
55
+ })
56
+ tags = @volume.tag_hash
57
+ tags.should be_an_instance_of(Hash)
58
+ tags["TAG_KEY"].should == "TAG_VALUE"
59
+ end
60
+ end
61
+
50
62
  describe "#refresh_from_account" do
51
63
  it "should fetch a list of EBS Volumes from AWS" do
52
64
  @account.ebs_volumes.delete_all
@@ -43,6 +43,18 @@ module AWSTracker
43
43
  @instance.should_not be_valid
44
44
  end
45
45
 
46
+ describe "#tag_hash" do
47
+ it "should return its Tags as a Hash" do
48
+ @instance.tags.create!({
49
+ :key => "TAG_KEY", :value => "TAG_VALUE",
50
+ :account => @account
51
+ })
52
+ tags = @instance.tag_hash
53
+ tags.should be_an_instance_of(Hash)
54
+ tags["TAG_KEY"].should == "TAG_VALUE"
55
+ end
56
+ end
57
+
46
58
  describe "#refresh_from_account" do
47
59
  it "should fetch a list of Instances from AWS" do
48
60
  @account.instances.clear
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws_tracker
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease: false
4
+ hash: 27
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Benton Roberts
@@ -15,13 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-26 00:00:00 -04:00
19
- default_executable:
18
+ date: 2011-04-28 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
- type: :runtime
23
- prerelease: false
24
21
  name: activerecord
22
+ type: :runtime
25
23
  version_requirements: &id001 !ruby/object:Gem::Requirement
26
24
  none: false
27
25
  requirements:
@@ -31,11 +29,11 @@ dependencies:
31
29
  segments:
32
30
  - 0
33
31
  version: "0"
32
+ prerelease: false
34
33
  requirement: *id001
35
34
  - !ruby/object:Gem::Dependency
36
- type: :runtime
37
- prerelease: false
38
35
  name: right_aws
36
+ type: :runtime
39
37
  version_requirements: &id002 !ruby/object:Gem::Requirement
40
38
  none: false
41
39
  requirements:
@@ -45,11 +43,11 @@ dependencies:
45
43
  segments:
46
44
  - 0
47
45
  version: "0"
46
+ prerelease: false
48
47
  requirement: *id002
49
48
  - !ruby/object:Gem::Dependency
50
- type: :runtime
51
- prerelease: false
52
49
  name: sqlite3
50
+ type: :runtime
53
51
  version_requirements: &id003 !ruby/object:Gem::Requirement
54
52
  none: false
55
53
  requirements:
@@ -59,11 +57,11 @@ dependencies:
59
57
  segments:
60
58
  - 0
61
59
  version: "0"
60
+ prerelease: false
62
61
  requirement: *id003
63
62
  - !ruby/object:Gem::Dependency
64
- type: :development
65
- prerelease: false
66
63
  name: rake
64
+ type: :development
67
65
  version_requirements: &id004 !ruby/object:Gem::Requirement
68
66
  none: false
69
67
  requirements:
@@ -73,11 +71,11 @@ dependencies:
73
71
  segments:
74
72
  - 0
75
73
  version: "0"
74
+ prerelease: false
76
75
  requirement: *id004
77
76
  - !ruby/object:Gem::Dependency
78
- type: :development
79
- prerelease: false
80
77
  name: rspec
78
+ type: :development
81
79
  version_requirements: &id005 !ruby/object:Gem::Requirement
82
80
  none: false
83
81
  requirements:
@@ -87,7 +85,22 @@ dependencies:
87
85
  segments:
88
86
  - 0
89
87
  version: "0"
88
+ prerelease: false
90
89
  requirement: *id005
90
+ - !ruby/object:Gem::Dependency
91
+ name: bundler
92
+ type: :development
93
+ version_requirements: &id006 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ prerelease: false
103
+ requirement: *id006
91
104
  description: This gem peridically queries AWS for information about Instances, SecurityGroups, EBSVolumes, etc., and saves the data as interconnected ActiveRecord objects.aws_tracker
92
105
  email:
93
106
  - benton@bentonroberts.com
@@ -105,6 +118,7 @@ files:
105
118
  - Rakefile
106
119
  - aws_tracker.gemspec
107
120
  - bin/tracker
121
+ - config/accounts.yml.example
108
122
  - config/database.yml.example
109
123
  - db/migrate/20110331145142_create_aws_accounts.rb
110
124
  - db/migrate/20110331152735_create_instances.rb
@@ -112,7 +126,9 @@ files:
112
126
  - db/migrate/20110403060000_create_instance_groups.rb
113
127
  - db/migrate/20110404014218_create_ebs_volumes.rb
114
128
  - db/migrate/20110408193824_create_tags.rb
129
+ - db/migrate/20110427222809_remove_aws_creds.rb
115
130
  - lib/aws_tracker.rb
131
+ - lib/aws_tracker/models/_taggable.rb
116
132
  - lib/aws_tracker/models/aws_account.rb
117
133
  - lib/aws_tracker/models/ebs_volume.rb
118
134
  - lib/aws_tracker/models/instance.rb
@@ -132,7 +148,6 @@ files:
132
148
  - spec/spec_helper.rb
133
149
  - spec/support/_configure_logging.rb
134
150
  - spec/support/create_testing_objects.rb
135
- has_rdoc: true
136
151
  homepage: http://github.com/benton/aws_tracker
137
152
  licenses: []
138
153
 
@@ -162,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
177
  requirements: []
163
178
 
164
179
  rubyforge_project: aws_tracker
165
- rubygems_version: 1.3.7
180
+ rubygems_version: 1.7.2
166
181
  signing_key:
167
182
  specification_version: 3
168
183
  summary: Models the state of Amazon Web Services accounts in ActiveRecord