8
8
import zulip
9
9
import yaml
10
10
11
+
11
12
BASEDIR = os .path .dirname (sys .argv [0 ])
12
13
CONFIG_FILE = os .path .join (BASEDIR , 'config.yaml' )
13
14
15
+
16
+ class AWSUsage (object ):
17
+ def __init__ (self , account_id , use_default_session = False ):
18
+ self ._account_id = account_id
19
+ self ._use_default_session = use_default_session
20
+ self ._custom_session = None
21
+ self ._profile_name = 'default'
22
+
23
+ def set_profile_name (self , name ):
24
+ if self ._use_default_session :
25
+ raise RuntimeError ("Cannot set profile name when using default session." )
26
+ self ._profile_name = name
27
+
28
+ def get_monthly_cost (self ):
29
+ client = self ._get_client ('budgets' )
30
+ resp = client .describe_budgets (AccountId = self ._account_id )
31
+ cost = resp ['Budgets' ][0 ]['CalculatedSpend' ]['ActualSpend' ]['Amount' ]
32
+ forecast = resp ['Budgets' ][0 ]['CalculatedSpend' ]['ForecastedSpend' ]['Amount' ]
33
+ return (float (cost ), float (forecast ))
34
+
35
+ def get_server_stats (self ):
36
+ client = self ._get_client ('ec2' )
37
+ resp = client .describe_instances ()
38
+ nserver = 0
39
+ for resv in resp ['Reservations' ]:
40
+ for inst in resv ['Instances' ]:
41
+ if inst ['State' ]['Name' ] != 'terminated' :
42
+ nserver += 1
43
+ return nserver
44
+
45
+ def _get_client (self , name ):
46
+ if self ._use_default_session :
47
+ return boto3 .client (name )
48
+ custom_session = self ._get_custom_session ()
49
+ return custom_session .client (name )
50
+
51
+ def _get_custom_session (self ):
52
+ if self ._custom_session is None :
53
+ self ._custom_session = boto3 .Session (profile_name = self ._profile_name )
54
+ return self ._custom_session
55
+
56
+
14
57
def load_config ():
15
58
with open (CONFIG_FILE ) as fp :
16
59
return yaml .load (fp , Loader = yaml .Loader )
17
60
18
- def get_monthly_cost (config , aws_profile_name ):
19
- session = boto3 .Session (profile_name = aws_profile_name )
20
- client = session .client ("budgets" )
21
- resp = client .describe_budgets (AccountId = config ['aws' ]['account_id' ])
22
- cost = resp ['Budgets' ][0 ]['CalculatedSpend' ]['ActualSpend' ]['Amount' ]
23
- forecast = resp ['Budgets' ][0 ]['CalculatedSpend' ]['ForecastedSpend' ]['Amount' ]
24
- return (float (cost ), float (forecast ))
25
-
26
- def get_server_stats (config , aws_profile_name ):
27
- # TODO Define AWSUsage() class to factor out the boilarplate.
28
- session = boto3 .Session (profile_name = aws_profile_name )
29
- client = session .client ("ec2" )
30
- resp = client .describe_instances ()
31
- nserver = 0
32
- for resv in resp ["Reservations" ]:
33
- for inst in resv ['Instances' ]:
34
- if inst ['State' ]['Name' ] != 'terminated' :
35
- nserver += 1
36
- return nserver
37
-
38
61
def send_message (config , message ):
39
62
client = zulip .Client (site = config ['zulip' ]['site' ],
40
63
email = config ['zulip' ]['email' ],
@@ -53,10 +76,15 @@ def format_message(config, cost, forecast, nserver):
53
76
return template .format (year = today .year , month = today .month , day = today .day ,
54
77
cost = cost , forecast = forecast , nserver = nserver )
55
78
56
- def main (aws_profile_name = " default" , dryrun = False ):
79
+ def main (aws_profile_name = ' default' , use_aws_default_session = False , dryrun = False ):
57
80
config = load_config ()
58
- cost , forecast = get_monthly_cost (config , aws_profile_name )
59
- nserver = get_server_stats (config , aws_profile_name )
81
+
82
+ aws_usage = AWSUsage (config ['aws' ]['account_id' ], use_aws_default_session )
83
+ if not use_aws_default_session :
84
+ aws_usage .set_profile_name (aws_profile_name )
85
+ cost , forecast = aws_usage .get_monthly_cost ()
86
+ nserver = aws_usage .get_server_stats ()
87
+
60
88
message = format_message (config , cost , forecast , nserver )
61
89
if dryrun :
62
90
print (message )
@@ -65,10 +93,12 @@ def main(aws_profile_name = "default", dryrun=False):
65
93
66
94
if __name__ == '__main__' :
67
95
parser = argparse .ArgumentParser ()
68
- parser .add_argument (" --aws-profile" , type = str , default = " default" ,
96
+ parser .add_argument (' --aws-profile' , type = str , default = ' default' ,
69
97
help = "AWS profile name. Default: 'default'." )
70
- parser .add_argument ("--dryrun" , action = 'store_true' ,
98
+ parser .add_argument ('--use-aws-default-session' , action = 'store_true' ,
99
+ help = "Use default session to connect AWS. --aws-profile is ignored." )
100
+ parser .add_argument ('--dryrun' , action = 'store_true' ,
71
101
help = "For debug. Print the message to stdout." )
72
102
args = parser .parse_args ()
73
103
74
- main (args .aws_profile , dryrun = args .dryrun )
104
+ main (args .aws_profile , args . use_aws_default_session , args .dryrun )
0 commit comments