Improved CLI experience with commander. Pending auditlog properties
This commit is contained in:
Родитель
cb4ec0b735
Коммит
cd28f288d5
21
README.md
21
README.md
|
@ -9,13 +9,20 @@ You can build an sh script on top of this one to store the data or query it.
|
|||
### CLI arguments
|
||||
This script can take the following arguments:
|
||||
```
|
||||
Arguments
|
||||
--token: the token to access the API (mandatory)
|
||||
--org: the organization we want to extract the audit log from (mandatory)
|
||||
--pretty: prints the json data in a readable format. Default: false
|
||||
--cfg: location for the config yaml file. Default '.ghec-audit-log'
|
||||
--cursor: if provided, this cursor will be used to query the newest entries from the cursor provided. If not present,
|
||||
the result will contain all the audit log from the org.
|
||||
> node audit-log-ghec-cli.js "--help"
|
||||
|
||||
Usage: audit-log-ghec-cli [options]
|
||||
|
||||
Options:
|
||||
-v, --version Output the current version
|
||||
-t, --token <string> the token to access the API (mandatory)
|
||||
-o, --org <string> the organization we want to extract the audit log from
|
||||
-cfg, --config <string> location for the config yaml file. Default ".ghec-audit-log" (default: "./.ghec-audit-log")
|
||||
-p, --pretty prints the json data in a readable format (default: false)
|
||||
-c, --cursor <string> if provided, this cursor will be used to query the newest entries from the cursor provided. If not present,
|
||||
the result will contain all the audit log from the org
|
||||
-h, --help display help for command
|
||||
|
||||
```
|
||||
|
||||
Optionally, you can create a file called `.ghec-audit-log` that supports
|
||||
|
|
|
@ -7,31 +7,33 @@ async function requestAllEntries(requestExecutor, org){
|
|||
"page": null,
|
||||
};
|
||||
|
||||
let firstPageCursor = null;
|
||||
let hasNextPage = true;
|
||||
// while(hasNextPage) {
|
||||
while(hasNextPage) {
|
||||
const data = await requestExecutor(allEntriesQuery, variables);
|
||||
entries = entries.concat(data.organization.auditLog.nodes);
|
||||
hasNextPage = data.organization.auditLog.pageInfo.hasNextPage;
|
||||
variables.page = data.organization.auditLog.pageInfo.endCursor;
|
||||
// }
|
||||
return entries;
|
||||
if(!firstPageCursor) firstPageCursor = data.organization.auditLog.pageInfo.startCursor
|
||||
}
|
||||
return {data: entries, newestCursor: firstPageCursor};
|
||||
}
|
||||
|
||||
async function requestNewestEntries(requestExecutor, org, cursor) {
|
||||
let entries = [];
|
||||
let variables = {
|
||||
"login": org,
|
||||
"org": org,
|
||||
"page": cursor,
|
||||
};
|
||||
|
||||
let hasNextPage = true;
|
||||
// while(hasNextPage) {
|
||||
let hasPreviousPage = true;
|
||||
while(hasPreviousPage) {
|
||||
const data = await requestExecutor(newEntriesQuery, variables);
|
||||
entries = entries.concat(data.organization.auditLog.nodes);
|
||||
hasNextPage = data.organization.auditLog.pageInfo.hasNextPage;
|
||||
hasPreviousPage = data.organization.auditLog.pageInfo.hasPreviousPage;
|
||||
variables.page = data.organization.auditLog.pageInfo.startCursor;
|
||||
// }
|
||||
return {data: entries, cursor: variables.page};
|
||||
}
|
||||
return {data: entries, newestCursor: variables.page};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -4,15 +4,26 @@ const {graphql} = require('@octokit/graphql');
|
|||
const {requestNewestEntries, requestAllEntries} = require('./audit-log-client');
|
||||
|
||||
//---- Obtain configuration
|
||||
const argv = require('minimist')(process.argv.slice(2));
|
||||
const { program } = require('commander');
|
||||
program.version('1.0.0', '-v, --version', 'Output the current version')
|
||||
.option('-t, --token <string>', 'the token to access the API (mandatory)')
|
||||
.option('-o, --org <string>', 'the organization we want to extract the audit log from')
|
||||
.option('-cfg, --config <string>', 'location for the config yaml file. Default ".ghec-audit-log"', './.ghec-audit-log')
|
||||
.option('-p, --pretty', 'prints the json data in a readable format', false)
|
||||
.option('-c, --cursor <string>', 'if provided, this cursor will be used to query the newest entries from the cursor provided. If not present,\n' +
|
||||
' the result will contain all the audit log from the org');
|
||||
|
||||
const configLocation = argv.cfg || './.ghec-audit-log';
|
||||
program.parse(process.argv);
|
||||
|
||||
const configLocation = program.cfg || './.ghec-audit-log';
|
||||
const config = YAML.parse(fs.readFileSync(configLocation, 'utf8'));
|
||||
|
||||
const cursor = argv.cursor || null;
|
||||
const pretty = argv.pretty || false;
|
||||
const token = argv.token || config.token;
|
||||
const org = argv.org || config.org;
|
||||
const cursor = program.cursor || null;
|
||||
const pretty = program.pretty || false;
|
||||
const token = program.token || config.token;
|
||||
const org = program.org || config.org;
|
||||
|
||||
//TODO maybe support other format like PUTVAL?
|
||||
|
||||
//---- Run validation
|
||||
if (!token) {
|
||||
|
@ -27,23 +38,25 @@ if (!org) {
|
|||
* Function containing all the queries
|
||||
*/
|
||||
async function queryAuditLog() {
|
||||
// Execute the query
|
||||
let entries;
|
||||
// Select the query to run
|
||||
let queryRunner;
|
||||
if (cursor) {
|
||||
let {data, cursor} = await requestNewestEntries(graphqlWithAuth, org, cursor);
|
||||
entries = data;
|
||||
fs.writeFileSync('.last-cursor-update', cursor)
|
||||
queryRunner = () => requestNewestEntries(graphqlWithAuth, org, cursor);
|
||||
} else {
|
||||
entries = await requestAllEntries(graphqlWithAuth, org);
|
||||
queryRunner = () => requestAllEntries(graphqlWithAuth, org);
|
||||
}
|
||||
|
||||
let json;
|
||||
// Run the query and store the most recent cursor
|
||||
let {data, newestCursor} = await queryRunner();
|
||||
let entries = data;
|
||||
fs.writeFileSync('.last-cursor-update', newestCursor);
|
||||
|
||||
// Return the data
|
||||
if (pretty) {
|
||||
json = JSON.stringify(entries, null, 4);
|
||||
return JSON.stringify(entries, null, 4);
|
||||
} else {
|
||||
json = JSON.stringify(entries);
|
||||
return JSON.stringify(entries);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@ const auditLogEntries = require('./audit-log-entries');
|
|||
const allEntriesQuery = `
|
||||
query($org: String!, $page: String) {
|
||||
organization(login: $org) {
|
||||
auditLog(first: 1, after: $page){
|
||||
auditLog(first: 100, after: $page){
|
||||
pageInfo {
|
||||
startCursor
|
||||
endCursor
|
||||
hasNextPage
|
||||
}
|
||||
|
@ -18,7 +19,7 @@ query($org: String!, $page: String) {
|
|||
const newEntriesQuery = `
|
||||
query($org: String!, $page: String!) {
|
||||
organization(login: $org) {
|
||||
auditLog(last: 1, before: $page){
|
||||
auditLog(last: 100, before: $page){
|
||||
pageInfo {
|
||||
startCursor
|
||||
hasNextPage
|
||||
|
|
|
@ -90,6 +90,11 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.5.tgz",
|
||||
"integrity": "sha512-3ySmiBYJPqgjiHA7oEaIo2Rzz0HrOZ7yrNO5HWyaE5q0lQ3BppDZ3N53Miz8bw2I7gh1/zir2MGVZBvpb1zq9g=="
|
||||
},
|
||||
"commander": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
|
||||
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
|
@ -165,11 +170,6 @@
|
|||
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz",
|
||||
"integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA=="
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/graphql": "^4.3.1",
|
||||
"minimist": "^1.2.5",
|
||||
"commander": "^5.1.0",
|
||||
"yaml": "^1.9.2"
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче