Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Extract context information from an array when passing to message #466

Open
1 task done
kurktchiev opened this issue Sep 10, 2024 · 18 comments · May be fixed by #471
Open
1 task done

[Feature] Extract context information from an array when passing to message #466

kurktchiev opened this issue Sep 10, 2024 · 18 comments · May be fixed by #471
Labels
enhancement New feature or request triage Default label assigned to all new issues indicating label curation is needed to fully organize.

Comments

@kurktchiev
Copy link

Problem Statement

Currently, if I would like my user message to include information stored in an Array, there is no way to traverse the objects of the array and extract the field I am looking for to send back to the end user. I want my user message to include information stored in an Array, and there is no way to traverse the array's objects in that context

Solution Description

Lets say we have the following Reference JSON, I want to be able to grab tasks[*].taskArn or tasks[*].containers[*].containerArn and provide it in my message block as proper identification for my end users:

{
  "failures": [],
  "tasks": [
    {
      "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/1dc5c17a-422b-4dc4-b493-371970c6c4d6",
      "overrides": {
        "containerOverrides": [
          {
            "name": "simple-app"
          },
          {
            "name": "busybox"
          }
        ]
      },
      "lastStatus": "RUNNING",
      "containerInstanceArn": "arn:aws:ecs:us-east-1:012345678910:container-instance/default/5991d8da-1d59-49d2-a31f-4230f9e73140",
      "createdAt": 1476822811.295,
      "version": 0,
      "clusterArn": "arn:aws:ecs:us-east-1:012345678910:cluster/default",
      "startedAt": 1476822833.998,
      "desiredStatus": "RUNNING",
      "taskDefinitionArn": "arn:aws:ecs:us-east-1:012345678910:task-definition/console-sample-app-dynamic-ports:1",
      "startedBy": "ecs-svc/9223370560032507596",
      "containers": [
        {
          "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/4df26bb4-f057-467b-a079-961675296e64",
          "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/default/1dc5c17a-422b-4dc4-b493-371970c6c4d6",
          "lastStatus": "RUNNING",
          "name": "simple-app",
          "networkBindings": [
            {
              "protocol": "tcp",
              "bindIP": "0.0.0.0",
              "containerPort": 80,
              "hostPort": 32774
            }
          ]
        },
        {
          "containerArn": "arn:aws:ecs:us-east-1:012345678910:container/e09064f7-7361-4c87-8ab9-8d073bbdbcb9",
          "taskArn": "arn:aws:ecs:us-east-1:012345678910:task/default/1dc5c17a-422b-4dc4-b493-371970c6c4d6",
          "lastStatus": "RUNNING",
          "name": "busybox",
          "networkBindings": []
        }
      ]
    }
  ]
}

Alternatives

No response

Additional Context

No response

Slack discussion

No response

Research

  • I have searched other issues in this repository and mine is not recorded.
@kurktchiev kurktchiev added enhancement New feature or request triage Default label assigned to all new issues indicating label curation is needed to fully organize. labels Sep 10, 2024
@eddycharly
Copy link
Member

@kurktchiev do you have a sample policy I can work with ?

@kurktchiev
Copy link
Author

Sure, if i want to add a container ARN to the message of the policy below, I do not have a way to

apiVersion: json.kyverno.io/v1alpha1
kind: ValidatingPolicy
metadata:
  name: validate-ecs-task-and-definition-memory-hard-limit
  annotations:
    policies.kyverno.io/title: Validate ECS Task Definition Memory Hard Limit
    policies.kyverno.io/category: ECS Best Practices
    policies.kyverno.io/severity: low
    policies.kyverno.io/description: >-
      This policy checks if Amazon Elastic Container Service
      (ECS) task definitions and tasks have a set memory limit for its container definitions.
      If a memory limit is not set for a container, it can consume excessive memory, potentially starving other containers running on the same host.
      Therefore, it is crucial to enforce a hard memory limit on each container to prevent resource contention.
      If a container exceeds its memory limit, it will be terminated by ECS.
spec:
  rules:
    - name: validate-ecs-task-memory-hard-limit
      match:
        all:
         - source: aws.ecs
         - detail-type: "ECS Task State Change"
         - detail:
            lastStatus: 'PROVISIONING'
      assert:
        all:
          - message: From Lambda - Memory limit for containers in the task should be set in the container definitions of its task
            check:
              detail:
                ~.(containers):
                    (!memory): false

@eddycharly
Copy link
Member

Thanks, it doesn't work directly with the payload you posted in the issue description right ?

@kurktchiev
Copy link
Author

It should if you modify the match and drop the source and detail-type

@eddycharly
Copy link
Member

