diff --git a/CHANGES.rst b/CHANGES.rst index a9493ebe..19f19ed4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,11 @@ Changelog ========= +6.1.6 (2019-04-19) +------------------ + +* `PR #402 `__ - Add ``--skip-check`` command line option for ignoring specific checks based on service and check name. Thanks to `@ddelnano `__. + 6.1.5 (2019-03-06) ------------------ diff --git a/awslimitchecker/runner.py b/awslimitchecker/runner.py index 03a71921..a4696255 100644 --- a/awslimitchecker/runner.py +++ b/awslimitchecker/runner.py @@ -68,6 +68,7 @@ def __init__(self): self.checker = None self.skip_ta = False self.service_name = None + self.skip_check = [] def parse_args(self, argv): """ @@ -105,6 +106,10 @@ def parse_args(self, argv): dest='skip_service', help='avoid performing actions for the specified service' ' name; see -s|--list-services for valid names') + p.add_argument('--skip-check', action='append', default=[], + dest='skip_check', + help='avoid performing actions for the specified check' + ' name') p.add_argument('-s', '--list-services', action='store_true', default=False, help='print a list of all AWS service types that ' @@ -311,6 +316,13 @@ def check_thresholds(self): columns = {} for svc in sorted(problems.keys()): for lim_name in sorted(problems[svc].keys()): + check_name = "{svc}/{limit}".format( + svc=svc, + limit=lim_name, + ) + if check_name in self.skip_check: + continue + limit = problems[svc][lim_name] warns = limit.get_warnings() crits = limit.get_criticals() @@ -382,6 +394,10 @@ def console_entry_point(self): if len(args.skip_service) > 0: self.checker.remove_services(args.skip_service) + if len(args.skip_check) > 0: + for check in args.skip_check: + self.skip_check.append(check) + if len(args.limit) > 0: self.set_limit_overrides(args.limit) diff --git a/awslimitchecker/tests/test_runner.py b/awslimitchecker/tests/test_runner.py index 010ac375..700b12f7 100644 --- a/awslimitchecker/tests/test_runner.py +++ b/awslimitchecker/tests/test_runner.py @@ -98,6 +98,7 @@ def test_init(self): assert self.cls.checker is None assert self.cls.skip_ta is False assert self.cls.service_name is None + assert len(self.cls.skip_check) == 0 def test_parse_args(self): argv = ['-V'] @@ -132,6 +133,10 @@ def test_parse_args_parser(self): help='avoid performing actions for the ' 'specified service name; see ' '-s|--list-services for valid names'), + call().add_argument('--skip-check', action='append', + dest='skip_check', default=[], + help='avoid performing actions for the ' + 'specified check name'), call().add_argument('-s', '--list-services', default=False, action='store_true', help='print a list of all AWS service types ' @@ -285,6 +290,24 @@ def test_parse_args_skip_service_multiple(self): res = self.cls.parse_args(argv) assert res.skip_service == ['foo', 'bar', 'baz'] + def test_parse_args_skip_check(self): + argv = [ + '--skip-check', 'EC2/Running On-Demand x1e.8xlarge instances', + ] + res = self.cls.parse_args(argv) + assert res.skip_check == ['EC2/Running On-Demand x1e.8xlarge instances'] + + def test_parse_args_skip_check_multiple(self): + argv = [ + '--skip-check', 'EC2/Running On-Demand x1e.8xlarge instances', + '--skip-check', 'EC2/Running On-Demand c5.9xlarge instances', + ] + res = self.cls.parse_args(argv) + assert res.skip_check == [ + 'EC2/Running On-Demand x1e.8xlarge instances', + 'EC2/Running On-Demand c5.9xlarge instances', + ] + def test_entry_version(self, capsys): argv = ['awslimitchecker', '-V'] expected = 'awslimitchecker ver (see for source code)\n' @@ -542,6 +565,56 @@ def test_entry_skip_service_multi(self): call().remove_services(['foo', 'bar']) ] + def test_entry_skip_check(self): + argv = [ + 'awslimitchecker', + '--skip-check=EC2/Max launch specifications per spot fleet' + ] + with patch.object(sys, 'argv', argv): + with patch('%s.Runner.check_thresholds' % pb, + autospec=True) as mock_check: + mock_check.return_value = 2 + with patch('%s.AwsLimitChecker' % pb, autospec=True) as mock_c: + with pytest.raises(SystemExit) as excinfo: + self.cls.console_entry_point() + assert excinfo.value.code == 2 + assert mock_c.mock_calls == [ + call(account_id=None, account_role=None, critical_threshold=99, + external_id=None, mfa_serial_number=None, mfa_token=None, + profile_name=None, region=None, ta_refresh_mode=None, + ta_refresh_timeout=None, warning_threshold=80, + check_version=True), + ] + assert self.cls.skip_check == [ + 'EC2/Max launch specifications per spot fleet', + ] + + def test_entry_skip_check_multi(self): + argv = [ + 'awslimitchecker', + '--skip-check=EC2/Max launch specifications per spot fleet', + '--skip-check', 'EC2/Running On-Demand i3.large instances', + ] + with patch.object(sys, 'argv', argv): + with patch('%s.Runner.check_thresholds' % pb, + autospec=True) as mock_check: + mock_check.return_value = 2 + with patch('%s.AwsLimitChecker' % pb, autospec=True) as mock_c: + with pytest.raises(SystemExit) as excinfo: + self.cls.console_entry_point() + assert excinfo.value.code == 2 + assert mock_c.mock_calls == [ + call(account_id=None, account_role=None, critical_threshold=99, + external_id=None, mfa_serial_number=None, mfa_token=None, + profile_name=None, region=None, ta_refresh_mode=None, + ta_refresh_timeout=None, warning_threshold=80, + check_version=True), + ] + assert self.cls.skip_check == [ + 'EC2/Max launch specifications per spot fleet', + 'EC2/Running On-Demand i3.large instances', + ] + def test_entry_limit(self): argv = ['awslimitchecker', '-L', 'foo=bar'] with patch.object(sys, 'argv', argv): @@ -1051,6 +1124,54 @@ def se_print(cls, s, l, c, w): ] assert res == 2 + def test_check_thresholds_when_skip_check(self): + """lots of problems""" + mock_limit1 = Mock(spec_set=AwsLimit) + type(mock_limit1).name = 'limit1' + mock_w1 = Mock(spec_set=AwsLimitUsage) + mock_limit1.get_warnings.return_value = [mock_w1] + mock_c1 = Mock(spec_set=AwsLimitUsage) + mock_limit1.get_criticals.return_value = [mock_c1] + + mock_limit2 = Mock(spec_set=AwsLimit) + type(mock_limit2).name = 'limit2' + mock_w2 = Mock(spec_set=AwsLimitUsage) + mock_limit2.get_warnings.return_value = [mock_w2] + mock_limit2.get_criticals.return_value = [] + + mock_checker = Mock(spec_set=AwsLimitChecker) + mock_checker.check_thresholds.return_value = { + 'svc1': { + 'limit1': mock_limit1, + 'limit2': mock_limit2, + }, + } + + def se_print(cls, s, l, c, w): + return ('{s}/{l}'.format(s=s, l=l.name), '') + + self.cls.checker = mock_checker + self.cls.skip_check = ['svc1/limit1'] + with patch('awslimitchecker.runner.Runner.print_issue', + autospec=True) as mock_print: + mock_print.side_effect = se_print + with patch('awslimitchecker.runner.dict2cols') as mock_d2c: + mock_d2c.return_value = 'd2cval' + res = self.cls.check_thresholds() + + assert mock_checker.mock_calls == [ + call.check_thresholds(use_ta=True, service=None) + ] + assert mock_print.mock_calls == [ + call(self.cls, 'svc1', mock_limit2, [], [mock_w2]), + ] + assert mock_d2c.mock_calls == [ + call({ + 'svc1/limit2': '', + }) + ] + assert res == 1 + def test_check_thresholds_warn(self): """just warnings""" mock_limit1 = Mock(spec_set=AwsLimit) diff --git a/awslimitchecker/version.py b/awslimitchecker/version.py index 1f576cbc..ff9c8275 100644 --- a/awslimitchecker/version.py +++ b/awslimitchecker/version.py @@ -47,7 +47,7 @@ except ImportError: logger.error("Unable to import versionfinder", exc_info=True) -_VERSION_TUP = (6, 1, 5) +_VERSION_TUP = (6, 1, 6) _VERSION = '.'.join([str(x) for x in _VERSION_TUP]) _PROJECT_URL = 'https://github.com/jantman/awslimitchecker' diff --git a/default) b/default) deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/source/cli_usage.rst b/docs/source/cli_usage.rst index 290c0122..b9973407 100644 --- a/docs/source/cli_usage.rst +++ b/docs/source/cli_usage.rst @@ -26,6 +26,7 @@ use as a Nagios-compatible plugin). (venv)$ awslimitchecker --help usage: awslimitchecker [-h] [-S [SERVICE [SERVICE ...]]] [--skip-service SKIP_SERVICE] [-s] [-l] + [--skip-check SKIP_CHECK] [--list-defaults] [-L LIMIT] [-u] [--iam-policy] [-W WARNING_THRESHOLD] [-C CRITICAL_THRESHOLD] [-P PROFILE_NAME] [-A STS_ACCOUNT_ID] @@ -46,6 +47,8 @@ use as a Nagios-compatible plugin). --skip-service SKIP_SERVICE avoid performing actions for the specified service name; see -s|--list-services for valid names + --skip-check SKIP_CHECK + avoid performing actions for the specified check -s, --list-services print a list of all AWS service types that awslimitchecker knows how to check -l, --list-limits print all AWS effective limits in @@ -235,6 +238,28 @@ For example, you can check usage of all services _except_ for ``Firehose`` and WARNING:awslimitchecker.checker:Skipping service: EC2 ... normal output ... +Disabling Specific Checks ++++++++++++++++++++++++++++ + +The ``--skip-check`` option can be used to completely disable the specified +check name(s). + +For example, you can run all the EC2 service checks except the ``Max launch specifications per spot fleet`` check with the following command: + +.. code-block:: console + + (venv)$ awslimitchecker --skip-check='EC2/Max launch specifications per spot fleet' + ... normal output ... + EC2/Max launch specifications per spot fleet (limit 50) WARNING: sfr-98e516f0-62f8-47ad-ada6-444da23fe6c5=42 + (venv)$ echo $? + 2 + + # With --skip-check + (venv)$ awslimitchecker --skip-check='EC2/Max launch specifications per spot fleet' + ... normal output ... + (venv)$ echo $? + 0 + Checking Usage ++++++++++++++ diff --git a/docs/source/cli_usage.rst.template b/docs/source/cli_usage.rst.template index a1aaafc0..f6483814 100644 --- a/docs/source/cli_usage.rst.template +++ b/docs/source/cli_usage.rst.template @@ -83,6 +83,28 @@ For example, you can check usage of all services _except_ for ``Firehose`` and WARNING:awslimitchecker.checker:Skipping service: EC2 ... normal output ... +Disabling Specific Checks ++++++++++++++++++++++++++++ + +The ``--skip-check`` option can be used to completely disable the specified +check name(s). + +For example, you can run all the EC2 service checks except the ``Max launch specifications per spot fleet`` check with the following command: + +.. code-block:: console + + (venv)$ awslimitchecker --skip-check='EC2/Max launch specifications per spot fleet' + ... normal output ... + EC2/Max launch specifications per spot fleet (limit 50) WARNING: sfr-98e516f0-62f8-47ad-ada6-444da23fe6c5=42 + (venv)$ echo $? + 2 + + # With --skip-check + (venv)$ awslimitchecker --skip-check='EC2/Max launch specifications per spot fleet' + ... normal output ... + (venv)$ echo $? + 0 + Checking Usage ++++++++++++++