description:'Get the extended osquery schema and documentation supported by Fleet by reading the raw osquery tables and Fleet\'s overrides from disk, then returning the extended set of tables.',
require('assert')(sails.config.custom.versionOfOsquerySchemaToUseWhenGeneratingDocumentation,'Please set sails.config.custom.sails.config.custom.versionOfOsquerySchemaToUseWhenGeneratingDocumentation to the version of osquery to use, for example \'5.8.1\'.');
returnnewError(`When trying to send a request to GitHub get a timestamp of the last commit to the osqeury schema JSON, an error occurred. Full error: ${util.inspect(err)}`);
});
// The value we'll use for the lastModifiedAt timestamp will be date value of the `commiter` property of the `commit` we got in the API response from github.
// Throw an error if the the response from GitHub is missing a commit or commiter.
thrownewError(`When trying to get a lastModifiedAt timestamp for the osqeury schema json, the response from the GitHub API did not include information about the most recent commit. Response from GitHub: ${util.inspect(responseData,{depth:null})}`);
}
rawOsqueryTablesLastModifiedAt=(newDate(mostRecentCommitToOsquerySchema.commit.committer.date)).getTime();// Convert the UTC timestamp from GitHub to a JS timestamp.
thrownewError(`Could not parse the Fleet overrides YAMl at ${yamlSchema} on line ${err.linePos.start.line}. To resolve, make sure the YAML is valid, then try running this script again: `+err.stack);
thrownewError(`Could not merge osquery schema with Fleet overrides. A table in the Fleet overrides schema has an invalid "name" (Expected a string, but instead got a ${typeofparsedYamlTable.name}. To resolve, change the "name" of the table located at ${yamlSchema} to be a string.`);
}
fleetOverridesForTables.push(parsedYamlTable);
}else{// Throw an error if a Fleet override table is missing a "name".
thrownewError(`Could not merge osquery schema with Fleet overrides. A table in the Fleet overrides schema is missing a "name". To resolve, add a "name" to the Fleet override table located at ${yamlSchema}.`);
letexpandedTables=[];// create an empty array for the merged schema.
for(letosquerySchemaTableofrawOsqueryTables){
letfleetOverridesForTable=_.find(fleetOverridesForTables,{'name':osquerySchemaTable.name});// Setting a flag if this table exists in the Fleet overrrides JSON
// Since we don't have a Fleet override for this table, we'll set the fleetRepoUrl for this table to be a link to create the Fleet override table YAML.
// This is done by adding a 'filename' and 'value' as search parameters to a url that creates a new folder in the schema/tables/ folder.
letsampleYamlSchemaForThisTable=`name: ${expandedTableToPush.name}\ndescription: |- # (required) string - The description for this table. Note: this field supports Markdown\n\t# Add description here\nexamples: |- # (optional) string - An example query for this table. Note: This field supports Markdown\n\t# Add examples here\nnotes: |- # (optional) string - Notes about this table. Note: This field supports Markdown.\n\t# Add notes here\ncolumns: # (required)\n\t- name: # (required) string - The name of the column\n\t description: # (required) string - The column's description. Note: this field supports Markdown\n\t type: # (required) string - the column's data type\n\t required: # (required) boolean - whether or not this column is required to query this table.`;
thrownewError(`Could not merge osquery schema with Fleet overrides. The Fleet override for the "${fleetOverridesForTable.name}" table located at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverridesForTable.name+'.yml')} has an invalid "platforms" value. To resolve, change the "platforms" for this table to be an array of values.`);
thrownewError(`Could not merge osquery schema with Fleet overrides. The Fleet override for the "${fleetOverridesForTable.name}" table located at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverridesForTable.name+'.yml')} has an invalid "description". To resolve, change the "description" for this table to be a string.`);
thrownewError(`Could not merge osquery schema with Fleet overrides. The Fleet override for the "${fleetOverridesForTable.name}" table located at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverridesForTable.name+'.yml')} has an invalid "examples". To resolve, change the "examples" for this table to be a string.`);
// If the override file does not contain an 'examples' value, we'll use the last example from the osquery schema (See above for more information about the reasoning behind this)
thrownewError(`Could not merge osquery schema with Fleet overrides. The Fleet override for the "${fleetOverridesForTable.name}" table located at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverridesForTable.name+'.yml')} has an invalid "notes". To resolve, change the "notes" for this table to be a string.`);
thrownewError(`Could not merge osquery schema with Fleet overrides. The Fleet override for the "${fleetOverridesForTable.name}" table located at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverridesForTable.name+'.yml')} has an invalid "hidden" value. To resolve, change the value of the "hidden" property for this table to be a boolean.`);
// If the table has Fleet overrides, we'll add the URL of the YAML file in the Fleet Github repo as the `fleetRepoUrl`, and add set the url to be where this table will live on fleetdm.com.
}else{// If the Fleet overrides JSON has column data for this table, we'll find the matching column and use the values from the Fleet overrides in the final schema.
if(columnHasFleetOverrides.hidden!==true){// If the overrides don't explicitly hide a column, we'll set the value to false to make sure the column is visible on fleetdm.com
fleetColumn.hidden=false;
}
mergedTableColumns.push(fleetColumn);
}
}
}//∞ After each column in osquery schema table
// Now iterate through the columns in the Fleet overrides, adding any columns that doesnt exist in the base osquery schema.
thrownewError(`The osquery schema could not be merged with the Fleet overrrides. The "${fleetOverridesForTable.name}" table in Fleet's overrides has an invalid "columns". To resolve, change the "columns" to be an array of objects (each containing values for "name", "type", "description" and "required" properties), and try running the script again.`);
thrownewError(`The osquery schema could not be merged with the Fleet overrides. A column in the "${fleetOverridesForTable.name}" is missing a "name". To resolve, make sure every column in /schema/tables/${fleetOverridesForTable.name}.yml has a "name" property`);
thrownewError(`The osquery tables could not be merged with the Fleet overrides. The "description" for the "${fleetOverrideColumn.name}" column of the "${fleetOverridesForTable.name}" table is an invalid type (${typeoffleetOverrideColumn.name}). to resolve, change the column's "description" to be a string.`);
thrownewError(`The osquery tables could not be merged with the Fleet overrides. The "${fleetOverrideColumn.name}" column added to the merged schema for the "${fleetOverridesForTable.name}" table is missing a description in the Fleet overrides schema. To resolve, add a description for this column to the Fleet overrides schema.`);
thrownewError(`The osquery tables could not be merged with the Fleet overrides. The "type" for the "${fleetOverrideColumn.name}" column of the "${fleetOverridesForTable.name}" table is an invalid type (${typeoffleetOverrideColumn.type}). To resolve, change the value of a column's "type" to be a string.`);
thrownewError(`The osquery tables could not be merged with the Fleet overrides. The "${fleetOverrideColumn.name}" column added to the merged schema for the "${fleetOverridesForTable.name}" table is missing a "type" in the Fleet overrides schema. To resolve, add a type for this column to the Fleet overrides schema.`);
thrownewError(`The osquery tables could not be merged with the Fleet overrides. The "platforms" property of the "${overrideColumnToAdd.name}" column of the "${fleetOverridesForTable.name}" table has an invalid value. To resolve, change the "platforms" of this column to an array`);
}//•
}
if(overrideColumnToAdd.required===undefined){
thrownewError(`The osquery tables could not be merged with the Fleet overrides. The "${fleetOverrideColumn.name}" column added in the Fleet overrides for the "${fleetOverridesForTable.name}" table is missing a "required" value. To resolve, add a "required" value (a boolean) to the column in Fleet's overrides at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverridesForTable.name+'.yml')}`);
thrownewError(`The osquery tables could not be merged with the Fleet overrides. The "${fleetOverrideColumn.name}" column added in the Fleet overrides for the "${fleetOverridesForTable.name}" table has an invalid "required" value. To resolve, change the value of the "required" property for this to the column in Fleet's overrides at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverridesForTable.name+'.yml')} to be either "true" or "false"`);
// After we've gone through the tables in the Osquery schema, we'll go through the tables in the Fleet schema JSON, and add any tables that don't exist in the osquery schema.
thrownewError(`A table in the Fleet overrides schema is missing a 'name' (${JSON.stringify(fleetOverrideToPush)}). To resolve, make sure this table has a "name" property.`);
if(!fleetSchemaTableExistsInOsquerySchema){// If a table in the Fleet schema does not exist in the osquery schema, we'll add it to the final schema after making sure that it has the required values.
thrownewError(`Could not add a new table from the Fleet overrides to final merged schema, the "${fleetOverrideToPush.name}" table is missing a 'description' value. To resolve, add a description to this table to the Fleet overrides schema at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')}. Tip: If this table is meant to override a table in the osquery schema, you may want to check that the "name" value of the added table is the same as the table in the osquery schema located at https://github.com/osquery/osquery-site/source/src/data/osquery_schema_versions/${VERSION_OF_OSQUERY_SCHEMA_TO_USE}.json`);
thrownewError(`Could not add a new table from the Fleet overrides to final merged schema, The "description" of the "${fleetOverridesForTable.name}" table is an invalid type (Eexpected a string, but instead got a ${typeoffleetOverrideToPush.description}). to resolve, change the tables's "description" to be a string.`);
thrownewError(`Could not add a new table from the Fleet overrides to final merged schema, the "${fleetOverrideToPush.name}" table is missing a 'platforms' value. To resolve, add an array of platforms to this table to the Fleet overrides schema at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')}. Tip: If this table is meant to override a table in the osquery schema, you may want to check that the "name" value of the added table is the same as the table in the osquery schema located at https://github.com/osquery/osquery-site/source/src/data/osquery_schema_versions/${VERSION_OF_OSQUERY_SCHEMA_TO_USE}.json`);
thrownewError(`Could not add a new table from the Fleet overrides to final merged schema, the "${fleetOverrideToPush.name}" table has an invalid 'platforms' value. (expected an array, but instead got a ${typeoffleetOverrideToPush.platforms}) To resolve, change the "platforms" value to be an array of values, then try runing this script again.`);
thrownewError(`Could not add a new table from the Fleet overrides to final merged schema, the "${fleetOverrideToPush.name}" table is missing a 'evented' value. To resolve, add an evented value to this table to the Fleet overrides schema at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')} .\n Tip: If this table is meant to override a table in the osquery schema, you may want to check that the "name" value of the added table is the same as the table in the osquery schema https://github.com/osquery/osquery-site/source/src/data/osquery_schema_versions/${VERSION_OF_OSQUERY_SCHEMA_TO_USE}.json`);
thrownewError(`Could not add a new table from the Fleet overrides to the final merged schema. The "${fleetOverrideToPush.name}" table has an invalid "evented" value. (expected a boolean, but instead got a ${typeoffleetOverrideToPush.evented}) To resolve, change the "evented" value for this table to be true or false, then try running this script again.`);
thrownewError(`Could not add a new table from the Fleet overrides to final merged schema. The "${fleetOverrideToPush.name}" table is missing a "columns" value. To resolve, add an array of columns to this table to the Fleet overrides schema at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')}. Tip: If this table is meant to override a table in the osquery schema, you may want to check that the "name" value of the added table is the same as the table in the osquery schema located at https://github.com/osquery/osquery-site/source/src/data/osquery_schema_versions/${VERSION_OF_OSQUERY_SCHEMA_TO_USE}.json`);
thrownewError(`Could not add a new table from the Fleet overrides to final merged schema, the "${fleetOverrideToPush.name}" table has an invalid "columns" value. (Expected an array, but instead got a ${typeoffleetOverrideToPush.columns}) To resolve, change the "columns" value to be an array of values, then try runing this script again.`);
for(letcolumnToValidateoffleetOverrideToPush.columns){// Check each column in the table to make sure it has the required values, and that all values are the correct type.
if(!columnToValidate.name){
thrownewError(`Could not add a new table from the Fleet overrides schema. A column in the "${fleetOverrideToPush.name}" table is missing a "name". To resolve, make sure every column in the table located at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')} has a "name" property.`);
}elseif(typeofcolumnToValidate.name!=='string'){
thrownewError(`Could not add a new table from the Fleet overrides schema. A column in the "${fleetOverrideToPush.name}" table located at /schema/tables/${fleetOverrideToPush.name}.yml has an invalid "name" (expected a string, but instead got ${typeofcolumnToValidate.name}).\nTo resolve, make sure that the "name" of every column in this table is a string.`);
}//•
if(!columnToValidate.type){
thrownewError(`Could not add a new table from the Fleet overrides schema. The "${columnToValidate.name}" column of the "${fleetOverrideToPush.name}" table is missing a "type". To resolve add a "type" to the "${columnToValidate.name}" column at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')}.`);
}elseif(typeofcolumnToValidate.type!=='string'){
thrownewError(`Could not add a table from the Fleet overrides schema. The "type" of the "${columnToValidate.name}" column of the "${fleetOverrideToPush.name}" table at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')} has an invalid value. (expected a string, but got a ${typeofcolumnToValidate.type}) To resolve, change the value of the column's "type" be a string.`);
thrownewError(`Could not add a new table from the Fleet overrides schema. The "${columnToValidate.name}" column of the "${fleetOverrideToPush.name}" table is missing a "description". To resolve add a "description" property to the "${columnToValidate.name}" column at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')}`);
thrownewError(`Could not add a table from the Fleet overrides schema. The "description" property of the "${columnToValidate.name}" column of the "${fleetOverrideToPush.name}" table at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')} has an invalid "description" value. To resolve, change the "description" property of the added column to be a string.`);
}//•
if(columnToValidate.required==='undefined'){
thrownewError(`Could not add a new table from the Fleet overrides schema. The "${columnToValidate.name}" column of the "${fleetOverrideToPush.name}" table is missing a "required" property. To resolve add a "required" property to the "${columnToValidate.name}" column at ${path.resolve(topLvlRepoPath+'/schema/tables',fleetOverrideToPush.name+'.yml')}`);
thrownewError(`Could not add a new table from the Fleet overrides schema. The "${columnToValidate.name}" column of the "${fleetOverrideToPush.name}" table has an invalid "required" value. (expected a boolean, but instead got a ${typeofcolumnToValidate.required}) To resolve, change the "required" property of the added column to be a boolean.`);
}//•
if(columnToValidate.platforms){
if(!_.isArray(columnToValidate.platforms)){
thrownewError(`Could not add a new table from the Fleet overrides schema. The "platforms" property of the "${columnToValidate.name}" column of the "${fleetOverrideToPush.name}" table has an invalid value. To resolve, change the "platforms" of this column to an array`);
// After we've made sure that this table has all the required values, we'll add the url of the table's YAML file in the Fleet GitHub repo as the `fleetRepoUrl` and the location of this table on fleetdm.com as the `url` before adding it to our merged schema.