Created
August 13, 2020 05:03
-
-
Save AaronMcCaughan/180180d23e6ad56796b3978c901b2c6f to your computer and use it in GitHub Desktop.
Create_Health_Check_Status_history_via_API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This script will connect to Plutora using Oauth 2.0 Authentication and retrieve a list of environments to be based on the search parameters defined in the Plutora UI. | |
It will then console.log the response to the execution log in Plutora. | |
This script uses credentials that are defined in Plutora UI as Job Parameters. Refer to the knowledge base in Plutora for more information on adding parameters | |
To execute this script on your own instance of Plutora, create a new Job, upload the script and define the parameters in the Plutora UI as follows (Note the parameter names are case sensitive): | |
- oauthurl = <This is the oauth url of your instance of Plutora> | |
- apiUrl = <This is the API url of your instance of Plutora> | |
- username = <This is the user email to authenticate with your instance of Plutora> | |
- password = <This is the user password to authenticate with your instance of Plutora> | |
- clientId = <This is the API client ID to authenticate with your instance of Plutora> | |
- clientSecret = <This is the API client secret to authenticate with Plutora> | |
- filterProperty = <This is the name of the field used to filter the list of Environment> | |
- filterValue = <This is the field value used to filter the list of Environment> | |
- filterOperator = <This is the operator used to filter the list of Environment> | |
*/ | |
/******************************************************** | |
*************STEP 1: Import npm's************************ | |
********************************************************/ | |
const fs = require('fs'); | |
const https = require('https'); | |
const uuid = require('uuid/v4'); | |
const querystring = require("querystring"); | |
/******************************************************** | |
*******STEP 2: Define you API and SSH parameters********* | |
********************************************************/ | |
const params = { | |
auth: { | |
server: { | |
hostname: '', | |
}, | |
client_id: '', | |
client_secret: '', | |
grant_type: '', | |
username: '', | |
password: '', | |
}, | |
api: { | |
server: { | |
hostname: '', | |
}, | |
pagination: { | |
pagenum: 0, | |
limit: 1 | |
}, | |
filter: { | |
property: '', | |
direction: '', | |
value: '', | |
operator: '', | |
} | |
}, | |
}; | |
/******************************************************** | |
****STEP 3: Create an API Request function******** | |
********************************************************/ | |
const makeRequest = function (options, payload = '') { | |
return new Promise(function (resolve, reject) { | |
let req = https.request(options, (res) => { | |
let body = ""; | |
res.on("data", data => { | |
body += data; | |
}); | |
res.on("end", () => { | |
if (res.statusCode >= 200 && res.statusCode < 300) { | |
resolve(body); | |
} | |
else { | |
reject(body); | |
} | |
}); | |
}); | |
req.on('error', (e) => { | |
console.error(e.message); | |
reject(e); | |
}); | |
req.write(payload); | |
req.end(); | |
}); | |
}; | |
/******************************************************** | |
****STEP 4: Define all the API requests required ******** | |
********************************************************/ | |
// API Call to Get Plutora oauth token | |
const getAuthToken = function (authParams) { | |
const postData = querystring.stringify({ | |
client_id: authParams.client_id, | |
client_secret: authParams.client_secret, | |
grant_type: authParams.grant_type, | |
username: authParams.username, | |
password: authParams.password | |
}); | |
const options = { | |
hostname: authParams.server.hostname, | |
path: '/oauth/token', | |
method: 'POST', | |
rejectUnauthorized: false, | |
headers: { | |
'Content-Type': 'application/x-www-form-urlencoded', | |
'Content-Length': postData.length | |
} | |
}; | |
return makeRequest(options, postData).then((data) => { | |
return JSON.parse(data); | |
}); | |
}; | |
// API Call to Get the list of existing environments | |
const getEnvironments = function (apiParams) { | |
const filterValue = querystring.escape(apiParams.filter.value); | |
const options = { | |
hostname: apiParams.server.hostname, | |
path: `/Environments?filter=%60${apiParams.filter.property}%60%20${apiParams.filter.operator}%20%60${filterValue}%60&pageNum=${apiParams.pagination.pagenum}&recordsPerPage=${apiParams.pagination.limit}`, | |
method: 'GET', | |
rejectUnauthorized: false, | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + apiParams.auth_token | |
} | |
}; | |
return makeRequest(options); | |
}; | |
const createLogFile = function (prefix) { | |
const logLines = 'This is just a sample log file.\n' + | |
'Console log: Starting environment health check\n' + | |
'Console log: Health check in progress...10% complete\n' + | |
'Console log: Health check in progress...50% complete\n' + | |
'Console log: Health check in progress...100% complete\n'; | |
const fileName = `${prefix}-log.txt`; | |
fs.writeFileSync(`/${fileName}`, logLines); | |
return fileName; | |
}; | |
// API Call to Create a health check record for each environments retrieved | |
const checkEnviromentHealth = function (id) { | |
// Replace this with the actual health check function | |
// Statuses: 0 - Unknown, 1 - Online, 2 - Offline, 3 - Issue | |
const logFileName = createLogFile(`env-${id}-${new Date().toISOString()}`); | |
if (id) { | |
return {logFile: logFileName, status: 1 } | |
} else { | |
return {logFile: logFileName, status: 0 } | |
} | |
}; | |
// Create health check records for each environment | |
const createHealthCheckRecords = function (apiParams, record) { | |
const testName = `test-via-inthub-at-${new Date().toISOString()}`; | |
const boundary = uuid(); // Generate a random id | |
const fileContent = fs.readFileSync(`/${record.logFile}`, 'utf8'); | |
const logFileName = record.logFileName; | |
const newLine = '\r\n'; | |
// The 2 dashes at the start and end of the boundary are required. Do NOT remove. | |
const payload = `--${boundary}${newLine}Content-Disposition: form-data; name=\"environmentId\"${newLine}${newLine}${record.environmentId}${newLine}` + | |
`--${boundary}${newLine}Content-Disposition: form-data; name=\"health\"${newLine}${newLine}${record.status}${newLine}` + | |
`--${boundary}${newLine}Content-Disposition: form-data; name=\"testName\"${newLine}${newLine}${testName}${newLine}` + | |
`--${boundary}${newLine}Content-Disposition: form-data; name=\"logFile\"; filename=\"${logFileName}\"${newLine}Content-Type: text/plain${newLine}${newLine}` + | |
`${fileContent}${newLine}--${boundary}--${newLine}`; | |
const options = { | |
hostname: apiParams.server.hostname, | |
path: '/environmenthealthcheck', | |
method: 'POST', | |
rejectUnauthorized: false, | |
headers: { | |
'Authorization': `Bearer ${apiParams.auth_token}`, | |
'Content-Type': `multipart/form-data; boundary=${boundary}`, | |
}, | |
body: payload, | |
}; | |
return makeRequest(options, payload); | |
}; | |
/******************************************************** | |
********STEP 5: Define the main run function ************ | |
********************************************************/ | |
const run = async function (args) { | |
const params = { | |
auth: { | |
server: { | |
hostname: args.arguments.oauthurl, | |
}, | |
client_id: args.arguments.clientId, | |
client_secret: args.arguments.clientSecret, | |
grant_type: 'password', | |
username: args.arguments.username, | |
password: args.arguments.password, | |
}, | |
api: { | |
server: { | |
hostname: args.arguments.apiUrl, | |
}, | |
pagination: { | |
pagenum: 0, | |
limit: 100 | |
}, | |
filter: { | |
property: args.arguments.filterProperty, | |
direction: "ASC", | |
value: args.arguments.filterValue, | |
operator: args.arguments.filterOperator, | |
} | |
}, | |
}; | |
return new Promise(async (resolve, reject) => { | |
console.log('Retrieving authentication token...'); | |
const authToken = await getAuthToken(params.auth); | |
const parameters = {...params.api, ...{auth_token: authToken.access_token}}; | |
console.log(`Filter settings: property=${parameters.filter.property} | keyword=${parameters.filter.value} | operator=${parameters.filter.operator}`); | |
let environments = []; | |
let healthCheckResults = []; | |
let complete = false; | |
while (!complete) { | |
console.log(`Fetching page ${parameters.pagination.pagenum} of environments...`); | |
const pagedResult = JSON.parse(await getEnvironments(parameters)); | |
if (pagedResult.resultSet.totalCount === 0) { | |
complete = true; | |
} | |
pagedResult.resultSet.forEach(item => { | |
environments.push({id: item.id, name: item.name}); | |
}); | |
complete = isAllRecordsFetched(parameters.pagination, pagedResult); | |
if (complete) { | |
console.log('All environments have been fetched.') | |
}; | |
parameters.pagination.pagenum++; | |
} | |
for (const env of environments) { | |
console.log(`Performing health check for environmentId: ${env.id} | environmentName: ${env.name}...`); | |
let result = await checkEnviromentHealth(env.id); | |
if (result) { | |
healthCheckResults.push({environmentId: env.id, environmentName: env.name, status: result.status, logFile: result.logFile}); | |
} | |
} | |
for (const record of healthCheckResults) { | |
let result = JSON.parse(await createHealthCheckRecords(parameters, record)) | |
if (result.Status === "Success") { | |
console.log(`Health check record successfully created for environmentId: ${record.environmentId} | environmentName: ${record.environmentName}. | Messages: ${result.Messages.join()}`); | |
} else { | |
console.log(`Failed to create health check record for environmentId: ${record.environmentId} | environmentName: ${record.environmentName}. | Message: ${result.Messages.join()}`); | |
} | |
} | |
console.log('Task complete.') | |
resolve(); | |
}); | |
}; | |
const isAllRecordsFetched = function (pageInfo, pagedResult) { | |
if (pageInfo.pagenum === 0 && pagedResult.totalCount === pagedResult.returnCount) { | |
return true; | |
} | |
if (pageInfo.pagenum >= Math.floor(pagedResult.totalCount / pageInfo.limit)) { | |
return true; | |
}; | |
return false; | |
} | |
module.exports = { | |
run: run | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment