Name
sn_agent.AgentFeatureRegistry
Description
No description available
Script
var AgentFeatureRegistry = Class.create();
AgentFeatureRegistry.prototype = {
initialize: function(familyRelease, patchLevel, agentFrameworkVersion) {
// set these variables to override the instance information parsed from the glide.buildtag
// familyReleaseOverride must be set to one of the values in the family_version_release choice in sn_agent_feature_registry table
// the overrides will be used if this.useInstanceVersionOverride is set to true
// this can be used when the instance information cannot be parsed properly from the glide.buildtag
this.useInstanceVersionOverride = false;
this.familyReleaseOverride = '';
this.patchLevelOverride = 0;
// default values used for instance information when the glide.buildtag sys_property cannot be found
// used in dev environments since the glide.buildtag property is not set in dev environments
// if paris patch 0 is not accurate for the dev environment, then the family release information can be overriden
// by setting the this.useInstanceVersionOverride, this.familyReleaseOverride, and this.patchLevelOverride variables above
this.familyReleaseDefault = 'paris';
this.patchLevelDefault = 0;
this.populateFamilyReleaseMap();
this.GLIDE_VERSION_REGEX = /glide-(\S*?)-\d{2}-\d{2}-\d{4}(?:__patch(\d+))?/;
// Used to compare agent versions
this.versionComparator = new sn_agent.AgentVersionComparator();
if (agentFrameworkVersion)
this.agentFrameworkVersion = agentFrameworkVersion;
else
this.agentFrameworkVersion = this.getAgentFrameworkVersion();
if (familyRelease && patchLevel) {
this.setInstanceVersionInformation(familyRelease, patchLevel);
} else
this.initializeInstanceVersionInformation();
},
setInstanceVersionInformation: function(familyRelease, patchLevel) {
this.familyRelease = familyRelease;
this.familyReleaseOrder = this.getFamilyReleaseOrder(familyRelease);
this.patchLevel = patchLevel;
this.familyReleaseName = familyRelease.charAt(0).toUpperCase() + familyRelease.substring(1);
},
/*
* Sets the following variables:
* this.familyRelease (string value of the family release), empty string represents no family release information
* this.familyReleaseOrder (integer value used for comparing releases, ordered defined by this.FAMILY_RELEASE_MAP), 0 represents no family release order information
* this.patchLevel (integer value used for comparing patch levels), -1 represents no patch level information
* If the familyReleaseOverride and the patchLevelOverride are set, then the instance version information will be initialized using those values
* Otherwise, the instance version information is parsed from the glide.buildtag sys_property
*/
initializeInstanceVersionInformation: function() {
// use override values if they are set
if (this.useInstanceVersionOverride) {
this.setInstanceVersionInformation(this.familyReleaseOverride, this.patchLevelOverride);
return;
}
// attempt to get the instance family release and patch level information from glide.buildtag sys_property
// glide.buildtag property examples:
// glide-paris-06-24-2020__patch4-11-25-2020
// glide-paris-06-24-2020__patch0-hotfix1-07-07-2020_07-17-202
// glide-quebec-12-09-2020
var glideBuildTag = gs.getProperty('glide.buildtag', '');
if (glideBuildTag == '' || glideBuildTag.indexOf('glide-track') > -1) {
// use default values if we cannot find the glide build tag
this.setInstanceVersionInformation(this.familyReleaseDefault, this.patchLevelDefault);
return;
}
this.parseInstanceVersionFromGlideBuildTag(glideBuildTag);
},
/*
* Check if the specified feature + version is supported on the specified agent
*/
isFeatureSupportedOnAgent: function(featureName, version, agentId) {
var agentExtendedInfoGr = this.getAgentExtendedInfoRecord(agentId);
if (!agentExtendedInfoGr)
return false;
var featureRecord = this.getFeatureRecord(featureName, version);
if (!featureRecord)
return false;
if (!this.featureIsSupportedByInstanceAndAgentFramework(featureRecord))
return false;
var minimumAgentVersionRequirement = featureRecord.getValue('min_agent_version');
var maximumAgentVersionRequirement = featureRecord.getValue('max_agent_version');
var agentVersion = agentExtendedInfoGr.getValue('agent_version');
return this.versionMeetsRequirements(agentVersion, minimumAgentVersionRequirement, maximumAgentVersionRequirement);
},
/*
* Returns a comma separated list of agent IDs for the agents that support the specified feature
*/
getSupportedAgentsForFeature: function(featureName, version) {
var featureRecord = this.getFeatureRecord(featureName, version);
if (!featureRecord)
return [];
if (!this.featureIsSupportedByInstanceAndAgentFramework(featureRecord))
return [];
var minimumAgentVersionRequirement = featureRecord.getValue('min_agent_version');
var maximumAgentVersionRequirement = featureRecord.getValue('max_agent_version');
return this.getSupportedAgentsForVersion(minimumAgentVersionRequirement, maximumAgentVersionRequirement);
},
getSupportedAgentsForVersion: function(minimumAgentVersionRequirement, maximumAgentVersionRequirement) {
var supportedAgents = [];
var agentExtendedInfoGr = new GlideRecord('sn_agent_ci_extended_info');
agentExtendedInfoGr.query();
while (agentExtendedInfoGr.next()) {
var agentId = agentExtendedInfoGr.getValue('agent_id');
var agentVersion = agentExtendedInfoGr.getValue('agent_version');
if (this.versionMeetsRequirements(agentVersion, minimumAgentVersionRequirement, maximumAgentVersionRequirement))
supportedAgents.push(agentId);
}
return supportedAgents;
},
/*
* Returns a comma separated list of agent IDs for the agents that do not support the specified feature
*/
getUnsupportedAgentsForFeature: function(featureName, version) {
if (this.isFeatureFullySupported(featureName, version))
return [];
var featureRecord = this.getFeatureRecord(featureName, version);
if (!featureRecord || !this.featureIsSupportedByInstanceAndAgentFramework(featureRecord)) {
// feature is not supported, add all agent ids to list of unsupported agents
var unsupportedAgents = [];
var agentExtendedInfoGr = new GlideRecord('sn_agent_ci_extended_info');
agentExtendedInfoGr.query();
while (agentExtendedInfoGr.next())
unsupportedAgents.push(agentExtendedInfoGr.getValue('agent_id'));
return unsupportedAgents;
}
var minimumAgentVersionRequirement = featureRecord.getValue('min_agent_version');
var maximumAgentVersionRequirement = featureRecord.getValue('max_agent_version');
return this.getUnsupportedAgentsForVersion(minimumAgentVersionRequirement, maximumAgentVersionRequirement);
},
getUnsupportedAgentsForVersion: function(minimumAgentVersionRequirement, maximumAgentVersionRequirement) {
var unsupportedAgents = [];
var agentExtendedInfoGr = new GlideRecord('sn_agent_ci_extended_info');
agentExtendedInfoGr.query();
while (agentExtendedInfoGr.next()) {
var agentId = agentExtendedInfoGr.getValue('agent_id');
var agentVersion = agentExtendedInfoGr.getValue('agent_version');
if (!this.versionMeetsRequirements(agentVersion, minimumAgentVersionRequirement, maximumAgentVersionRequirement))
unsupportedAgents.push(agentId);
}
return unsupportedAgents;
},
getFeatureRecord: function(featureName, version) {
var featureGr = new GlideRecord('sn_agent_feature_registry');
featureGr.addQuery('feature_name', featureName);
featureGr.addQuery('feature_version', version);
featureGr.query();
if (!featureGr.next()) {
gs.warn('getFeatureRecord: could not find feature with name "' + featureName + '" and version "' + version + '"', 'AgentFeatureRegistry');
return null;
}
return featureGr;
},
getFeatureRecordBySysId: function(featureSysId) {
var featureGr = new GlideRecord('sn_agent_feature_registry');
var found = featureGr.get(featureSysId);
if (!found) {
gs.warn('getFeatureRecordBySysId: could not find feature with sys_id "' + featureSysId + '"', 'AgentFeatureRegistry');
return null;
}
return featureGr;
},
getAgentExtendedInfoRecord: function(agentId) {
var agentExtendedInfoGr = new GlideRecord('sn_agent_ci_extended_info');
agentExtendedInfoGr.addQuery('agent_id', agentId);
agentExtendedInfoGr.query();
if (!agentExtendedInfoGr.next()) {
gs.warn('getAgentExtendedInfoRecord: could not find agent with id "' + agentId + '"', 'AgentFeatureRegistry');
return null;
}
return agentExtendedInfoGr;
},
isFeatureFullySupported: function(featureName, version) {
var featureRecord = this.getFeatureRecord(featureName, version);
if (!featureRecord)
return false;
if (!this.featureIsSupportedByInstanceAndAgentFramework(featureRecord))
return false;
return this.allAgentsMeetAgentVersionRequirement(featureRecord);
},
getHighestAgentVersion: function() {
if (this.highestAgentVersion)
return this.highestAgentVersion;
var agentExtendedInfoGr = new GlideRecord('sn_agent_ci_extended_info');
agentExtendedInfoGr.setLimit(1);
agentExtendedInfoGr.orderByDesc('agent_version');
agentExtendedInfoGr.query();
if (!agentExtendedInfoGr.next())
return null;
this.highestAgentVersion = agentExtendedInfoGr.getValue('agent_version');
return this.highestAgentVersion;
},
getLowestAgentVersion: function() {
if (this.lowestAgentVersion)
return this.lowestAgentVersion;
var agentExtendedInfoGr = new GlideRecord('sn_agent_ci_extended_info');
agentExtendedInfoGr.setLimit(1);
agentExtendedInfoGr.orderBy('agent_version');
agentExtendedInfoGr.query();
if (!agentExtendedInfoGr.next())
return null;
this.lowestAgentVersion = agentExtendedInfoGr.getValue('agent_version');
return this.lowestAgentVersion;
},
allAgentsMeetAgentVersionRequirement: function(featureRecord) {
var agentExtendedInfoGr;
var maximumAgentVersionRequirement = featureRecord.getValue('max_agent_version');
if (maximumAgentVersionRequirement) {
// query for the agent with the highest agent version
var maxAgentVersion = this.getHighestAgentVersion();
if (!maxAgentVersion)
return false;
// return false if maxAgentVersion is greater than (return value 1) maximumAgentVersionRequirement
if (this.versionComparator.compare(maxAgentVersion, maximumAgentVersionRequirement) == 1)
return false;
}
// query for the agent with the lowest agent version
var minAgentVersion = this.getLowestAgentVersion();
if (!minAgentVersion)
return false;
// all agents meet the agent version requirement of this feature if the lowest agent version is
// greater than or equal to the minimum agent version requirement specified by the feature record
var minimumAgentVersionRequirement = featureRecord.getValue('min_agent_version');
// return true if minAgentVersion is greater than or equal to (return value 0 or 1) minimumAgentVersionRequirement
return this.versionComparator.compare(minAgentVersion, minimumAgentVersionRequirement) != -1;
},
allAgentsMeetMinRequirement: function(featureRecord) {
var minAgentVersion = this.getLowestAgentVersion();
if (!minAgentVersion)
return false;
return this.versionMeetsMinRequirement(minAgentVersion, featureRecord.min_agent_version);
},
noAgentsMeetAgentVersionRequirement: function(featureRecord) {
var agentExtendedInfoGr;
var maximumAgentVersionRequirement = featureRecord.getValue('max_agent_version');
if (maximumAgentVersionRequirement) {
// query for the agent with the lowest agent version
var minAgentVersion = this.getLowestAgentVersion();
if (!minAgentVersion)
return true;
// return true if minAgentVersion is greater than (return value 1) maximumAgentVersionRequirement
if (this.versionComparator.compare(minAgentVersion, maximumAgentVersionRequirement) == 1)
return true;
}
// query for the agent with the highest agent version
var maxAgentVersion = this.getHighestAgentVersion();
if (!maxAgentVersion)
return true;
var minimumAgentVersionRequirement = featureRecord.getValue('min_agent_version');
// return true if minAgentVersion is less than (return value -1) minimumAgentVersionRequirement
return this.versionComparator.compare(maxAgentVersion, minimumAgentVersionRequirement) == -1;
},
versionMeetsMaxRequirement: function(version, maxRequirement) {
// check to see if we have a max requirement
// if the version is greater than the max requirement, then we know the requirements aren't met
if (maxRequirement && (this.versionComparator.compare(version, maxRequirement) == 1))
// return false if version is greater than (return value 1) maxRequirement
return false;
// return true if no max requirement or if the version is lower than or equal to the max
return true;
},
versionMeetsMinRequirement: function(version, minRequirement) {
// return true if version is greater than or equal to (return value 0 or 1) minRequirement
return this.versionComparator.compare(version, minRequirement) != -1;
},
versionMeetsRequirements: function(version, minRequirement, maxRequirement) {
return this.versionMeetsMaxRequirement(version, maxRequirement) && this.versionMeetsMinRequirement(version, minRequirement);
},
featureIsSupportedByInstanceAndAgentFramework: function(featureRecord) {
return this.featureIsSupportedByInstance(featureRecord) && this.featureIsSupportedByAgentFramework(featureRecord);
},
featureIsSupportedByInstance: function(featureRecord) {
return this.instanceMeetsMaxRequirement(featureRecord) && this.instanceMeetsMinRequirement(featureRecord);
},
instanceMeetsMaxRequirement: function(featureRecord) {
var familyReleaseMaximumRequirement = featureRecord.getValue('max_family_release');
var patchLevelMaximumRequirement = featureRecord.getValue('max_patch_level');
if (familyReleaseMaximumRequirement != null && patchLevelMaximumRequirement != null) {
var familyReleaseOrderMaximumRequirement = this.getFamilyReleaseOrder(familyReleaseMaximumRequirement);
if (this.familyReleaseOrder > familyReleaseOrderMaximumRequirement ||
this.familyReleaseOrder == familyReleaseOrderMaximumRequirement && this.patchLevel > patchLevelMaximumRequirement)
return false;
}
// return true if there are no max requirements
return true;
},
instanceMeetsMinRequirement: function(featureRecord) {
var familyReleaseMinimumRequirement = featureRecord.getValue('min_family_release');
var familyReleaseOrderMinimumRequirement = this.getFamilyReleaseOrder(familyReleaseMinimumRequirement);
var patchLevelMinimumRequirement = featureRecord.getValue('min_patch_level');
return this.familyReleaseOrder > familyReleaseOrderMinimumRequirement ||
(this.familyReleaseOrder == familyReleaseOrderMinimumRequirement && this.patchLevel >= patchLevelMinimumRequirement);
},
featureIsSupportedByAgentFramework: function(featureRecord) {
return this.agentFrameworkMeetsMaxRequirement(featureRecord) && this.agentFrameworkMeetsMinRequirement(featureRecord);
},
agentFrameworkMeetsMaxRequirement: function(featureRecord) {
var maxRequirement = featureRecord.getValue('max_acc_f_version');
return this.versionMeetsMaxRequirement(this.agentFrameworkVersion, maxRequirement);
},
agentFrameworkMeetsMinRequirement: function(featureRecord) {
var minRequirement = featureRecord.getValue('min_acc_f_version');
return this.versionMeetsMinRequirement(this.agentFrameworkVersion, minRequirement);
},
/*
* Maps the family release names to its index in the family release order
* e.g. orlando -> 0, paris -> 1, quebec -> 2, etc.
* This allows for the script to determine the order of the family releases
* The map is populated by obtaining the sequence of the family releases in the
* sn_agent_feature_registry min_family_release choice field
*/
populateFamilyReleaseMap: function() {
this.FAMILY_RELEASE_MAP = {};
var sysChoiceGr = new GlideRecord('sys_choice');
sysChoiceGr.addQuery('name', 'sn_agent_feature_registry');
sysChoiceGr.addQuery('element', 'min_family_release');
sysChoiceGr.query();
while (sysChoiceGr.next()) {
var releaseName = sysChoiceGr.getValue('value');
var sequence = parseInt(sysChoiceGr.getValue('sequence'));
this.FAMILY_RELEASE_MAP[releaseName] = sequence;
}
},
getFamilyReleaseOrder: function(familyRelease) {
if (!this.FAMILY_RELEASE_MAP)
throw 'family release map has not been populated yet';
if (!this.FAMILY_RELEASE_MAP.hasOwnProperty(familyRelease))
throw 'could not find specified family release "' + familyRelease + '" in the family release map';
return this.FAMILY_RELEASE_MAP[familyRelease];
},
parseInstanceVersionFromGlideBuildTag: function(glideBuildTag) {
var matches = this.GLIDE_VERSION_REGEX.exec(glideBuildTag);
if (!matches || matches.length < 2)
throw 'could not parse family release and patch level from glide.buildtag';
var familyRelease = matches[1];
if (matches.length == 3)
var patchLevelInt = parseInt(matches[2]);
var patchLevel = patchLevelInt ? patchLevelInt : 0;
this.setInstanceVersionInformation(familyRelease, patchLevel);
},
getAgentFrameworkVersion: function() {
var storeAppGr = new GlideRecord('sys_store_app');
storeAppGr.addQuery('name', 'Agent Client Collector Framework');
storeAppGr.query();
if (!storeAppGr.next())
throw 'could not find store app record with name "Agent Client Collector Framework"';
var version = storeAppGr.getValue('version');
if (!version)
throw 'could not obtain version from "Agent Client Collector Framework" store app record';
if (version.endsWith('-SNAPSHOT'))
version = version.substr(0, version.lastIndexOf('-'));
return version;
},
type: 'AgentFeatureRegistry'
};
Sys ID
b13fb7307365e0102535b7385ef6a704