Name

global.VisibilityLicensingItemizer

Description

No description available

Script

var VisibilityLicensingItemizer = Class.create();
VisibilityLicensingItemizer.prototype = {
  initialize: function() {
      this.utils = new sn_itom_license.ITOMLicensingUtils();
  },

  getCIs: function() {
      var valueStream = "Visibility";
      if (!this.utils.ignoreITOMDiscovery())
          valueStream = "Discovery";
      // is the new license model in place for this customer ?
      if (!this.utils.isNewLicenseModel())
          return;

      var metadata = new sn_itom_license.ITOMLicensingMetaData();
      var counts = this.utils.getCountsJsonTemplate();
      var allAllowedSources = this._getDiscoverySources();
      var excludedStatus = ['7', '8', '100']; // RETIRED, STOLEN, ABSENT
      var dateFilter = 'Last 90 days@javascript:gs.beginningOfLast90Days()@javascript:gs.endOfLast90Days()';
      var countedCIs = [];

      // for each applicable category
      for (var category in counts) {
          // NOTE: special case for enduser_devices where we *ONLY* want to count AgentClientCollector sourced CIs
          var allowedSources = (category == 'enduser_devices' ? ['AgentClientCollector'] : allAllowedSources);

          // get the list of tables that we need to count
          var tables = metadata.getTables(category);
          var totalCount = 0;
          var domains = {};
          var categoryTotalCIs = [];
          // for each table that's found for a category
          for (var tableIndex in tables) {
              var tableName = tables[tableIndex];
              var includedCIListwithDomain = [];
              var includedCIList = [];

              //	gs.debug("\tprocessing table : " + tableName);
              var tableCountGr = new GlideRecord(tableName);
              if (!tableCountGr.isValid())
                  continue;

              this._addCountConditions(tableCountGr, excludedStatus, allowedSources, dateFilter);
              tableCountGr.query();
              // Making Record List 
              while (tableCountGr.next()) {
                  var sysId = tableCountGr.getUniqueValue();
                  includedCIListwithDomain.push({
                      'sysId': sysId,
                      'domain': tableCountGr.getValue('sys_domain')
                  });
                  includedCIList.push(sysId);
              }
              //	gs.debug("\t Selected sysId before exclude : " + JSON.stringify(includedCIList));
              includedCIList = this._excludeMetadata(includedCIList, tableName, valueStream);
              //	gs.debug("\t Selected sysId after exclude : " + JSON.stringify(includedCIList));						
              if (tableName == 'cmdb_ci_vm_instance')
                  includedCIList = this._ecsVMExclude(includedCIList);

              includedCIListwithDomain.forEach(function(ci) {
                  if (includedCIList.indexOf(ci.sysId) != -1)
                      categoryTotalCIs.push(ci);
              });
          }
          // Counting CI Domain Wise
          categoryTotalCIs.forEach(function(ci) {
              countedCIs.push(ci.sysId);
              if (domains.hasOwnProperty(ci.domain))
                  domains[ci.domain]++;
              else
                  domains[ci.domain] = 1;
          });

          if (category == 'Servers') {
              // a VM can be discovered by both cloud discovery and IP based discovery to avoid
              // counting the same node twice, find the CI's that have a Virtualized by::Virtualizes
              // relationship between cmdb_ci_vm_instance and cmdb_ci_server
              // and deduct that from the total count of domain wise
              var excludeArr = [];
  			var relGr = new GlideRecord('cmdb_rel_ci');
              var subDomain = {};
              // vm relationship to host can be either Instantiates::Instantiated by or Virtualized by::Virtualizes
              relGr.addQuery('type.name', 'IN', 'Instantiates::Instantiated by, Virtualized by::Virtualizes, Owns::Owned by');
              this._addDeduplicationVmConditions(relGr, excludedStatus, allowedSources, dateFilter);
              relGr.query();
  			
              while (relGr.next()) {
                  // Counting only cmdb_ci_vm_instance
  				var parentSysId = relGr.getValue('parent');
  				excludeArr.push(parentSysId);
  				
  				var domain = relGr.parent.sys_domain;
                  if (subDomain.hasOwnProperty(domain))
                      subDomain[domain]++;
                  else
                      subDomain[domain] = 1;
              }
              Object.keys(subDomain).forEach(function(e) {
                  if (domains.hasOwnProperty(e)) {
                      domains[e] -= subDomain[e];
                  }
              });
  			countedCIs = this._excludeUtil(excludeArr, countedCIs);
  			
          }

          // Adding 0 count with default domain in case of empty object
          counts[category] = (Object.keys(domains).length) ? domains : {
              "global": 0
          };
      }

      return countedCIs;
  },

  // NOTE: This function is overriden in ITOMVisibilityLicenseCounterWithServices
  _addCountConditions: function(tableCountGr, excludedStatus, allowedSources, dateFilter) {
      tableCountGr.addQuery('duplicate_of', 'NULL');
      tableCountGr.addQuery('install_status', 'NOT IN', excludedStatus);
      this._addSourceFilter(tableCountGr, 'sys_id', allowedSources, dateFilter);
  },

  // NOTE: This function is overriden in ITOMVisibilityLicenseCounterWithServices
  _addDeduplicationVmConditions: function(relGr, excludedStatus, allowedSources, dateFilter) {
      // filter first for conditions on parent side ...
      var serverQuery = relGr.addJoinQuery('cmdb_ci_server', 'parent', 'sys_id');
      serverQuery.addCondition('duplicate_of', 'NULL');
      serverQuery.addCondition('install_status', 'NOT IN', excludedStatus.join(","));
      this._addSourceFilter(relGr, 'parent', allowedSources, dateFilter);

      // then filter for conditions on child side ...
      var vmQuery = relGr.addJoinQuery('cmdb_ci_vm_instance', 'child', 'sys_id');
      vmQuery.addCondition('duplicate_of', 'NULL');
      vmQuery.addCondition('install_status', 'NOT IN', excludedStatus.join(","));
      this._addSourceFilter(relGr, 'child', allowedSources, dateFilter);
  },

  _addSourceFilter: function(gr, ref, allowedSources, dateFilter) {
      var sourceQuery = gr.addJoinQuery('sys_object_source', ref, 'target_sys_id');
      sourceQuery.addCondition('name', 'IN', allowedSources.join(","));
      sourceQuery.addCondition('last_scan', 'ON', dateFilter);
  },


  _getDiscoverySources: function() {
      var allowedSources = [];
      var licenseDiscoverySourceGr = new GlideRecord('itom_lu_discovery_sources');
      licenseDiscoverySourceGr.query();
      while (licenseDiscoverySourceGr.next())
          allowedSources.push(licenseDiscoverySourceGr.getValue('source'));

      return allowedSources;
  },

  // This method will exclude the CIs which satisfies the condition from exclude metadata table

  _excludeMetadata: function(includedCIList, tableName, valueStream) {
      var excludeSysId = [];
      var queryObject = {};
      var gr = new GlideRecord('itom_licensing_exclusion_metadata');
      gr.addQuery('category_table_name', tableName);
      gr.addQuery('value_stream', valueStream).addOrCondition('value_stream', 'All');
      gr.addQuery('active', true);
      gr.query();

      while (gr.next()) {
          var tName = gr.table_name;
          if (queryObject.hasOwnProperty(tName))
              queryObject[tName].push(gr.getValue('condition'));
          else
              queryObject[tName] = [gr.getValue('condition')];
      }
      //	gs.debug('Query Object' + JSON.stringify(queryObject));
      var queryArr = Object.keys(queryObject);

      for (var i = 0; i < queryArr.length; i++) {
          var querytableName = queryArr[i];
          queryObject[querytableName].forEach(function(query) {
              var tbGr = new GlideRecord(querytableName);
              tbGr.addEncodedQuery(query);
              tbGr.query();
              while (tbGr.next()) {
                  var sysId = tbGr.getUniqueValue();
                  if (excludeSysId.indexOf(sysId) == -1)
                      excludeSysId.push(sysId);
              }
          }, this);
      }

      return this._excludeUtil(excludeSysId, includedCIList);
  },

  // Special Condition to Exclude ECS Cluster VMs
  _ecsVMExclude: function(includedCIList) {
      var excludeSysId = [];
      var countGr = new GlideRecord('cmdb_ci_vm_instance');
      var ecsVMQuery = countGr.addJoinQuery('cmdb_rel_ci', 'sys_id', 'child');
      ecsVMQuery.addCondition('type.name', 'IN', 'Uses::Used by');
      ecsVMQuery.addCondition('parent.sys_class_name', 'cmdb_ci_cloud_ecs_cluster');
      countGr.query();

      while (countGr.next()) {
          var sysId = countGr.getUniqueValue();
          if (excludeSysId.indexOf(sysId) == -1)
              excludeSysId.push(sysId);
      }

      return this._excludeUtil(excludeSysId, includedCIList);
  },

  // Util function to remove the SysId from Included Array
  _excludeUtil: function(excludeArr, includeArr) {
      excludeArr.forEach(function(e) {
          var index = includeArr.indexOf(e);
          if (index > -1)
              includeArr.splice(index, 1);
      });

      return includeArr;
  },

  printCIClasswiseCount: function() {
      var CIs = this.getCIs();
      if (CIs.length == 0) {
          gs.info("Counted CI list is empty");
          return;
      }
      var gr = new GlideAggregate('cmdb_ci');
      gr.addQuery('sys_id', 'IN', CIs.join(","));
      gr.addAggregate('COUNT', 'sys_class_name');
      gr.orderBy('sys_class_name');
      gr.query();

      while (gr.next()) {
          var tableName = gr.sys_class_name;
          var tableCount = gr.getAggregate('COUNT', 'sys_class_name');
          gs.info("Table Name: " + tableName + ", Count: " + tableCount);
      }
  },

  printCIsGroupedBy: function() {
      var CIs = this.getCIs();
      var len = arguments.length;
      this.column = [];
  	this.filters = [];
      if (len == 0) {
          this.gr = new GlideRecord('cmdb_ci');
          this.gr.addQuery('sys_id', 'IN', CIs.join(","));
          this.gr.orderBy('sys_class_name');
          this.column.push('sys_class_name');
      } else {
          this.gr = new GlideRecord('cmdb_ci');
          this.gr.addQuery('sys_id', 'IN', CIs.join(","));
          for (var i = 0; i < len; i++) {
              this.gr.orderBy(arguments[i]);
              this.column.push(arguments[i]);
          }
      }
      return this;
  },

  filterOn: function(param1, param2, param3) {
    
      if (param3)
          this.gr.addQuery(param1, param2, param3);
      else
          this.gr.addQuery(param1, param2);
  	if(this.filters.indexOf(param1) == -1)
  		this.filters.push(param1);
      return this;
  },

  showFilters: function(val) {
      this.showFilters = val;
      if (val == 'true') {
          for(var i = 0; i < this.filters.length;i++)
  			if(this.column.indexOf(this.filters[i]) == -1)
  				this.column.push(this.filters[i]);
      }
      return this;
  },

  print: function(top) {

      if (top)
          this.gr.setLimit(top);
      this.gr.query();

      while (this.gr.next()) {
          var str = "sysId: " + this.gr.getValue('sys_id') + ",\t" + "Name: " + this.gr.getValue('name') + ",\t";
          for (var i = 0; i < this.column.length; i++)
              str += this.column[i] + ": " + this.gr.getValue(this.column[i]) + ",\t";
          gs.info(str);
      }
  },

  printCIsforClass: function(tableName) {
      var CIs = this.getCIs();
      var gr = new GlideAggregate('cmdb_ci');
      gr.addQuery('sys_id', 'IN', CIs.join(","));
      gr.addQuery('sys_class_name', tableName);
      gr.query();
      if (gr.hasNext()) {
          gs.info('Below are the counted CIs for Table: ' + tableName);
          while (gr.next())
              gs.info("CI Name: " + gr.getValue('name') + ", Sys ID: " + gr.getValue('sys_id'));
      } else
          gs.info('No counted CIs present in table ' + tableName);
  },


  type: 'VisibilityLicensingItemizer'
};

Sys ID

e78e29aa1b882c10bc7e76e48d4bcbb8

Offical Documentation

Official Docs: