Configuration Mismatch-checkpoint-gaia,ipso

Configuration Mismatch-checkpoint-gaia,ipso
0

Configuration Mismatch-checkpoint-gaia,ipso

Vendor: checkpoint

OS: gaia,ipso

Description:
Indeni can verify that certain lines appear in the “show configuration” output for the device." +
" The required configuration lines need to be entered in Indeni Rules > Configuration tab. " +
" “*” can be used as a wildcard for a single word or numeric value.

Remediation Steps:
Modify the device’s configuration as required.

How does this work?
The script logs into the device through SSH and pulls the configuration by running “show configuration” in “clish”.

Why is this important?
Pulling the configuration of the devices enables Indeni to apply compliance checks on the configuration to tell the user when a non-optimal configuration has been detected.

Without Indeni how would you find this?
An administrator could login and manually run the command to view the configuration.

chkp-clish-show-configuration

name: chkp-clish-show-configuration
description: Run "show configuration" over clish
type: monitoring
monitoring_interval: 60 minutes
requires:
    vendor: checkpoint
    or:
    -   os.name: gaia
    -   os.name: ipso
comments:
    configuration-content:
        why: |
            Pulling the configuration of the devices enables Indeni to apply compliance checks on the configuration to tell the user when a non-optimal configuration has been detected.
        how: |
            The script logs into the device through SSH and pulls the configuration by running "show configuration" in "clish".
        can-with-snmp: false
        can-with-syslog: false
steps:
-   run:
        type: SSH
        command: ${nice-path} -n 15 clish -c "show configuration"
    parse:
        type: AWK
        file: show-configuration.parser.1.awk

ConfigurationComplianceCheckRule

package com.indeni.server.rules.library.crossvendor

import com.indeni.ruleengine.Scope.{Scope, ScopeValueHelper}
import com.indeni.ruleengine.expressions.core._
import com.indeni.ruleengine.expressions.data.{MultiSnapshotExtractScalarExpression, SelectSnapshotsExpression, SelectTagsExpression, SnapshotExpression}
import com.indeni.ruleengine.expressions.scope.ScopableExpression
import com.indeni.ruleengine.expressions.utility.IsEmptyExpression.IsEmptyExpressionHelper
import com.indeni.ruleengine.expressions.utility._
import com.indeni.ruleengine.expressions.{Expression, conditions}
import com.indeni.server.common.AlertNotificationSettings
import com.indeni.server.common.AlertNotificationSettings._
import com.indeni.server.common.data.conditions.True
import com.indeni.server.params.ParameterDefinition
import com.indeni.server.params.ParameterDefinition.UIType
import com.indeni.server.rules._
import com.indeni.server.rules.config.expressions.DynamicParameterExpression
import com.indeni.server.rules.library.{ConditionalRemediationSteps, PerDeviceRule, RuleHelper}
import com.indeni.server.sensor.models.managementprocess.alerts.dto.AlertSeverity


/**
  * Created by amir on 19/02/2017.
  * Updated for wild card resolution by tomas on 2018 01 20.
  */
case class CrossVendorConfigurationComplianceCheckRule() extends
  PerDeviceRule with RuleHelper {

  private val linesParameterName = "config_lines_to_look_for"
  private val linesParameter = new ParameterDefinition(
    linesParameterName,
    "",
    "Configuration Lines Needed (multi-line)",
    "List the configuration commands that need to show in the output of \"show configuration\".",
    UIType.MULTILINE_TEXT,
    "")

  override def expressionTree(context: RuleContext): StatusTreeExpression = {
    val linesExpected = DynamicParameterExpression.withConstantDefault(linesParameter.getName, Seq[String]()).withLazy
    val snapshotKey = "configuration-content"
    val missingResolved = new SeqDiffWithoutOrderExpression[String](
      MultiSnapshotExtractScalarExpression(
        SnapshotExpression(snapshotKey)
          .asMulti()
          .mostRecent()
          .value(),
        "line"), linesExpected) {

      // Modification for a wildcard "*" resolution.
      override def eval(time: Long): SeqDiff[String] = {
        val actualSet = actual.eval(time).toSet
        val expectedSetResolved = expected.eval(time).toSet.map { x: String => x.replace("*", "\\S+").r.anchored }
        val redundant = Set[String]()
        val missingChecked = {
          for {
            i <- expectedSetResolved
            j <- actualSet
          } yield i.findFirstIn(j) match {
            case Some(_) => Some(i)
            case _ => None
          }
        }.flatten.map(_.toString())
        val expectedSet = expectedSetResolved.map(_.toString())
        val missing = (expectedSetResolved.map(_.toString()) diff missingChecked).map(_.replace("\\S+", "*"))
        SeqDiff(expectedSet, missing, redundant)
      }
    }.missings.withLazy

    val missingLineHeadline = new ScopableExpression[String] {
      override protected def evalWithScope(time: Long, scope: Scope): String =
        scope.getVisible(CrossVendorConfigurationComplianceCheckRule.ConfigurationTag).get.toString

      override def args: Set[Expression[_]] = Set()
    }

    StatusTreeExpression(
      // Which objects to pull (normally, devices)
      SelectTagsExpression(context.metaDao, Set(DeviceKey), True),

      // What constitutes an issue
      StatusTreeExpression(
        // The snapshot we check the test condition against:
        SelectSnapshotsExpression(context.snapshotsDao, Set(snapshotKey)).multi(),

        // The condition which, if true, we have an issue. Checked against the snapshots we've collected
        missingResolved.nonEmpty,

        multiInformers =
          Set(
            MultiIssueInformer(
              missingLineHeadline,
              EMPTY_STRING,
              "Missing lines"
            ).iterateOver(collection = missingResolved,
              scopeKey = CrossVendorConfigurationComplianceCheckRule.ConfigurationTag,
              condition = conditions.True)
          )

        // Details of the alert itself
      ).withRootInfo(
        getHeadline(),
        ConstantExpression("Some configuration lines that should be defined are not:\n" +
          "Indeni has found that some lines are missing. These are listed below."),
        ConditionalRemediationSteps("Modify the device's configuration as required.")
      ).asCondition()
    ).withoutInfo()
  }

  /**
    * @return The rule's metadata.
    */
  override def metadata: RuleMetadata =
    RuleMetadata.builder(
      "ConfigurationComplianceCheckRule",
      "Compliance Check: Configuration Mismatch",
      "Indeni can verify that certain lines appear in the \"show configuration\" output for the device." +
        " The required configuration lines need to be entered in Indeni Rules > Configuration tab. " +
        " \"*\" can be used as a wildcard for a single word or numeric value. ",
      AlertSeverity.ERROR,
      categories = Set(RuleCategory.VendorBestPractices),
      deviceCategory = DeviceCategory.ComplianceCheck).defaultAction(
      AlertNotificationSettings(NONE))
      .configParameter(linesParameter)
      .disableGlobalRuleSet(true)
    .build()
}


object CrossVendorConfigurationComplianceCheckRule {
  val ConfigurationTag = "ConfigurationTag"
}