Skip to content

Commit

Permalink
fixes #71 - add support for SES service; currently just daily sending…
Browse files Browse the repository at this point in the history
… quota
  • Loading branch information
jantman committed Mar 13, 2016
1 parent d0907e1 commit 9d78c09
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This release requires the following new IAM permissions to function:
* ``rds:DescribeAccountAttributes``
* ``iam:GetAccountSummary``
* ``s3:ListAllMyBuckets``
* ``ses:GetSendQuota``

Issues addressed:

Expand All @@ -22,6 +23,7 @@ Issues addressed:
* `#157 <https://github.com/jantman/awslimitchecker/issues/157>`_ fix for TrustedAdvisor polling multiple times - have TA set an instance variable flag when it updates services after a poll, and skip further polls and updates if the flag is set. Also add an integration test to confirm this.
* `#50 <https://github.com/jantman/awslimitchecker/issues/50>`_ Add support for IAM service with a subset of its limits (Groups, Instance Profiles, Policies, Policy Versions In Use, Roles, Server Certificates, Users), using both limits and usage information from the `GetAccountSummary <http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccountSummary.html>`_ API action. This **requires an additional IAM permission**, ``iam:GetAccountSummary``.
* `#48 <https://github.com/jantman/awslimitchecker/issues/48>`_ Add support for S3 Buckets limit. This **requires an additional IAM permission**, ``s3:ListAllMyBuckets``.
* `#71 <https://github.com/jantman/awslimitchecker/issues/71>`_ Add support for SES service (daily sending limit). This **requires an additional IAM permission**, ``ses:GetSendQuota``.

0.3.2 (2016-03-11)
------------------
Expand Down
1 change: 1 addition & 0 deletions awslimitchecker/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from awslimitchecker.services.rds import _RDSService
from awslimitchecker.services.iam import _IamService
from awslimitchecker.services.s3 import _S3Service
from awslimitchecker.services.ses import _SesService

# dynamically generate the service name to class dict
_services = {}
Expand Down
113 changes: 113 additions & 0 deletions awslimitchecker/services/ses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"""
awslimitchecker/services/ses.py
The latest version of this package is available at:
<https://github.com/jantman/awslimitchecker>
################################################################################
Copyright 2015 Jason Antman <jason@jasonantman.com> <http://www.jasonantman.com>
This file is part of awslimitchecker, also known as awslimitchecker.
awslimitchecker is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
awslimitchecker is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with awslimitchecker. If not, see <http://www.gnu.org/licenses/>.
The Copyright and Authors attributions contained herein may not be removed or
otherwise altered, except to add the Author attribution of a contributor to
this work. (Additional Terms pursuant to Section 7b of the AGPL v3)
################################################################################
While not legally required, I sincerely request that anyone who finds
bugs please submit them at <https://github.com/jantman/pydnstest> or
to me via email, and that you send any contributions or improvements
either as a pull request on GitHub, or to me via email.
################################################################################
AUTHORS:
Jason Antman <jason@jasonantman.com> <http://www.jasonantman.com>
################################################################################
"""

import abc # noqa
import logging

from .base import _AwsService
from ..limit import AwsLimit

logger = logging.getLogger(__name__)


class _SesService(_AwsService):

service_name = 'SES'
api_name = 'ses' # AWS API name to connect to (boto3.client)

def find_usage(self):
"""
Determine the current usage for each limit of this service,
and update corresponding Limit via
:py:meth:`~.AwsLimit._add_current_usage`.
"""
logger.debug("Checking usage for service %s", self.service_name)
self.connect()
for lim in self.limits.values():
lim._reset_usage()
resp = self.conn.get_send_quota()
self.limits['Daily sending quota']._add_current_usage(
resp['SentLast24Hours']
)
self._have_usage = True
logger.debug("Done checking usage.")

def get_limits(self):
"""
Return all known limits for this service, as a dict of their names
to :py:class:`~.AwsLimit` objects.
:returns: dict of limit names to :py:class:`~.AwsLimit` objects
:rtype: dict
"""
if self.limits != {}:
return self.limits
limits = {}
limits['Daily sending quota'] = AwsLimit(
'Daily sending quota',
self,
200,
self.warning_threshold,
self.critical_threshold,
limit_type='AWS::SES::Email',
)
self.limits = limits
return limits

def _update_limits_from_api(self):
"""
Call the service's API action to retrieve limit/quota information, and
update AwsLimit objects in ``self.limits`` with this information.
"""
self.connect()
resp = self.conn.get_send_quota()
self.limits['Daily sending quota']._set_api_limit(resp['Max24HourSend'])

def required_iam_permissions(self):
"""
Return a list of IAM Actions required for this Service to function
properly. All Actions will be shown with an Effect of "Allow"
and a Resource of "*".
:returns: list of IAM Action strings
:rtype: list
"""
return [
"ses:GetSendQuota",
]
130 changes: 130 additions & 0 deletions awslimitchecker/tests/services/test_ses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"""
awslimitchecker/tests/services/test_ses.py
The latest version of this package is available at:
<https://github.com/jantman/awslimitchecker>
################################################################################
Copyright 2015 Jason Antman <jason@jasonantman.com> <http://www.jasonantman.com>
This file is part of awslimitchecker, also known as awslimitchecker.
awslimitchecker is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
awslimitchecker is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with awslimitchecker. If not, see <http://www.gnu.org/licenses/>.
The Copyright and Authors attributions contained herein may not be removed or
otherwise altered, except to add the Author attribution of a contributor to
this work. (Additional Terms pursuant to Section 7b of the AGPL v3)
################################################################################
While not legally required, I sincerely request that anyone who finds
bugs please submit them at <https://github.com/jantman/pydnstest> or
to me via email, and that you send any contributions or improvements
either as a pull request on GitHub, or to me via email.
################################################################################
AUTHORS:
Jason Antman <jason@jasonantman.com> <http://www.jasonantman.com>
################################################################################
"""

import sys
from awslimitchecker.services.ses import _SesService

# https://code.google.com/p/mock/issues/detail?id=249
# py>=3.4 should use unittest.mock not the mock package on pypi
if (
sys.version_info[0] < 3 or
sys.version_info[0] == 3 and sys.version_info[1] < 4
):
from mock import patch, call, Mock
else:
from unittest.mock import patch, call, Mock


pbm = 'awslimitchecker.services.ses' # module patch base
pb = '%s._SesService' % pbm # class patch pase


class Test_SesService(object):

def test_init(self):
"""test __init__()"""
cls = _SesService(21, 43)
assert cls.service_name == 'SES'
assert cls.api_name == 'ses'
assert cls.conn is None
assert cls.warning_threshold == 21
assert cls.critical_threshold == 43

def test_get_limits(self):
cls = _SesService(21, 43)
cls.limits = {}
res = cls.get_limits()
assert sorted(res.keys()) == sorted([
'Daily sending quota',
])
limit = cls.limits['Daily sending quota']
assert limit.service == cls
assert limit.def_warning_threshold == 21
assert limit.def_critical_threshold == 43
assert limit.default_limit == 200

def test_get_limits_again(self):
"""test that existing limits dict is returned on subsequent calls"""
mock_limits = Mock()
cls = _SesService(21, 43)
cls.limits = mock_limits
res = cls.get_limits()
assert res == mock_limits

def test_find_usage(self):
mock_conn = Mock()
mock_conn.get_send_quota.return_value = {
'Max24HourSend': 123.0,
'MaxSendRate': 12.0,
'SentLast24Hours': 122.0
}

with patch('%s.connect' % pb) as mock_connect:
cls = _SesService(21, 43)
cls.conn = mock_conn
assert cls._have_usage is False
cls.find_usage()
assert mock_connect.mock_calls == [call()]
assert cls._have_usage is True
assert mock_conn.mock_calls == [call.get_send_quota()]
assert len(cls.limits['Daily sending quota'].get_current_usage()) == 1
assert cls.limits['Daily sending quota'].get_current_usage()[
0].get_value() == 122.0

def test_update_limits_from_api(self):
mock_conn = Mock()
mock_conn.get_send_quota.return_value = {
'Max24HourSend': 123.0,
'MaxSendRate': 12.0,
'SentLast24Hours': 122.0
}

with patch('%s.connect' % pb) as mock_connect:
cls = _SesService(21, 43)
cls.conn = mock_conn
cls._update_limits_from_api()
assert mock_connect.mock_calls == [call()]
assert mock_conn.mock_calls == [call.get_send_quota()]
assert cls.limits['Daily sending quota'].api_limit == 123.0

def test_required_iam_permissions(self):
cls = _SesService(21, 43)
assert cls.required_iam_permissions() == [
'ses:GetSendQuota'
]
1 change: 1 addition & 0 deletions docs/source/awslimitchecker.services.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ Submodules
awslimitchecker.services.iam
awslimitchecker.services.rds
awslimitchecker.services.s3
awslimitchecker.services.ses
awslimitchecker.services.vpc

7 changes: 7 additions & 0 deletions docs/source/awslimitchecker.services.ses.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
awslimitchecker.services.ses module
===================================

.. automodule:: awslimitchecker.services.ses
:members:
:undoc-members:
:show-inheritance:
11 changes: 6 additions & 5 deletions docs/source/cli_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ View the AWS services currently supported by ``awslimitchecker`` with the
IAM
RDS
S3
SES
VPC
Expand Down Expand Up @@ -194,12 +195,12 @@ using their IDs).
(venv)$ awslimitchecker -u
AutoScaling/Auto Scaling groups 392
AutoScaling/Launch configurations 464
EBS/Active snapshots 13234
EBS/Active snapshots 13235
EBS/Active volumes 1418
EBS/General Purpose (SSD) volume storage (GiB) 39608
(...)
VPC/Rules per network ACL max: acl-bde47dd9=6 (acl-4bd96a2e=4, acl-8190 (...)
VPC/Subnets per VPC max: vpc-c89074a9=32 (vpc-1e5e3c7b=1, vpc-ae7 (...)
VPC/Subnets per VPC max: vpc-c89074a9=32 (vpc-ae7bc5cb=1, vpc-1e5 (...)
VPC/VPCs 9
Expand Down Expand Up @@ -263,9 +264,9 @@ threshold only, and another has crossed the critical threshold):
.. code-block:: console
(venv)$ awslimitchecker --no-color
EBS/Active snapshots (limit 16000) WARNING: 13234
EBS/Active snapshots (limit 16000) WARNING: 13235
EC2/Security groups per VPC (limit 100) CRITICAL: vpc-c89074a9=778
EC2/VPC security groups per elastic network interface (limit 5) CRITICAL: eni-b26a07fc=5, eni-27515 (...)
EC2/VPC security groups per elastic network interface (limit 5) CRITICAL: eni-2751546e=5, eni-b26a0 (...)
ElastiCache/Clusters (limit 50) WARNING: 42
ElastiCache/Nodes (limit 50) WARNING: 42
RDS/DB parameter groups (limit 50) WARNING: 40
Expand All @@ -282,7 +283,7 @@ To set the warning threshold of 50% and a critical threshold of 75% when checkin
(venv)$ awslimitchecker -W 97 --critical=98 --no-color
EC2/Security groups per VPC (limit 100) CRITICAL: vpc-c89074a9=778
EC2/VPC security groups per elastic network interface (limit 5) CRITICAL: eni-b26a07fc=5, eni-ab0ce (...)
EC2/VPC security groups per elastic network interface (limit 5) CRITICAL: eni-2751546e=5, eni-b26a0 (...)
S3/Buckets (limit 100) CRITICAL: 152
Expand Down
1 change: 1 addition & 0 deletions docs/source/iam_policy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ permissions required for it to function correctly:
"rds:DescribeOptionGroups",
"rds:DescribeReservedDBInstances",
"s3:ListAllMyBuckets",
"ses:GetSendQuota",
"support:*",
"trustedadvisor:Describe*"
],
Expand Down
17 changes: 17 additions & 0 deletions docs/source/limits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ updated from Trusted Advisor:

* Storage quota (GB)

* SES

* Daily sending quota

* VPC

* Internet gateways
Expand Down Expand Up @@ -207,6 +211,10 @@ precedence than anything other than explicit limit overrides:

* Subnets per Subnet Group

* SES

* Daily sending quota



.. _limits.checks:
Expand Down Expand Up @@ -381,6 +389,15 @@ Limit Default
Buckets 100
======= ===

SES
++++

============================================ ===
Limit Default
============================================ ===
Daily sending quota :sup:`(TA)` :sup:`(API)` 200
============================================ ===

VPC
++++

Expand Down

0 comments on commit 9d78c09

Please sign in to comment.