Saturday, April 20, 2019

Jenkins Delete Jobs under (nested) views

'''
Script to delete jobs and nested views in Jenkins CI including the parent view.
This currently works when you have two-level nested views with jobs under the child view.
Parent view
- Child view 1
- Job 1
- Job 2
- Child view 2
- Job 3
- Job 4
The script will first delete all the jobs in child view, then proceed to delete the child view itself.
Once all child views have been deleted, it will delete the parent view as last step.
License: MIT
'''
import sys
import requests
# Update Jenkins end-point here upto the context path for view with trailing slash
jenkins_endpoint_url="http://localhost:8005/view/"
#######################################
#### DONT MODIFY BELOW
# First arg is username
user = sys.argv[1]
# Second arg is password
passw = sys.argv[2]
# Third arg is the view name
view_to_delete = sys.argv[3]
'''
Method to invoke REST-API call to delete jobs
'''
def delete_job(job):
del_job_req = requests.delete(job['url'], auth=(user, passw))
if(del_job_req.status_code == 200):
print ">>>> Job " + job['name'] + " deleted successfully."
else:
print ">>>> Exception occurred deleting job. HTTP status code: " + str(del_job_req.status_code)
sys.exit();
'''
Method to invoke REST-API call to delete views
'''
def delete_view(view):
request = requests.post(view['url'] + 'doDelete' , auth=(user, passw))
if(request.status_code == 200):
print ">>>> View " + view['name'] + " deleted successfully."
else:
print ">>>> Exception occurred deleting view. HTTP status code: " + str(del_view_req.status_code)
sys.exit()
#### Start of script
# Fetch list of all nested views
nested_view_list_req = requests.get(jenkins_endpoint_url + view_to_delete + '/api/json', auth=(user, passw))
if(nested_view_list_req.status_code == 200):
for app_view in nested_view_list_req.json()['views']: # Loop through each nested view
print "Processing: " + app_view['name']
# Get each job under the nested views
nested_view_req = requests.get(app_view['url'] + 'api/json', auth=(user, passw))
if(nested_view_req.status_code == 200):
# Loop through each jobs in the nested view and delete them
for jobs in nested_view_req.json()['jobs']:
delete_job(jobs)
print "Deleting nested view " + app_view['name'] + " now"
# Delete each of the nested view
delete_view(app_view)
else:
print "Unable to get list of jobs in the view. Error code: " + str(nested_view_list_req.status_code)
if(nested_view_list_req.status_code == 200):
print "Lastly deleting parent view: " + view_to_delete
delete_view(nested_view_list_req.json())
print "All done"
view raw delete-jobs.py hosted with ❤ by GitHub

Thursday, April 4, 2019

Script to diff properties file

Compare application properties files in Groovy

This script below allows you to compare properties files between environments.

If you maintain your application's externalised properties file in a seperate repository with a structure similar to below, you can use this to compare properties file between different environment.

compare-properties.groovy
|- src
|	|- main
|	|	|- resources
|	|	|	|- finance-app
|	|	|	|	|- dev
|	|	|	|	|	|- application.properties
|	|	|	|	|- test
|	|	|	|	|	|- application.properties

The script offers 2 mode for comparison. First is showing properties that missing in one or other environments. Second being the values of matching properties that are different.

Setting up and running the script

Update the name of the properties file and the base path from where the script will be run:

def propertiesFileName = "application.properties"
def basePath = "src/main/resources"

To run the script, place it at the root of the project and run by: groovy compare-properties.groovy

view raw _readme.md hosted with ❤ by GitHub
/**
* Usage: Run the script: groovy compare-properties.groovy
* You will be prompted for application name (finance-app), source environment (eg. uat3) and target environment (prod)
*/
// Script configuration
def propertiesFileName = 'application.properties'
def basePath = 'src/main/resources'
// End of script configuration - no more config below this point
def applicationName, src, target, diffMode
def allowedDiffModes = ['1', '2', '3']
if (args.length == 0) {
diffMode = System.console().readLine 'Select mode: \n ' +
'Enter 1 to evaluate missing properties. \n ' +
'Enter 2 to evaluate value mismatches.\n ' +
'Enter 3 to find properties where values are duplicating. \n ' +
'Choice: '
if (!allowedDiffModes.contains(diffMode)) {
println 'Invalid option selected'
System.exit(0)
}
applicationName = System.console().readLine 'Enter application name: '
src = System.console().readLine 'Enter Source Environment: '
if (['1', '2'].contains(diffMode))
target = System.console().readLine 'Enter Target Environment: '
} else {
diffMode = args[0]
applicationName = args[1]
src = args[2]
target = args[3]
}
Properties srcProperties = new Properties()
Properties targetProperties = new Properties()
File srcPropertiesFile = new File("${basePath}/${applicationName}/${src}/${propertiesFileName}")
File targetPropertiesFile = new File("${basePath}/${applicationName}/${target}/${propertiesFileName}")
Closure loadPropertiesFromFile = {
File propertiesFile, Properties loadIntoProps, String env, String appName ->
if (env) {
try {
propertiesFile.withInputStream {
loadIntoProps.load(it)
}
}
catch (FileNotFoundException e) {
println "Environment ${env} not defined for the application ${appName}. \nExiting script. \n"
System.exit(0)
}
}
}
loadPropertiesFromFile(srcPropertiesFile, srcProperties, src, applicationName)
loadPropertiesFromFile(targetPropertiesFile, targetProperties, target, applicationName)
// Only the keys
List srcPropListKeys = srcProperties.collect { return it.key }
List targetPropListKeys = targetProperties.collect { return it.key }
List srcPropList = srcProperties.collect { return ["${it.key}": it.value] }
List targetPropList = targetProperties.collect { return ["${it.key}": it.value] }
Closure evaluateMissingProps = {
println "Properties in ${src} that are not in ${target}: "
(srcPropListKeys - targetPropListKeys).size == 0 ? println(' None') : (srcPropListKeys - targetPropListKeys).each {
println " ${it} \n"
}
println "\n"
println "Properties in ${target} that not in ${src}:"
(targetPropListKeys - srcPropListKeys).size == 0 ? println(' None') : (targetPropListKeys - srcPropListKeys).each {
println " ${it} \n"
}
}
Closure evaluateValueMismatches = {
List diff = (srcPropList - targetPropList)
println "${diff.size} properties in ${src} are different in ${target}: "
diff.size == 0 ? println('None') : diff.each {
it.each { k, v ->
def targetProp = targetProperties.find { it.key == k }
println "-----"
println " $k "
println "\t${src}\t: $v "
println "\t${target}\t: ${targetProp?.value ? targetProp?.value : " ** DOES NOT EXIST IN: ${target}. ** "}"
}
}
}
Closure findDuplicatingProperties = {
srcProperties.groupBy { it.value }.findAll { it.value.size() > 1 }?.each {
it.value.each { println "${it.key}=${it.value}" }
}
}
println '*********** START ***********'
println "Number of properties in ${applicationName}/${src}: ${srcPropListKeys.size}\n"
if (target) println "Number of properties in ${applicationName}/${target}: ${targetPropListKeys.size}\n"
if (diffMode == '1')
evaluateMissingProps()
else if (diffMode == '2')
evaluateValueMismatches()
else if (diffMode == '3')
findDuplicatingProperties()
else
throw new RuntimeException('Invalid mode selected...')
println "\n *********** END *********** \n"