Skip to content

Commit

Permalink
Website: Create queries.yml, add vitals and query pages, move policie…
Browse files Browse the repository at this point in the history
…s. (#25701)

Related to: fleetdm/confidential#9096

Changes:
- Created docs/queries.yml. A YAML file that contains the queries from
the standard query library (`kind: query`) and the host vitals queries
(`kind: built-in`).
- Added the `vitals/*` page, a page that displays details about host
vital queries used to gather information about.
- Updated the /queries page to show queries from the new
`docs/queries.yml` file, and moved policies to a new page (/policies)
- Updated the view action for the query-detail page to look for/redirect
to a policy page with a matching slug before returning a 404 response if
a matching query is not found. This behavior will make it so all of the
old URLs for policy pages will redirect users to the new URL.
- Updated the website's "Docs" navigation menu to have links to the new
vitals and policies pages.
  • Loading branch information
eashaw authored Jan 23, 2025
1 parent 19947a0 commit 5c0894c
Show file tree
Hide file tree
Showing 27 changed files with 4,076 additions and 125 deletions.
1,594 changes: 1,594 additions & 0 deletions docs/queries.yml

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions website/api/controllers/view-policy-details.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
module.exports = {


friendlyName: 'View policy detail',


description: 'Display "policy details" page.',


inputs: {
slug: { type: 'string', required: true, description: 'A slug uniquely identifying this policy in the library.', example: 'get-macos-disk-free-space-percentage' },
},


exits: {
success: { viewTemplatePath: 'pages/policy-details' },
notFound: { responseType: 'notFound' },
badConfig: { responseType: 'badConfig' },
},


fn: async function ({ slug }) {

if (!_.isObject(sails.config.builtStaticContent) || !_.isArray(sails.config.builtStaticContent.policies)) {
throw {badConfig: 'builtStaticContent.policies'};
} else if (!_.isString(sails.config.builtStaticContent.policyLibraryYmlRepoPath)) {
throw {badConfig: 'builtStaticContent.queryLibraryYmlRepoPath'};
}

// Serve appropriate content for policy.
// > Inspired by https://github.com/sailshq/sailsjs.com/blob/b53c6e6a90c9afdf89e5cae00b9c9dd3f391b0e7/api/controllers/documentation/view-documentation.js
let policy = _.find(sails.config.builtStaticContent.policies, { slug: slug });
if (!policy) {
throw 'notFound';
}

// Find the related osquery table documentation for tables used in this query, and grab the keywordsForSyntaxHighlighting from each table used.
let allTablesInformation = _.filter(sails.config.builtStaticContent.markdownPages, (pageInfo)=>{
return _.startsWith(pageInfo.url, '/tables/');
});
// Get all the osquery table names, we'll use this list to determine which tables are used.
let allTableNames = _.pluck(allTablesInformation, 'title');
// Create an array of words in the query.
let queryWords = _.words(policy.query, /[^ \n;]+/g);
let columnNamesForSyntaxHighlighting = [];
let tableNamesForSyntaxHighlighting = [];
// Get all of the words that appear in both arrays
let intersectionBetweenQueryWordsAndTableNames = _.intersection(queryWords, allTableNames);
// For each matched osquery table, add the keywordsForSyntaxHighlighting and the names of the tables used into two arrays.
for(let tableName of intersectionBetweenQueryWordsAndTableNames) {
let tableMentionedInThisQuery = _.find(sails.config.builtStaticContent.markdownPages, {title: tableName});
tableNamesForSyntaxHighlighting.push(tableMentionedInThisQuery.title);
let keyWordsForThisTable = tableMentionedInThisQuery.keywordsForSyntaxHighlighting;
columnNamesForSyntaxHighlighting = columnNamesForSyntaxHighlighting.concat(keyWordsForThisTable);
}
// Remove the table names from the array of column names to highlight.
columnNamesForSyntaxHighlighting = _.difference(columnNamesForSyntaxHighlighting, tableNamesForSyntaxHighlighting);


// Setting the meta title and description of this page using the query object, and falling back to a generic title or description if policy.name or policy.description are missing.
let pageTitleForMeta = policy.name ? policy.name + ' | Policy details' : 'Policy details';
let pageDescriptionForMeta = policy.description ? policy.description : 'View more information about a policy in Fleet\'s standard query library';
// Respond with view.
return {
policy,
queryLibraryYmlRepoPath: sails.config.builtStaticContent.policyLibraryYmlRepoPath,
pageTitleForMeta,
pageDescriptionForMeta,
columnNamesForSyntaxHighlighting,
tableNamesForSyntaxHighlighting,
algoliaPublicKey: sails.config.custom.algoliaPublicKey,
};

}


};
55 changes: 55 additions & 0 deletions website/api/controllers/view-policy-library.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module.exports = {


friendlyName: 'View policy library',


description: 'Display "Policy library" page.',


exits: {

success: {
viewTemplatePath: 'pages/policy-library'
},
badConfig: { responseType: 'badConfig' },

},


fn: async function () {

if (!_.isObject(sails.config.builtStaticContent) || !_.isArray(sails.config.builtStaticContent.policies)) {
throw {badConfig: 'builtStaticContent.policies'};
}
let policies = _.where(sails.config.builtStaticContent.policies, {kind: 'policy'});
let macOsPolicies = _.filter(policies, (policy)=>{
let platformsForThisPolicy = policy.platform.split(',');
return _.includes(platformsForThisPolicy, 'darwin');
});
let windowsPolicies = _.filter(policies, (policy)=>{
let platformsForThisPolicy = policy.platform.split(',');
return _.includes(platformsForThisPolicy, 'windows');
});
let linuxPolicies = _.filter(policies, (policy)=>{
let platformsForThisPolicy = policy.platform.split(',');
return _.includes(platformsForThisPolicy, 'linux');
});
let chromePolicies = _.filter(policies, (policy)=>{
let platformsForThisPolicy = policy.platform.split(',');
return _.includes(platformsForThisPolicy, 'chrome');
});
// Respond with view.
return {
macOsPolicies,
windowsPolicies,
linuxPolicies,
chromePolicies,
algoliaPublicKey: sails.config.custom.algoliaPublicKey,
};


}


};
18 changes: 16 additions & 2 deletions website/api/controllers/view-query-detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ module.exports = {
success: { viewTemplatePath: 'pages/query-detail' },
notFound: { responseType: 'notFound' },
badConfig: { responseType: 'badConfig' },
redirectToPolicy: {
description: 'The requesting user has been redirected to a policy page.',
responseType: 'redirect'
},
},


fn: async function ({ slug }) {

if (!_.isObject(sails.config.builtStaticContent) || !_.isArray(sails.config.builtStaticContent.queries)) {
throw {badConfig: 'builtStaticContent.queries'};
} else if (!_.isObject(sails.config.builtStaticContent) || !_.isArray(sails.config.builtStaticContent.policies)) {
throw {badConfig: 'builtStaticContent.policies'};
} else if (!_.isString(sails.config.builtStaticContent.queryLibraryYmlRepoPath)) {
throw {badConfig: 'builtStaticContent.queryLibraryYmlRepoPath'};
}
Expand All @@ -31,7 +37,15 @@ module.exports = {
// > Inspired by https://github.com/sailshq/sailsjs.com/blob/b53c6e6a90c9afdf89e5cae00b9c9dd3f391b0e7/api/controllers/documentation/view-documentation.js
let query = _.find(sails.config.builtStaticContent.queries, { slug: slug });
if (!query) {
throw 'notFound';
// If we didn't find a query matching this slug, check to see if there is a policy with a matching slug.
// Note: We do this because policies used to be on /queries/* pages. This way, all old URLs that policies used to live at will still bring users to the correct page.
let policyWithThisSlug = _.find(sails.config.builtStaticContent.policies, {kind: 'policy', slug: slug});
if(policyWithThisSlug){
// If we foudn a matchign policy, redirect the user.
throw {redirect: `/policies/${policyWithThisSlug.slug}`};
} else {
throw 'notFound';
}
}

// Find the related osquery table documentation for tables used in this query, and grab the keywordsForSyntaxHighlighting from each table used.
Expand All @@ -41,7 +55,7 @@ module.exports = {
// Get all the osquery table names, we'll use this list to determine which tables are used.
let allTableNames = _.pluck(allTablesInformation, 'title');
// Create an array of words in the query.
let queryWords = _.words(query.query, /[^ ]+/g);
let queryWords = _.words(query.query, /[^ \n;]+/g);
let columnNamesForSyntaxHighlighting = [];
let tableNamesForSyntaxHighlighting = [];
// Get all of the words that appear in both arrays
Expand Down
14 changes: 7 additions & 7 deletions website/api/controllers/view-query-library.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,24 @@ module.exports = {
if (!_.isObject(sails.config.builtStaticContent) || !_.isArray(sails.config.builtStaticContent.queries)) {
throw {badConfig: 'builtStaticContent.queries'};
}
let policies = _.where(sails.config.builtStaticContent.queries, {kind: 'policy'});
let macOsPolicies = _.filter(policies, (policy)=>{
let policies = _.where(sails.config.builtStaticContent.queries, {kind: 'query'});
let macOsQueries = _.filter(policies, (policy)=>{
let platformsForThisPolicy = policy.platform.split(',');
return _.includes(platformsForThisPolicy, 'darwin');
});
let windowsPolicies = _.filter(policies, (policy)=>{
let windowsQueries = _.filter(policies, (policy)=>{
let platformsForThisPolicy = policy.platform.split(',');
return _.includes(platformsForThisPolicy, 'windows');
});
let linuxPolicies = _.filter(policies, (policy)=>{
let linuxQueries = _.filter(policies, (policy)=>{
let platformsForThisPolicy = policy.platform.split(',');
return _.includes(platformsForThisPolicy, 'linux');
});
// Respond with view.
return {
macOsPolicies,
windowsPolicies,
linuxPolicies,
macOsQueries,
windowsQueries,
linuxQueries,
algoliaPublicKey: sails.config.custom.algoliaPublicKey,
};

Expand Down
97 changes: 97 additions & 0 deletions website/api/controllers/view-vital-details.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
module.exports = {


friendlyName: 'View vital details',


description: 'Display "Vital details" page.',


inputs: {
slug: { type: 'string', required: true, description: 'A slug uniquely identifying this query in the library.', example: 'get-macos-disk-free-space-percentage' },
},


exits: {
success: { viewTemplatePath: 'pages/vital-details' },
notFound: { responseType: 'notFound' },
badConfig: { responseType: 'badConfig' },
},


fn: async function ({ slug }) {

if (!_.isObject(sails.config.builtStaticContent) || !_.isArray(sails.config.builtStaticContent.queries)) {
throw {badConfig: 'builtStaticContent.queries'};
} else if (!_.isString(sails.config.builtStaticContent.queryLibraryYmlRepoPath)) {
throw {badConfig: 'builtStaticContent.queryLibraryYmlRepoPath'};
}

// Serve appropriate content for vital.
// > Inspired by https://github.com/sailshq/sailsjs.com/blob/b53c6e6a90c9afdf89e5cae00b9c9dd3f391b0e7/api/controllers/documentation/view-documentation.js
let thisVital = _.find(sails.config.builtStaticContent.queries, { slug: slug });
if (!thisVital) {
throw 'notFound';
}

// Find the related osquery table documentation for tables used in this query, and grab the keywordsForSyntaxHighlighting from each table used.
let allTablesInformation = _.filter(sails.config.builtStaticContent.markdownPages, (pageInfo)=>{
return _.startsWith(pageInfo.url, '/tables/');
});
// Get all the osquery table names, we'll use this list to determine which tables are used.
let allTableNames = _.pluck(allTablesInformation, 'title');
// Create an array of words in the vital.
let queryWords = _.words(thisVital.query, /[^ \n;]+/g);
let columnNamesForSyntaxHighlighting = [];
let tableNamesForSyntaxHighlighting = [];
// Get all of the words that appear in both arrays
let intersectionBetweenQueryWordsAndTableNames = _.intersection(queryWords, allTableNames);
// For each matched osquery table, add the keywordsForSyntaxHighlighting and the names of the tables used into two arrays.
for(let tableName of intersectionBetweenQueryWordsAndTableNames) {
let tableMentionedInThisQuery = _.find(sails.config.builtStaticContent.markdownPages, {title: tableName});
tableNamesForSyntaxHighlighting.push(tableMentionedInThisQuery.title);
let keyWordsForThisTable = tableMentionedInThisQuery.keywordsForSyntaxHighlighting;
columnNamesForSyntaxHighlighting = columnNamesForSyntaxHighlighting.concat(keyWordsForThisTable);
}
// Remove the table names from the array of column names to highlight.
columnNamesForSyntaxHighlighting = _.difference(columnNamesForSyntaxHighlighting, tableNamesForSyntaxHighlighting);

// Setting the meta title and description of this page using the query object, and falling back to a generic title or description if vital.name or vital.description are missing.
let pageTitleForMeta = thisVital.name ? thisVital.name + ' | Vital details' : 'Vital details';
let pageDescriptionForMeta = thisVital.description ? thisVital.description : 'Explore Fleet’s built-in queries for collecting and storing important device information.';
let vitals = _.where(sails.config.builtStaticContent.queries, {kind: 'built-in'});
let macOsVitals = _.filter(vitals, (vital)=>{
let platformsForThisPolicy = vital.platform.split(', ');
return _.includes(platformsForThisPolicy, 'darwin');
});
let windowsVitals = _.filter(vitals, (vital)=>{
let platformsForThisPolicy = vital.platform.split(', ');
return _.includes(platformsForThisPolicy, 'windows');
});
let linuxVitals = _.filter(vitals, (vital)=>{
let platformsForThisPolicy = vital.platform.split(', ');
return _.includes(platformsForThisPolicy, 'linux');
});
let chromeVitals = _.filter(vitals, (vital)=>{
let platformsForThisPolicy = vital.platform.split(', ');
return _.includes(platformsForThisPolicy, 'chrome');
});
// Respond with view.
return {
thisVital,
macOsVitals,
windowsVitals,
linuxVitals,
chromeVitals,
queryLibraryYmlRepoPath: sails.config.builtStaticContent.queryLibraryYmlRepoPath,
pageTitleForMeta,
pageDescriptionForMeta,
columnNamesForSyntaxHighlighting,
tableNamesForSyntaxHighlighting,
algoliaPublicKey: sails.config.custom.algoliaPublicKey,
};

}


};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 5c0894c

Please sign in to comment.