Skip to content

Rules

Configuring Rules

A Fitness Rule is a configuration for a set of rules that act on a signal collected from a Sensor and calculate the score for various Measures

A single Fitness Rule can create scores for multiple Measures defined in configuration.

A Fitness Function associates a Fitness Rule using its unique name to start evaluating Metrics based on the Fitness Rule to generate the scores.

Sample Fitness Rule

{
  "kind": "OrcasRule",
  "apiVersion": "orcasio.com/v1alpha3",
  "metadata": {
    "name": "avail-deploy",
    "namespace": "sample_tenant"
  },
  "spec": {
    "version": "v1.0.0",
    "rule": {
      "spec": {
        "template": {
          "spec": {
            "hostNetwork": false,
            "containers": [
              {
                "securityContext": {
                  "readOnlyRootFilesystem": false,
                  "runAsNonRoot": true,
                  "runAsUser": {
                    "orcas:enabled": true,
                    "orcas:measure": "run-as-user",
                    "orcas:value": "[0-9]+",
                    "orcas:min": 0,
                    "orcas:max": 65535
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
}
kind: OrcasRule
apiVersion: orcasio.com/v1alpha3
metadata:
  name: avail-deploy
  namespace: <tenant_ID>
spec:
  version: v1.0.0
  rule:
    spec:
      template:
        spec:
          hostNetwork: false
          containers:
          - securityContext:
              readOnlyRootFilesystem: false
              runAsNonRoot: true
              runAsUser:
                orcas:enabled: true
                orcas:measure: run-as-user
                orcas:value: "[0-9]+"
                orcas:min: 0
                orcas:max: 65535

Rule Specification

Name Description Value Value Type
kind Configuration object kind OrcasRule (fixed - do not change)
apiVersion Configuration object version orcasio.com/v1alpha3 (fixed - do not change)
metadata.name Unique name of function \<unique string> Ensure name is unique and no spaces or special chars except for "-"
metadata.namespace Unique namespace corresponding to the tenant \<unique string> (fixed - do not change)
spec.version Rule spec version v1.0.0 (fixed - do not change)
spec.rule Rule object container -none- Object specifying the rule
spec.rule.object Rule Object that mirrors Source data spec without modifications \<object> Rules can be written using below guide

Guide to Writing Rules

  1. Simple Rules: Direct JSON query path of source metric compared against static data. ex: ".spec.template.spec.hostNetwork": false . In this example the Measure name is derived as "hostNetwork". The score for this measure is evaluated as 100 if the source metric matches and 0 if the source metric has the field .spec.template.spec.hostNetwork as not available or if the value is anything other than false.
  2. Embellished Simple Rules: Same as above but with "Embellishments" provided as JSON tags to modify the rule evaluation. Multiple embellishments can be used in a single Measure as a combination.

    Embellishment Tag Description Effect
    orcas:enabled true/false Enables or disables the scoring of the Measure embellished
    orcas:measure name of measure Allows custom Measure name to be used as specified
    orcas:value string / regex / go lambda code / webhook Value to evaluate the score - can be specified as String (to compare) or as Regex to compare. Go Lambda & Webhooks is an advanced concept that can be explored beyond this Demo
    orcas:tags array of key:value tags Can be used to enrich Metadata tags futher
    orcas:desc string describing rule/measure Description that can help in cataloging the rule for maintenance
    orcas:optional true/false If enabled, this can apply rules to optional fields in the Metric JSON
  3. In-line Functions: Inline Functions provide a method to execute predefined operations directly within your Fitness Rules. This powerful feature allows for dynamic data evaluation, enabling custom logic to be applied to the signal data collected. Supported operations include comparison, logical, and array manipulation functions that can be directly invoked in the rule definition.

    • GreaterThan(value): Checks if the signal's value is greater than the specified value.
    • LessThan(value): Determines if the signal's value is less than the specified value.
    • Between(min, max): Verifies if the signal's value falls within the specified range, inclusive of min and max.
    • Diff(value1, value2, ...): Ensures the signal's value is different from all specified values.
    • Equal(value1, value2, ...): Confirms the signal's value matches all specified values.
    • ArrayIsEmpty(): Checks if the array is empty.
    • ArrayIsNotEmpty(): Validates the array is not empty.
    • Some(path, value): Determines if any element in the array matches the specified value at the given path.

    Each function call is written within the rule string and follows the syntax functionName(parameters). Parameters can be static values or references to other values within the signal data, allowing for complex rule definitions.

    Examples:

    • Checks if the signal's value is greater than the specified value.
      rule:
        spec:
          replicas: eval.GreaterThan(2)
      
    • Determines if the signal's value is less than the specified value.
      rule:
        spec:
          replicas: eval.LessThan(5)
      
    • Verifies if the signal's value falls within the specified range, inclusive of min and max.
      rule:
        spec:
          replicas: eval.Between(2, 5)
      
    • Ensures the signal's value is different from all specified values.
      rule:
        merge_requests:
          approval:
            user: eval.Diff("merge_request.created_by.user")
      
    • Confirms the signal's value matches all specified values.
      rule:
        user:
          role: eval.Equal("admin")
      
    • Checks if the array is empty.
      rule:
        alerts: eval.ArrayIsEmpty()
      
    • Validates the array is not empty.
      rule:
        merge_requests:
          approvals: eval.ArrayIsNotEmpty()
      
    • Determines if any element in the array matches the specified value at the given path.
      rule:
        user: eval.Some("country", "Argentina")
      
  4. Advanced Rules: Advanced rules can be written using the orcas:value tag set to 2 modes - Go Lambda or Webhooks. Go Lambda allows writing Golang code as an inline lambda snippet. Webhooks allows calling external APIs to evaluate the scores for a Measure. This purposes of this demo this section has been left out and can be explored further in subsequent sessions. For more information refer to Go Lambda

Configure Rule using API

Create rule

  • URI: https://api-sample_tenant.flukes.aws.orcasio.net/api/inventory/ orcasio.com/v1alpha3/orcasrules/<name_of_rule>
  • Method: POST
  • Header (for security): orcas-token: TOKEN (See TOKEN generation details above)
  • Header: Content-type: application/json
  • Request Body (JSON):

    {
      "data": {
        "kind": "OrcasRule",
        "apiVersion": "orcasio.com/v1alpha3",
        "metadata": {
          "name": "<name_of_rule>",
          "namespace": "<sample_tenant>"
        },
        "spec": {
          "version": "v1.0.0",
          "rule": {
            "sample": true,
            "sampleGoCode": {
              "orcas:enabled": true,
              "orcas:measure": "replicas",
              "orcas:value": "# golang\nv, _ := toInt(request.Value)\nresponse.Measure = \"replicas\"\nswitch v {\ncase 0:\n  response.Message = \"No active replicas\"\n  response.FitnessPercent = 0\n  response.MutatedValue = 3\ncase 1:\n  response.Message = \"Does not meet the minimum number of replicas\"\n  response.FitnessPercent = 25\ncase 2:\n  response.Message = \"Does not meet the minimum number of replicas\"\n  response.FitnessPercent = 50\ndefault:\n  response.Message = \"Meets the minimum number of replicas\"\n  response.FitnessPercent = 100\n}"
            }
          }
        }
      }
    }
    
  • Header: Content-type: application/x-yaml
  • Request Body (raw-text):

    data:
      kind: OrcasRule
      apiVersion: orcasio.com/v1alpha3
      metadata:
        name: "<name_of_rule>"
        namespace: "<sample_tenant>"
      spec:
        version: v1.0.0
        rule:
          sample: true
          sampleGoCode:
            orcas:enabled: true
            orcas:measure: "replicas"
            orcas:value: |
              # golang
              v, _ := toInt(request.Value)
              response.Measure = "replicas"
              switch v {
              case 0:
                response.Message = "No active replicas"
                response.FitnessPercent = 0
              case 1:
                response.Message = "Does not meet the minimum number of replicas"
                response.FitnessPercent = 25
              case 2:
                response.Message = "Does not meet the minimum number of replicas"
                response.FitnessPercent = 50
              default:
                response.Message = "Meets the minimum number of replicas"
                response.FitnessPercent = 100
              }
    
  • Request Response

    {
      "data": [
        {
          "apiVersion": "orcasio.com/v1alpha3",
          "kind": "OrcasRule",
          "metadata": {
            "creationTimestamp": "2023-07-24T18:07:36Z",
            "generation": 1,
            "managedFields": [],
            "name": "avail-deploy-test",
            "namespace": "orcas",
            "resourceVersion": "656867",
            "uid": "3b988157-8932-43cc-9f68-d61aae1fb098"
          },
          "spec": {
            "rule": { "<rule_as_json>" },
            "version": "v1.0.0"
          }
        }
      ]
    }
    
    {
      "error": "the server rejected our request due to an error in our request",
      "message": {
        "apiVersion": "v1",
        "code": 422,
        "details": { "<error_details>" },
        "kind": "Status",
        "message": "<error_message>",
        "metadata": {},
        "reason": "Invalid",
        "status": "Failure"
      }
    }
    

Get rules

  • URI: https://api-sample_tenant.flukes.aws.orcasio.net/api/inventory/ orcasio.com/v1alpha3/orcasrules
  • Method: GET
  • Header (for security): orcas-token: TOKEN (See TOKEN generation details above)
  • Header: Content-type: application/json
  • Request Response

    {
      "data": [
        {
          "apiVersion": "orcasio.com/v1alpha3",
          "kind": "OrcasRule",
          "metadata": {
            "creationTimestamp": "2023-07-24T18:07:36Z",
            "generation": 1,
            "managedFields": [],
            "name": "<rule_name>",
            "namespace": "orcas",
            "resourceVersion": "656867",
            "uid": "3b988157-8932-43cc-9f68-d61aae1fb098"
          },
          "spec": {
            "rule": { "<rule_as_json>" },
            "version": "v1.0.0"
          }
        }
      ]
    }
    
    {
      "error": "the server rejected our request due to an error in our request",
      "message": {
        "apiVersion": "v1",
        "code": 422,
        "details": { "<error_details>" },
        "kind": "Status",
        "message": "<error_message>",
        "metadata": {},
        "reason": "Invalid",
        "status": "Failure"
      }
    }
    

Update rule

Note

When updating a rule you need to include the current metadata.resourceVersion in the data. You can obtain this value using the GET request

  • URI: https://api-sample_tenant.flukes.aws.orcasio.net/api/inventory/ orcasio.com/v1alpha3/orcasrules/<name_of_rule>
  • Method: PUT
  • Header (for security): orcas-token: TOKEN (See TOKEN generation details above)
  • Header: Content-type: application/json
  • Request Body (JSON):

    {
      "data": {
        "kind": "OrcasRule",
        "apiVersion": "orcasio.com/v1alpha3",
        "metadata": {
          "name": "<name_of_rule>",
          "namespace": "<sample_tenant>",
          "resourceVersion": "657268"
        },
        "spec": {
          "version": "v1.0.0",
          "rule": {
            "sample": true
          }
        }
      }
    }
    
  • Header: Content-type: application/x-yaml
  • Request Body (raw-text):

    data:
      kind: OrcasRule
      apiVersion: orcasio.com/v1alpha3
      metadata:
        name: "<name_of_rule>"
        namespace: "<sample_tenant>"
        resourceVersion: '657268'
      spec:
        version: v1.0.0
        rule:
          sample: true
    
  • Request Response

    {
      "data": [
        {
          "apiVersion": "orcasio.com/v1alpha3",
          "kind": "OrcasRule",
          "metadata": {
            "creationTimestamp": "2023-07-24T18:07:36Z",
            "generation": 1,
            "managedFields": [
              {
                "apiVersion": "orcasio.com/v1alpha3",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                  "f:spec": {
                    ".": {},
                    "f:rule": {
                      ".": {},
                      "f:spec": {
                        ".": {},
                        "f:template": {
                          ".": {},
                          "f:spec": {
                            ".": {},
                            "f:containers": {},
                            "f:hostNetwork": {}
                          }
                        }
                      }
                    },
                    "f:version": {}
                  }
                },
                "manager": "orcas-pulse",
                "operation": "Update",
                "time": "2023-07-24T18:07:36Z"
              }
            ],
            "name": "avail-deploy-test",
            "namespace": "orcas",
            "resourceVersion": "656867",
            "uid": "3b988157-8932-43cc-9f68-d61aae1fb098"
          },
          "spec": {
            "rule": { "<rule_as_json>" },
            "version": "v1.0.0"
          }
        }
      ]
    }
    
    {
      "error": "the server rejected our request due to an error in our request",
      "message": {
        "apiVersion": "v1",
        "code": 422,
        "details": { "<error_details>" },
        "kind": "Status",
        "message": "<error_message>",
        "metadata": {},
        "reason": "Invalid",
        "status": "Failure"
      }
    }