lita-spendo 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 529456b3bdf3fc77c3beaa9b53fa8637414df145
4
- data.tar.gz: 43805a4f1e72389fb1cfd734200f98cb25611c77
3
+ metadata.gz: bc4b4aeb89372358c7c9cf749bb1100460133b65
4
+ data.tar.gz: f35e2fc01077fc05be824d154207c8bbe7bb710e
5
5
  SHA512:
6
- metadata.gz: 3541b6ba32df59527cdaa955216f298b50be57dadef8661169fb56e06be5de7aad2da7a2113a236b6588d63e2842c734d6d47f86168919f11ca80e74a5b51cfc
7
- data.tar.gz: a93c84f6d65caf9bab6815b953454f4900074d6792ae0685ee6946919f47b411b37c90eebd5bd5e7c49140e18e7e8b618da6a5842dfcc70aaf479003ef0e99d9
6
+ metadata.gz: a8f027a73e88ef7a89ae731e79e21c216e384c1c8d4ad51c93b6b63fdc74660afbe8a5f548e203531702392cf3d4d1642acb90f240bb75bb500194392bac5072
7
+ data.tar.gz: 7079d9d39d5486cf7715a4bf32e0846239259319aa6f8f03745bc56fa7bbf7025af0741e99e34d861e75ed9751074d15b1a10db349a55e27079cbc668c86c5b9
data/README.md CHANGED
@@ -12,17 +12,29 @@ gem "lita-spendo"
12
12
 
13
13
  ## Configuration
14
14
 
15
- Spendo relies on the aws-sdk gem. You must either specify the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables or, if you are running on EC2, rely on IAM instance roles. The account requires read access to the DynamoDB table holding your billing history.
15
+ Spendo relies on the aws-sdk gem so it requires an AWS account. The account requires read access to the DynamoDB table holding your billing history.
16
16
 
17
17
  ### Required attributes
18
18
 
19
- * `aws_account_id` (String) - Account number for your AWS account
20
19
  * `base_image_url` (String) - Base url for alert images. Images should be named 'n.jpg' where n is the alert level. We suggest increasingly-scary clown photos.
20
+ * `accounts` (Array) - Array of hashes containing account information. Each hash should look like this:
21
+
22
+ ``` ruby
23
+ {
24
+ nickname: 'foo',
25
+ aws_account_id: ENV['AWS_ACCOUNT_ID'],
26
+ aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
27
+ aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
28
+ aws_region: 'us-east-1',
29
+ room: 'shell', # or room JID or whatever
30
+ dynamodb_table: 'BillingHistory'
31
+ }
32
+ ```
21
33
 
22
34
  ### Optional attributes
23
35
 
24
- * `dynamodb_table` (String) - Name of the DynamoDB table containing billing history (defaults to 'BillingHistory')
36
+ * `time_between_polls` (Integer) - Spendo will wait this many seconds between polls to the BillingHistory table. Defaults to one hour (3600 seconds).
25
37
 
26
38
  ## Usage
27
39
 
28
- TODO: Describe the plugin's features and how to use them.
40
+ `lita spendo foo` - display current billing alert level for account foo.
@@ -7,12 +7,16 @@ module Lita
7
7
  attr_accessor :account, :table_name
8
8
 
9
9
  def initialize(params={})
10
+ @aws_access_key_id = params[:aws_access_key_id]
11
+ @aws_secret_access_key = params[:aws_secret_access_key]
12
+ @aws_region = params[:aws_region]
10
13
  @account = params[:aws_account_id]
11
14
  @table_name = params[:dynamodb_table]
12
15
  end
13
16
 
14
17
  def latest
15
- ddb = Aws::DynamoDB::Resource.new()
18
+ credentials = Aws::Credentials.new(@aws_access_key_id, @aws_secret_access_key)
19
+ ddb = Aws::DynamoDB::Resource.new(region: @aws_region, credentials: credentials)
16
20
  table = ddb.table(table_name)
