- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-13-2017 12:50 AM
Hi developers,
The following question:
I want to create a (standard)change based on a existing maintenance schedules that's coming the next day.
More information:
- We have CI's with maintenance schedule. (Patch management)
- I want to create a change IF a maintenance schedule is coming up in the following ~12/24 hours.
- Each day a daily scheduled job or planned maintenance (not sure which is best) is checking if I have a maintenance window in the following 12 hours then create a 'standard change'.
*Eventually creating a standard change with the maintenance window and CI's attached.
Maintenance schedules are based on 'Every first/second/third monday of the month' etc.
Worth mentioning is that there are multiple Maintenance Schedules during a week maybe even the day itself.
Any idea what's the best approach for this?
I've been trying out scheduled jobs. But I cannot seem to find a way to query the 'start date'/'end date' within the cmn_schedules_span, since this is in the past.
Creating a scheduled job that's exactly the same as the maintenance window seems kind off pointless to me. (For instance creating a scheduled job that run every first monday etc)
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-13-2017 10:04 AM
Hi Wybren,
you can make use of the GlideSchedule API and its "whenNext()" method to easily get when the next span in your schedule is due to.
For example
var sysId = 'type_your_schedule_sys_id_here'
var schedule = new GlideSchedule(sysId);
var whenNext = schedule.whenNext();
gs.log("Next maintenance window starts in: " + whenNext + " milliseconds");
gs.log("That is: " + (whenNext/(1000*60*60)) + " hours");
So you can add a schedule jobs to run every (half a day) and check if a maintenance schedule starts in the following x hours.
So for example, adding in your script:
...
if ( (whenNext/(1000*60*60)) < 24){
// maintenance starts in 24 hours ...
}
That's the simplest but effective thing you can do.
Instead, if you require more precision, like for example, I want to do something exactly 24 hours before the maintenance, you can run an script periodically which, in turn, creates schedule triggers to timeout exactly 24 hours before the maintenance period for each of the maintenance windows. When the schedule triggers timeout, then they should run the script which actually create your change.
The logic would be something like.
- Add a schedule job which run every 1 week.
- The schedule job script needs to get all the spans of your maintenance schedules from tomorrow to the next week + 1 day.
To do that, you can make use of the method getSpans(start, end), also from the GlideSchedule API.
- For each span, create a schedule trigger (sys_trigger table), with the date of the span minus 24 hours.
This will then trigger exactly 24 hours before the maintenance period.
In the script of the schedule trigger you should therefore the change creation, or any other action you want to take.
Hope it helps,
Ginés.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-13-2017 10:04 AM
Hi Wybren,
you can make use of the GlideSchedule API and its "whenNext()" method to easily get when the next span in your schedule is due to.
For example
var sysId = 'type_your_schedule_sys_id_here'
var schedule = new GlideSchedule(sysId);
var whenNext = schedule.whenNext();
gs.log("Next maintenance window starts in: " + whenNext + " milliseconds");
gs.log("That is: " + (whenNext/(1000*60*60)) + " hours");
So you can add a schedule jobs to run every (half a day) and check if a maintenance schedule starts in the following x hours.
So for example, adding in your script:
...
if ( (whenNext/(1000*60*60)) < 24){
// maintenance starts in 24 hours ...
}
That's the simplest but effective thing you can do.
Instead, if you require more precision, like for example, I want to do something exactly 24 hours before the maintenance, you can run an script periodically which, in turn, creates schedule triggers to timeout exactly 24 hours before the maintenance period for each of the maintenance windows. When the schedule triggers timeout, then they should run the script which actually create your change.
The logic would be something like.
- Add a schedule job which run every 1 week.
- The schedule job script needs to get all the spans of your maintenance schedules from tomorrow to the next week + 1 day.
To do that, you can make use of the method getSpans(start, end), also from the GlideSchedule API.
- For each span, create a schedule trigger (sys_trigger table), with the date of the span minus 24 hours.
This will then trigger exactly 24 hours before the maintenance period.
In the script of the schedule trigger you should therefore the change creation, or any other action you want to take.
Hope it helps,
Ginés.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-14-2017 04:58 AM
I'll will try this out, and let you know the outcome!
Thanks in advance!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-04-2017 12:42 AM
So I did the following:
Created a reference field in the table maintenance window (with template, that's pointing to the standard changes)
Create a scheduled script execution (scheduled job)
- Check the schedules when they start (with a template)
- Use the whenNext to find the proper schedule
- Create two system properties the password for internal user & how many hours before should it check
- Then send a http request for the change with an internal user
*This method will give you flexibility as you create a standard change which is editable by other users besides admins
*One more thing I did was creating a Business Rule that will fill the standard change with the 'CI's' of the Maintenance window given.
Scheduled Script:
//Check all the schedules if it start within a certain time, if so create a task for the template
//Get the amount of hours the change should be created for the maintenance window
var hoursBefore = gs.getProperty('bnc.hours.for.maintenance');
var grSchedule = new GlideRecord('cmn_schedule_maintenance');
grSchedule.addEncodedQuery('u_templateISNOTEMPTY');
grSchedule.query();
while (grSchedule.next()) {
//Ask the schedule when the next window is
var schedule = new GlideSchedule(grSchedule.sys_id);
var whenNext = schedule.whenNext();
//If the start of the maintenance window is within the given hours create a standard change
if (whenNext/(1000*60*60) > 0 && whenNext/(1000*60*60) < hoursBefore){
gs.log(grSchedule.name + 'Deze start tussen 0 en ' + hoursBefore);
//Do a rest call to SN for a creation of the default/template request
var taskToCreate = grSchedule.u_template;
//Call a rest message to initiate the standard change
try{
var request = new sn_ws.RESTMessageV2();
request.setHttpMethod('get');
//Get the gliderecord for the URL
var grChange = new GlideRecord('std_change_record_producer');
grChange.addQuery('sys_id',taskToCreate);
grChange.query();
while(grChange.next()){
gs.log(taskToCreate + '-> Name: ' + grChange.name);
}
var url = gs.getProperty('glide.servlet.uri');
url += new StdChangeUtils().getActionURL(grChange);
gs.log(url);
request.setEndpoint(url);
request.setBasicAuth('internaluser', gs.getProperty('sys.password'));
response = request.execute();
httpResponseStatus = response.getStatusCode();
gs.print(" http response status_code: " + httpResponseStatus);
}
catch(ex){
var message = ex.getMessage();
gs.print(message);
}
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-01-2019 01:40 PM
Hello,
This process appears to no-longer work as-of London. StdChangeUtils is now generating a token in the URL, and authentication for the REST login fails with a "401". I'm guessing this is because each user session requires its own token...
Any thoughts or ides on how to have the REST user generate then use a new token?