sw-collector: Added --installed/removed options

This commit is contained in:
Andreas Steffen
2017-08-03 09:02:54 +02:00
parent 8f63a36b34
commit bea3f5d07f
5 changed files with 109 additions and 43 deletions
+16 -3
View File
@@ -15,7 +15,14 @@ sw-collector \- Extracts software installation events from dpkg history log
.SY "sw-collector" .SY "sw-collector"
.OP \-\-debug level .OP \-\-debug level
.OP \-\-quiet .OP \-\-quiet
.BR \-\-list |\fB\-\-unregistered\fR|\fB\-\-generate\fR|\fB\-\-migrate .OP \-\-installed\fR|\fB\--removed
.BR \-\-list |\fB\-\-unregistered\fR|\fB\-\-generate
.YS
.
.SY "sw-collector"
.OP \-\-debug level
.OP \-\-quiet
.BR \-\-migrate
.YS .YS
. .
.SY "sw-collector" .SY "sw-collector"
@@ -44,6 +51,12 @@ Set debug level, default: 2.
.B "\-q, \-\-quiet .B "\-q, \-\-quiet
Disable debug output to stderr. Disable debug output to stderr.
.TP .TP
.B "\-i, \-\-installed
Apply command to installed software packages, only.
.TP
.B "\-r, \-\-removed
Apply command to removed software packages, only.
.TP
.B "\-l, \-\-list .B "\-l, \-\-list
Lists all software packages stored in the collector database showing their Lists all software packages stored in the collector database showing their
installation status. installation status.
@@ -54,8 +67,8 @@ which no SWID tags exist yet in a central collector database reachable via a
REST interface. REST interface.
.TP .TP
.B "\-g, \-\-generate .B "\-g, \-\-generate
Generates minimal SWID tags for all deleted software packages residing in the Generates minimal SWID tags for all software packages residing in the local
local collector database but for which no SWID tags exist in a central collector collector database but for which no SWID tags exist in a central collector
database reachable via a REST interface. database reachable via a REST interface.
.TP .TP
.B "\-m, \-\-migrate .B "\-m, \-\-migrate
+86 -33
View File
@@ -116,16 +116,19 @@ static void usage(void)
Usage:\n\ Usage:\n\
sw-collector --help\n\ sw-collector --help\n\
sw-collector [--debug <level>] [--quiet] [--count <event count>]\n\ sw-collector [--debug <level>] [--quiet] [--count <event count>]\n\
sw-collector [--debug <level>] [--quiet] --list|-unregistered\n\ sw-collector [--debug <level>] [--quiet] [--installed|--removed] \
sw-collector [--debug <level>] [--quiet] ---generate|--migrate\n"); --list|-unregistered|--generate\n\
sw-collector [--debug <level>] [--quiet] --migrate\n");
} }
/** /**
* Parse command line options * Parse command line options
*/ */
static collector_op_t do_args(int argc, char *argv[]) static collector_op_t do_args(int argc, char *argv[],
sw_collector_db_query_t *query_type)
{ {
collector_op_t op = COLLECTOR_OP_EXTRACT; collector_op_t op = COLLECTOR_OP_EXTRACT;
bool installed = FALSE, removed = FALSE;
/* reinit getopt state */ /* reinit getopt state */
optind = 0; optind = 0;
@@ -139,14 +142,16 @@ static collector_op_t do_args(int argc, char *argv[])
{ "count", required_argument, NULL, 'c' }, { "count", required_argument, NULL, 'c' },
{ "debug", required_argument, NULL, 'd' }, { "debug", required_argument, NULL, 'd' },
{ "generate", no_argument, NULL, 'g' }, { "generate", no_argument, NULL, 'g' },
{ "installed", no_argument, NULL, 'i' },
{ "list", no_argument, NULL, 'l' }, { "list", no_argument, NULL, 'l' },
{ "migrate", no_argument, NULL, 'm' }, { "migrate", no_argument, NULL, 'm' },
{ "quiet", no_argument, NULL, 'q' }, { "quiet", no_argument, NULL, 'q' },
{ "removed", no_argument, NULL, 'r' },
{ "unregistered", no_argument, NULL, 'u' }, { "unregistered", no_argument, NULL, 'u' },
{ 0,0,0,0 } { 0,0,0,0 }
}; };
c = getopt_long(argc, argv, "hc:d:lmqu", long_opts, NULL); c = getopt_long(argc, argv, "hc:d:gilmqru", long_opts, NULL);
switch (c) switch (c)
{ {
case EOF: case EOF:
@@ -164,6 +169,9 @@ static collector_op_t do_args(int argc, char *argv[])
case 'g': case 'g':
op = COLLECTOR_OP_GENERATE; op = COLLECTOR_OP_GENERATE;
continue; continue;
case 'i':
installed = TRUE;
continue;
case 'l': case 'l':
op = COLLECTOR_OP_LIST; op = COLLECTOR_OP_LIST;
continue; continue;
@@ -173,6 +181,9 @@ static collector_op_t do_args(int argc, char *argv[])
case 'q': case 'q':
stderr_quiet = TRUE; stderr_quiet = TRUE;
continue; continue;
case 'r':
removed = TRUE;
continue;
case 'u': case 'u':
op = COLLECTOR_OP_UNREGISTERED; op = COLLECTOR_OP_UNREGISTERED;
continue; continue;
@@ -182,6 +193,18 @@ static collector_op_t do_args(int argc, char *argv[])
} }
break; break;
} }
if ((!installed && !removed) || (installed && removed))
{
*query_type = SW_QUERY_ALL;
}
else if (installed)
{
*query_type = SW_QUERY_INSTALLED;
}
else
{
*query_type = SW_QUERY_REMOVED;
}
return op; return op;
} }
@@ -337,13 +360,13 @@ end:
/** /**
* List all endpoint software identifiers stored in local collector database * List all endpoint software identifiers stored in local collector database
*/ */
static int list_identifiers(sw_collector_db_t *db) static int list_identifiers(sw_collector_db_t *db, sw_collector_db_query_t type)
{ {
enumerator_t *e; enumerator_t *e;
char *name, *package, *version; char *name, *package, *version;
uint32_t sw_id, count = 0, installed_count = 0, installed; uint32_t sw_id, count = 0, installed_count = 0, removed_count, installed;
e = db->create_sw_enumerator(db, SW_QUERY_ALL, NULL); e = db->create_sw_enumerator(db, type, NULL);
if (!e) if (!e)
{ {
return EXIT_FAILURE; return EXIT_FAILURE;
@@ -357,9 +380,22 @@ static int list_identifiers(sw_collector_db_t *db)
} }
count++; count++;
} }
removed_count = count - installed_count;
e->destroy(e); e->destroy(e);
DBG1(DBG_IMC, "retrieved %u software identities with %u installed and %u "
"deleted", count, installed_count, count - installed_count); switch (type)
{
case SW_QUERY_ALL:
DBG1(DBG_IMC, "retrieved %u software identities with %u installed "
"and %u removed", count, installed_count, removed_count);
break;
case SW_QUERY_INSTALLED:
DBG1(DBG_IMC, "retrieved %u installed software identities", count);
break;
case SW_QUERY_REMOVED:
DBG1(DBG_IMC, "retrieved %u removed software identities", count);
break;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@@ -371,7 +407,7 @@ static bool query_registry(sw_collector_rest_api_t *rest_api, bool installed)
char *sw_id; char *sw_id;
int count = 0; int count = 0;
type = installed ? SW_QUERY_INSTALLED : SW_QUERY_DELETED; type = installed ? SW_QUERY_INSTALLED : SW_QUERY_REMOVED;
enumerator = rest_api->create_sw_enumerator(rest_api, type); enumerator = rest_api->create_sw_enumerator(rest_api, type);
if (!enumerator) if (!enumerator)
{ {
@@ -384,7 +420,7 @@ static bool query_registry(sw_collector_rest_api_t *rest_api, bool installed)
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
DBG1(DBG_IMC, "%d %s software identifiers not registered", count, DBG1(DBG_IMC, "%d %s software identifiers not registered", count,
installed ? "installed" : "deleted"); installed ? "installed" : "removed");
return TRUE; return TRUE;
} }
@@ -393,7 +429,8 @@ static bool query_registry(sw_collector_rest_api_t *rest_api, bool installed)
* List all endpoint software identifiers stored in local collector database * List all endpoint software identifiers stored in local collector database
* that are not registered yet in central collelector database * that are not registered yet in central collelector database
*/ */
static int unregistered_identifiers(sw_collector_db_t *db) static int unregistered_identifiers(sw_collector_db_t *db,
sw_collector_db_query_t type)
{ {
sw_collector_rest_api_t *rest_api; sw_collector_rest_api_t *rest_api;
int status = EXIT_SUCCESS; int status = EXIT_SUCCESS;
@@ -405,13 +442,13 @@ static int unregistered_identifiers(sw_collector_db_t *db)
} }
/* List installed software identifiers not registered centrally */ /* List installed software identifiers not registered centrally */
if (!query_registry(rest_api, TRUE)) if (type != SW_QUERY_REMOVED && !query_registry(rest_api, TRUE))
{ {
status = EXIT_FAILURE; status = EXIT_FAILURE;
} }
/* List deleted software identifiers not registered centrally */ /* List removed software identifiers not registered centrally */
if (!query_registry(rest_api, FALSE)) if (type != SW_QUERY_INSTALLED && !query_registry(rest_api, FALSE))
{ {
status = EXIT_FAILURE; status = EXIT_FAILURE;
} }
@@ -450,15 +487,17 @@ static char* generate_tag(char *name, char *package, char *version,
/** /**
* Generate a minimalistic ISO 19770-2:2015 SWID tag for * Generate a minimalistic ISO 19770-2:2015 SWID tag for
* all deleted SW identifiers that are not registered centrally * all removed SW identifiers that are not registered centrally
*/ */
static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db) static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db,
sw_collector_db_query_t type)
{ {
sw_collector_rest_api_t *rest_api; sw_collector_rest_api_t *rest_api;
char *pos, *name, *package, *version, *entity, *regid, *product, *tag; char *name, *package, *version, *entity, *regid, *product, *tag;
enumerator_t *enumerator; enumerator_t *enumerator;
uint32_t sw_id; uint32_t sw_id;
int status = EXIT_FAILURE; bool installed;
int count = 0, installed_count = 0, status = EXIT_FAILURE;
entity = lib->settings->get_str(lib->settings, "%s.tag_creator.name", entity = lib->settings->get_str(lib->settings, "%s.tag_creator.name",
"strongSwan Project", lib->ns); "strongSwan Project", lib->ns);
@@ -472,28 +511,26 @@ static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db)
goto end; goto end;
} }
enumerator = rest_api->create_sw_enumerator(rest_api, SW_QUERY_DELETED); enumerator = rest_api->create_sw_enumerator(rest_api, type);
if (!enumerator) if (!enumerator)
{ {
goto end; goto end;
} }
while (enumerator->enumerate(enumerator, &name)) while (enumerator->enumerate(enumerator, &name))
{ {
sw_id = db->get_sw_id(db, name, &package, &version, NULL, NULL); sw_id = db->get_sw_id(db, name, &package, &version, NULL, &installed);
if (sw_id) if (sw_id)
{ {
/* Remove architecture from package name */
pos = strchr(package, ':');
if (pos)
{
*pos = '\0';
}
tag = generate_tag(name, package, version, entity, regid, product); tag = generate_tag(name, package, version, entity, regid, product);
if (tag) if (tag)
{ {
printf("%s\n", tag); printf("%s\n", tag);
free(tag); free(tag);
count++; count++;
if (installed)
{
installed_count++;
}
} }
free(package); free(package);
free(version); free(version);
@@ -501,8 +538,23 @@ static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db)
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
status = EXIT_SUCCESS; status = EXIT_SUCCESS;
DBG1(DBG_IMC, "%d tags for deleted unregistered software identifiers",
count); switch (type)
{
case SW_QUERY_ALL:
DBG1(DBG_IMC, "%d tags for unregistered software identifiers with "
"%d installed and %d removed", count, installed_count,
count - installed_count);
break;
case SW_QUERY_INSTALLED:
DBG1(DBG_IMC, "%d tags for unregistered installed software "
"identifiers", count);
break;
case SW_QUERY_REMOVED:
DBG1(DBG_IMC, "%d tags for unregistered removed software "
"identifiers", count);
break;
}
end: end:
DESTROY_IF(rest_api); DESTROY_IF(rest_api);
@@ -560,12 +612,13 @@ static int migrate(sw_collector_info_t *info, sw_collector_db_t *db)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
sw_collector_db_t *db = NULL; sw_collector_db_t *db = NULL;
sw_collector_db_query_t query_type;
sw_collector_info_t *info; sw_collector_info_t *info;
collector_op_t op; collector_op_t op;
char *uri, *tag_creator; char *uri, *tag_creator;
int status = EXIT_FAILURE; int status = EXIT_FAILURE;
op = do_args(argc, argv); op = do_args(argc, argv, &query_type);
/* enable sw_collector debugging hook */ /* enable sw_collector debugging hook */
dbg = sw_collector_dbg; dbg = sw_collector_dbg;
@@ -613,13 +666,13 @@ int main(int argc, char *argv[])
status = extract_history(info, db); status = extract_history(info, db);
break; break;
case COLLECTOR_OP_LIST: case COLLECTOR_OP_LIST:
status = list_identifiers(db); status = list_identifiers(db, query_type);
break; break;
case COLLECTOR_OP_UNREGISTERED: case COLLECTOR_OP_UNREGISTERED:
status = unregistered_identifiers(db); status = unregistered_identifiers(db, query_type);
break; break;
case COLLECTOR_OP_GENERATE: case COLLECTOR_OP_GENERATE:
status = generate_tags(info, db); status = generate_tags(info, db, query_type);
break; break;
case COLLECTOR_OP_MIGRATE: case COLLECTOR_OP_MIGRATE:
status = migrate(info, db); status = migrate(info, db);
+4 -4
View File
@@ -32,7 +32,7 @@ typedef enum sw_collector_db_query_t sw_collector_db_query_t;
enum sw_collector_db_query_t { enum sw_collector_db_query_t {
SW_QUERY_ALL, SW_QUERY_ALL,
SW_QUERY_INSTALLED, SW_QUERY_INSTALLED,
SW_QUERY_DELETED SW_QUERY_REMOVED
}; };
/** /**
@@ -97,9 +97,9 @@ struct sw_collector_db_t {
char **version, uint8_t *source, bool *installed); char **version, uint8_t *source, bool *installed);
/** /**
* Get number of installed or deleted software identifiers * Get number of installed or removed software identifiers
* *
* @param type Query type (ALL, INSTALLED, DELETED) * @param type Query type (ALL, INSTALLED, REMOVED)
* @return Count * @return Count
*/ */
uint32_t (*get_sw_id_count)(sw_collector_db_t *this, uint32_t (*get_sw_id_count)(sw_collector_db_t *this,
@@ -130,7 +130,7 @@ struct sw_collector_db_t {
/** /**
* Enumerate over all collected [installed] software identities * Enumerate over all collected [installed] software identities
* *
* @param type Query type (ALL, INSTALLED, DELETED) * @param type Query type (ALL, INSTALLED, REMOVED)
* @param package If not NULL enumerate over all package versions * @param package If not NULL enumerate over all package versions
* @return Enumerator * @return Enumerator
*/ */
+2 -2
View File
@@ -329,7 +329,7 @@ METHOD(sw_collector_history_t, extract_packages, bool,
} }
if (sw_id) if (sw_id)
{ {
/* sw identifier exists - update state to 'deleted' */ /* sw identifier exists - update state to 'removed' */
if (!this->db->update_sw_id(this->db, sw_id, NULL, NULL, FALSE)) if (!this->db->update_sw_id(this->db, sw_id, NULL, NULL, FALSE))
{ {
goto end; goto end;
@@ -337,7 +337,7 @@ METHOD(sw_collector_history_t, extract_packages, bool,
} }
else else
{ {
/* new sw identifier - create with state 'deleted' */ /* new sw identifier - create with state 'removed' */
sw_id = this->db->set_sw_id(this->db, del_sw_id, p->package, sw_id = this->db->set_sw_id(this->db, del_sw_id, p->package,
del_version, this->source, FALSE); del_version, this->source, FALSE);
+1 -1
View File
@@ -34,7 +34,7 @@ struct sw_collector_rest_api_t {
* List of locally stored software identifiers that are not registered * List of locally stored software identifiers that are not registered
* in a central collector database * in a central collector database
* *
* @param type Query type (ALL, INSTALLED, DELETED) * @param type Query type (ALL, INSTALLED, REMOVED)
* @return Enumerator * @return Enumerator
*/ */
enumerator_t* (*create_sw_enumerator)(sw_collector_rest_api_t *this, enumerator_t* (*create_sw_enumerator)(sw_collector_rest_api_t *this,