17
21
  opts = {
18
22
  key_condition_expression: 'Account = :account',
@@ -26,69 +30,89 @@ module Lita
26
30
  end
27
31
 
28
32
  class Spendo < Handler
29
-
30
33
  LAST_RECORD_KEY = 'last_record'
31
34
 
32
- config :aws_account_id, type: String
33
- config :dynamodb_table, type: String, default: 'BillingHistory'
34
- config :base_image_url, type: String
35
- config :room, type: String
35
+ config :base_image_url, type: String
36
36
  config :time_between_polls, type: Integer, default: 60*60
37
37
 
38
- route(/^spendo$/, :show, command: true, help: {
39
- "spendo" => "show current billing level"
38
+ # array of hashes, each hash describing a different
39
+ # account to monitor.
40
+ # config.accounts = [
41
+ # {
42
+ # :aws_account_id = 'foo',
43
+ # :dynamodb_table = 'BillingHistory',
44
+ # :room = 'shell',
45
+ # :aws_access_key_id = 'foo',
46
+ # :aws_secret_access_key = 'foo',
47
+ # :nickname = 'foo'
48
+ # }
49
+ # ]
50
+ config :accounts, type: Array
51
+
52
+ route(/^spendo\s+(\S+)$/, :show, command: true, help: {
53
+ "spendo account_name" => "show current billing level for account_name"
40
54
  })
41
55
 
42
- on(:connected) do |payload|
43
- if config.room
44
- # join the alert room
45
- robot.join config.room
56
+ on(:connected) do
57
+ config.accounts.each do |account|
58
+ setup account
59
+ end
60
+ end
61
+
62
+ def setup(account)
63
+ if account[:room]
64
+ robot.join account[:room]
46
65
  end
47
66
 
48
- # set up a timer to poll DynamoDB
49
67
  every(config.time_between_polls) do |timer|
50
- check_for_alerts
68
+ check_for_alerts account
51
69
  end
52
70
  end
53
71
 
54
72
  def show(response)
55
- message, url = create_message
73
+ account_nick = response.match_data[1]
74
+ account = lookup_account account_nick
75
+ message, url = create_message account
56
76
 
57
77
  response.reply message
58
78
  response.reply url
59
79
  end
60
80
 
61
- attr_writer :billing_history
81
+ def create_client(account)
82
+ params = {
83
+ aws_account_id: account[:aws_account_id],
84
+ aws_region: account[:aws_region],
85
+ dynamodb_table: account[:dynamodb_table],
86
+ aws_access_key_id: account[:aws_access_key_id],
87
+ aws_secret_access_key: account[:aws_secret_access_key]
88
+ }
89
+
90
+ BillingHistory.new(params)
91
+ end
62
92
 
63
- def billing_history
64
- if @billing_history.nil?
65
- params = {
66
- aws_account_id: config.aws_account_id,
67
- dynamodb_table: config.dynamodb_table
68
- }
69
- @billing_history = BillingHistory.new(params)
70
- end
71
- @billing_history
93
+ def lookup_account(nickname)
94
+ config.accounts.select {|a| a[:nickname] == nickname }.first
72
95
  end
73
96
 
74
- def create_message
75
- data = billing_history.latest
97
+ def create_message(account)
98
+ client = create_client account
99
+ data = client.latest
76
100
 
77
- account = data['Account']
101
+ account_id = data['Account']
78
102
  current_fees = data['TotalFees'].to_f
79
103
  expected_fees = data['ExpectedFees'].to_f
80
104
  alert_level = data['AlertLevel'].to_i
81
105
  categorized_fees = data['FeesByCategory']
82
106
 
83
107
  message = "The current fees alert threshold has been reached.\n"
84
- message << "\nAccount: #{account}"
108
+ message << "\nAccount: #{account[:nickname]} #{account_id}"
85
109
  message << "\nCurrent fees: $#{current_fees}"
86
110
  message << "\nExpected monthly fees: $#{expected_fees}" # TODO
87
111
  message << "\nFee level is at #{alert_level * 25}% of expected"
88
112
  message << "\n\n Fee Category Breakdown\n\n"
89
113
 
90
- categorized_fees.each_pair do |k,v|
91
- value = v.to_f
114
+ categorized_fees.keys.sort.each do |k|
115
+ value = categorized_fees[k].to_f
92
116
  next if value == 0.0
93
117
  message << "#{k.ljust(20)}: $#{sprintf('%8.2f', value.round(2))}\n"
94
118
  end
@@ -98,16 +122,22 @@ module Lita
98
122
  return [message, url]
99
123
  end
100
124
 
125
+ def account_key(account)
126
+ account[:aws_account_id] + '_' + LAST_RECORD_KEY
127
+ end
128
+
101
129
  # write current data to redis
102
130
  # BigDecimals get saved as strings which fail to
103
131
  # deserialize as integers (but do deserialize as floats)
104
- def save_billing_data(data)
105
- redis.set LAST_RECORD_KEY, data.to_json
132
+ def save_billing_data(account, data)
133
+ key = account_key account
134
+ redis.set key, data.to_json
106
135
  end
107
136
 
108
137
  # read previous data from redis
109
- def load_billing_data
110
- data = redis.get LAST_RECORD_KEY
138
+ def load_billing_data(account)
139
+ key = account_key account
140
+ data = redis.get key
111
141
  return nil if data.nil?
112
142
 
113
143
  JSON.parse(data)
@@ -117,20 +147,21 @@ module Lita
117
147
  previous['AlertLevel'].to_f != current['AlertLevel'].to_f
118
148
  end
119
149
 
120
- def check_for_alerts
150
+ def check_for_alerts(account)
121
151
  log.debug "checking for alerts"
122
- current_data = billing_history.latest
123
- last_data = load_billing_data
152
+ client = create_client account
153
+ current_data = client.latest
154
+ last_data = load_billing_data(account)
124
155
 
125
156
  if last_data && alert_level_changed?(last_data, current_data)
126
- message, url = create_message
127
- target = Source.new(room: config.room)
157
+ message, url = create_message account
158
+ target = Source.new(room: account[:room])
128
159
  robot.send_messages(target, message, url)
129
160
  else
130
161
  log.debug "alert level unchanged"
131
162
  end
132
163
 
133
- save_billing_data current_data
164
+ save_billing_data account, current_data
134
165
  end
135
166
  end
136
167
 
data/lita-spendo.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "lita-spendo"
3
- spec.version = "0.2.0"
3
+ spec.version = "0.3.0"
4
4
  spec.authors = ["Chris Chalfant"]
5
5
  spec.email = ["cchalfant@leafsoftwaresolutions.com"]
6
6
  spec.description = "Lita handler for displaying AWS billing"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita-spendo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Chalfant