@kurktchiev
Copy link
Author

Ok so using the above as an example, lets say container 1 fails, but container 2 doesn't. What you provide above just dumps out all container ARNs, which is better than nothing but not useful as I still am not pointing the user to the specific failure.

@kurktchiev
Copy link
Author

Or if we take the example further how can I pull out the Task ARN from the original JSON reference block, when a container ends up failing, considering that the Task list is an Array and the containers are an Array?

@eddycharly
Copy link
Member

Ok so you want to get the specific sub-element that caused the error right ?

@kurktchiev
Copy link
Author

Yes I want to contextualize my errors

@eddycharly
Copy link
Member

eddycharly commented Sep 11, 2024

This is a tricky one 🥵

Basically kyverno-json is all about projecting data and passing the projected data to children until we hit a leaf.
Contextualizing would mean doing something AFTER children have been processed (sort of prolog vs epilog).

I can imaging different solutions:

  • introduce a prolog syntax, allowing action AFTER children execution (this is only a technical block, doesn't provide the full solution but a good starting point)
  • introduce a more granular checks concept that could work the same as today but with smaller pieces so that you can access the context at the granularity you need

Example solution 1 (prolog):

      assert:
        all:
          - check:
              detail:
                ~.(containers)/(join(' ', ['container needs memory', containerArn])): # expression behind the / is the prolog
                    (!memory): false

Example solution 2 (small checks):

      checks:
         container-needs-memory:
            message: container needs memory {{ containerArn }}
            assert:
               (!memory): false
      assert:
        all:
          - with:
              list: containers
            checks:
            -  container-needs-memory

@eddycharly
Copy link
Member

Or maybe just this:

apiVersion: json.kyverno.io/v1alpha1
kind: ValidatingPolicy
metadata:
  name: validate-ecs-task-and-definition-memory-hard-limit
  annotations:
    policies.kyverno.io/title: Validate ECS Task Definition Memory Hard Limit
    policies.kyverno.io/category: ECS Best Practices
    policies.kyverno.io/severity: low
    policies.kyverno.io/description: >-
      This policy checks if Amazon Elastic Container Service
      (ECS) task definitions and tasks have a set memory limit for its container definitions.
      If a memory limit is not set for a container, it can consume excessive memory, potentially starving other containers running on the same host.
      Therefore, it is crucial to enforce a hard memory limit on each container to prevent resource contention.
      If a container exceeds its memory limit, it will be terminated by ECS.
spec:
  rules:
    - name: validate-ecs-task-memory-hard-limit
      match:
        all:
         - source: aws.ecs
         - detail-type: "ECS Task State Change"
         - detail:
            lastStatus: 'PROVISIONING'
      assert:
        all:
          - message: container needs memory {{ containerArn }}
            with:
               list: containers
            check:
              detail:
                  memory: {}

@kurktchiev
Copy link
Author

how would that work if we are in a nested array situation?

@eddycharly
Copy link
Member

you can project as much as you want

@kurktchiev
Copy link
Author

can you provide an example? maybe I am not understanding the vision here

@eddycharly
Copy link
Member

you rebuild the objects you need, leveraging jp flattening and projections features

@eddycharly
Copy link
Member

@eddycharly
Copy link
Member

I've been playing around with the idea and have a working prototype:

apiVersion: json.kyverno.io/v1alpha1
kind: ValidatingPolicy
metadata:
  name: validate-ecs-task-and-definition-memory-hard-limit
  annotations:
    policies.kyverno.io/title: Validate ECS Task Definition Memory Hard Limit
    policies.kyverno.io/category: ECS Best Practices
    policies.kyverno.io/severity: low
    policies.kyverno.io/description: >-
      This policy checks if Amazon Elastic Container Service
      (ECS) task definitions and tasks have a set memory limit for its container definitions.
      If a memory limit is not set for a container, it can consume excessive memory, potentially starving other containers running on the same host.
      Therefore, it is crucial to enforce a hard memory limit on each container to prevent resource contention.
      If a container exceeds its memory limit, it will be terminated by ECS.
spec:
  rules:
    - name: validate-ecs-task-memory-hard-limit
      assert:
        all:
          - with: >-
                ~.(tasks[].let $taskArn = taskArn in containers[].{taskArn:$taskArn,container:@})[]
            check:
                container:
                    memory: {}
            message: >-
                container {{ container.containerArn }}
                in task {{ taskArn }}
                needs memory

WDYT ?

@eddycharly eddycharly linked a pull request Sep 12, 2024 that will close this issue
@eddycharly
Copy link
Member

Prototype here #471

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request triage Default label assigned to all new issues indicating label curation is needed to fully organize.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants