From bf18dc42dd16811a3e0f42d4591604a4213afb3e Mon Sep 17 00:00:00 2001
From: Christian Schmidt <c960657@users.noreply.github.com>
Date: Thu, 29 Dec 2016 16:09:24 +0100
Subject: [PATCH] Add --only-critical switch to check_apt

---
 plugins/check_apt.c   | 15 ++++++++++++---
 plugins/t/check_apt.t | 18 +++++++++++++++++-
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/plugins/check_apt.c b/plugins/check_apt.c
index a639a41..c90b3df 100644
--- a/plugins/check_apt.c
+++ b/plugins/check_apt.c
@@ -73,6 +73,7 @@ char* add_to_regexp(char *expr, const char *next);
 /* configuration variables */
 static int verbose = 0;      /* -v */
 static int do_update = 0;    /* whether to call apt-get update */
+static int only_critical = 0;    /* whether to warn about non-critical updates */
 static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */
 static char *upgrade_opts = NULL; /* options to override defaults for upgrade */
 static char *update_opts = NULL; /* options to override defaults for update */
@@ -110,7 +111,7 @@ int main (int argc, char **argv) {
 
 	if(sec_count > 0){
 		result = max_state(result, STATE_CRITICAL);
-	} else if(packages_available > 0){
+	} else if(packages_available > 0 && only_critical == 0){
 		result = max_state(result, STATE_WARNING);
 	} else if(result > STATE_UNKNOWN){
 		result = STATE_UNKNOWN;
@@ -148,12 +149,13 @@ int process_arguments (int argc, char **argv) {
 		{"include", required_argument, 0, 'i'},
 		{"exclude", required_argument, 0, 'e'},
 		{"critical", required_argument, 0, 'c'},
+		{"only-critical", no_argument, 0, 'o'},
 		{"input-file", required_argument, 0, INPUT_FILE_OPT},
 		{0, 0, 0, 0}
 	};
 
 	while(1) {
-		c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:", longopts, NULL);
+		c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:o", longopts, NULL);
 
 		if(c == -1 || c == EOF || c == 1) break;
 
@@ -203,6 +205,9 @@ int process_arguments (int argc, char **argv) {
 		case 'c':
 			do_critical=add_to_regexp(do_critical, optarg);
 			break;
+		case 'o':
+			only_critical=1;
+			break;
 		case INPUT_FILE_OPT:
 			input_filename = optarg;
 			break;
@@ -463,7 +468,11 @@ print_help (void)
   printf ("    %s\n", _("upgrades for Debian and Ubuntu:"));
   printf ("    \t\%s\n", SECURITY_RE);
   printf ("    %s\n", _("Note that the package must first match the include list before its"));
-  printf ("    %s\n\n", _("information is compared against the critical list."));
+  printf ("    %s\n", _("information is compared against the critical list."));
+  printf (" %s\n", "-o, --only-critical");
+  printf ("    %s\n", _("Only warn about upgrades matching the critical list.  The total number"));
+  printf ("    %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause"));
+  printf ("    %s\n\n", _("the plugin to return WARNING status."));
 
   printf ("%s\n\n", _("The following options require root privileges and should be used with care:"));
   printf (" %s\n", "-u, --update=OPTS");
diff --git a/plugins/t/check_apt.t b/plugins/t/check_apt.t
index 9ba0ff8..430eb53 100644
--- a/plugins/t/check_apt.t
+++ b/plugins/t/check_apt.t
@@ -23,7 +23,7 @@ sub make_result_regexp {
 }
 
 if (-x "./check_apt") {
-	plan tests => 28;
+	plan tests => 36;
 } else {
 	plan skip_all => "No check_apt compiled";
 }
@@ -40,10 +40,18 @@ $result = NPTest->testCmd( sprintf($testfile_command, "", "debian2") );
 is( $result->return_code, 1, "Debian apt output, warning" );
 like( $result->output, make_result_regexp(13, 0), "Output correct" );
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian2") );
+is( $result->return_code, 0, "Debian apt output, no critical" );
+like( $result->output, make_result_regexp(13, 0), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "", "debian3") );
 is( $result->return_code, 2, "Debian apt output, some critical" );
 like( $result->output, make_result_regexp(19, 4), "Output correct" );
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian3") );
+is( $result->return_code, 2, "Debian apt output, some critical" );
+like( $result->output, make_result_regexp(19, 4), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "-c '^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)'", "debian3") );
 is( $result->return_code, 2, "Debian apt output - should have same result when default security regexp specified via -c" );
 like( $result->output, make_result_regexp(19, 4), "Output correct" );
@@ -52,6 +60,10 @@ $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6", "debian3") );
 is( $result->return_code, 1, "Debian apt output, filter for libc6" );
 like( $result->output, make_result_regexp(3, 0), "Output correct" );
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-i libc6", "debian3") );
+is( $result->return_code, 1, "Debian apt output, filter for libc6, not critical" );
+like( $result->output, make_result_regexp(3, 0), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6 -i xen", "debian3") );
 is( $result->return_code, 2, "Debian apt output, filter for libc6 and xen" );
 like( $result->output, make_result_regexp(9, 4), "Output correct" );
@@ -64,6 +76,10 @@ $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6", "debian3") );
 is( $result->return_code, 2, "Debian apt output, filter out libc6" );
 like( $result->output, make_result_regexp(16, 4), "Output correct" );
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -o", "debian3") );
+is( $result->return_code, 2, "Debian apt output, filter out libc6, critical" );
+like( $result->output, make_result_regexp(16, 4), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -e xen", "debian3") );
 is( $result->return_code, 1, "Debian apt output, filter out libc6 and xen" );
 like( $result->output, make_result_regexp(10, 0), "Output correct" );
