Skip to content

Add common TypeInstance injection#646

Merged
mkuziemko merged 12 commits intocapactio:mainfrom
mkuziemko:common_ti_injection
Mar 8, 2022
Merged

Add common TypeInstance injection#646
mkuziemko merged 12 commits intocapactio:mainfrom
mkuziemko:common_ti_injection

Conversation

@mkuziemko
Copy link
Copy Markdown
Collaborator

@mkuziemko mkuziemko commented Feb 28, 2022

Description

Changes proposed in this pull request:

  • modify graphql to support TypeInstance injection,
  • merge policies with the new default field,
  • add new tests connected with Type Instance injection

More information about the structure of the new fields and detailed descriptions can be found here.

Testing

Matermost installation

To test it locally, the Matermost installation guide can be used, with a change of the Policy step:

interface:
  rules: # Configures the following behavior for Engine during rendering Action
    - interface:
        path: cap.interface.database.postgresql.install
      oneOf:
         - implementationConstraints:
             attributes:
               - path: "cap.attribute.cloud.provider.aws"
    - interface:
        path: cap.*
      oneOf:
        - implementationConstraints:
            requires:
              - path: "cap.core.type.platform.kubernetes"
        - implementationConstraints: {} # fallback to any Implementation
  default:
    inject:
      requiredTypeInstances:
      - id: "59d20d01-a096-4a06-a849-990bd0ddc3a8" # id of the AWS TypeInstance ID
        description: "AWS credentials" 

Backend testing

Note: For testing use hub-manifests from here. During testing, I noticed one possible issue with a manifest( PR is on the way).

  1. Build Capact CLI: make build-tool-cli and use for all below commands.

  2. Create TypeInstances for update and download:

    cat > /tmp/download-ti.yaml << ENDOFFILE
    typeInstances:
      - alias: "download"
        typeRef:
          path: cap.type.capactio.capact.validation.download
          revision: 0.1.0
        value:
          key: "true"
    ENDOFFILE
    export DOWNLOAD_TI=$(capact ti create -f /tmp/download-ti.yaml -ojson | jq -r '.[] | select(.alias == "download") | .id')
    cat > /tmp/update-ti.yaml << ENDOFFILE
    typeInstances:
      - alias: "update"
        typeRef:
          path: cap.type.capactio.capact.validation.update
          revision: 0.1.0
        value:
          key: "true"
    ENDOFFILE
    export UPDATE_TI=$(capact ti create -f /tmp/update-ti.yaml -ojson | jq -r '.[] | select(.alias == "update") | .id')
  3. Create Helm storage TypeInstance:

    cat > /tmp/helm-storage.yaml << ENDOFFILE
    typeInstances:
      - alias: "helm"
        typeRef:
          path: cap.type.helm.storage
          revision: 0.1.0
        value:
          contextSchema: {"\$schema":"http://json-schema.org/draft-07/schema","additionalProperties":false,"properties":{"name":{"\$id":"#/properties/context/properties/name","type":"string"},"namespace":{"\$id":"#/properties/context/properties/namespace","type":"string"}},"required":["name","namespace"],"type":"object"}
          acceptValue: true # just for demo purposes
          url: "helm-release.default:50051"
    ENDOFFILE
    export HELM_STORAGE_TI=$(capact ti create -f /tmp/helm-storage.yaml -ojson | jq -r '.[] | select(.alias == "helm") | .id')
  4. Create Action with Helm storage defined in default Policy.

    1. Create required TypeInstance:

      cat > /tmp/inject-ti.yaml << ENDOFFILE
      typeInstances:
        - alias: "inject"
          typeRef:
            path: cap.type.capactio.capact.validation.single-key
            revision: 0.1.0
          value:
            key: "true"
      ENDOFFILE
      export INJECT_TI=$(capact ti create -f /tmp/inject-ti.yaml -ojson | jq -r '.[] | select(.alias == "inject") | .id')
    2. Update Global Policy:

      cat > /tmp/inject-storage-policy.yaml << ENDOFFILE
      interface:
        default:
          inject:
              requiredTypeInstances:
              - description: Test TypeInstance
                id: ${INJECT_TI}
              - description: Helm backend TypeInstance
                id: ${HELM_STORAGE_TI}
        rules:
        - interface:
            path: cap.interface.capactio.capact.validation.action.passing
          oneOf:
          - implementationConstraints:
              attributes:
              - path: cap.attribute.capactio.capact.validation.policy.most-preferred
              requires:
              - path: cap.type.capactio.capact.validation.single-key
          - implementationConstraints:
              path: cap.implementation.capactio.capact.validation.action.passing-a
        - interface:
            path: cap.*
          oneOf:
          - implementationConstraints: {}
      typeInstance:
        rules: []
      ENDOFFILE
      capact policy apply -f /tmp/inject-storage-policy.yaml
    3. Create Action input:

      cat > /tmp/act-input-ti.yaml << ENDOFFILE
      typeInstances:
        - name: "testUpdate"
          id: ${UPDATE_TI}
        - name: "testInput"
          id: ${DOWNLOAD_TI}
      ENDOFFILE
    4. Run Action

      capact act create cap.interface.capactio.capact.validation.action.passing --name inject-storage --type-instances-from-file /tmp/act-input-ti.yaml

      capact act run & capact act watch

    5. Get Action output TypeInstances:

      capact act get inject-storage -ojson | jq '.Actions[0].output.typeInstances'

      Example output:

      [
        {
          "backend": {
            "abstract": false,
            "id": "e9d424b3-c55d-4b02-9e92-9c736b96f98e"
          },
          "id": "cdf4ff38-f66e-4d03-a6ed-1093f154d3af",
          "typeRef": {
            "path": "cap.type.capactio.capact.validation.upload",
            "revision": "0.1.0"
          }
        }
      ]

Check with capact ti get that uses were properly set for a given Storage Backends.

  1. Create Action with Helm storage defined in default Policy and Policy Rule.
    1. Create one more Helm Storage TI:
    export HELM_STORAGE_TI_2=$(capact ti create -f /tmp/helm-storage.yaml -ojson | jq -r '.[] | select(.alias == "helm") | .id')
    1. Repeat all the steps from the previous scenario with change of Policy:
    cat > /tmp/inject-storage-policy.yaml << ENDOFFILE
    interface:
      default:
        inject:
            requiredTypeInstances:
            - description: Test TypeInstance
              id: ${INJECT_TI}
            - description: Helm backend TypeInstance
              id: ${HELM_STORAGE_TI}
      rules:
      - interface:
          path: cap.interface.capactio.capact.validation.action.passing
        oneOf:
        - implementationConstraints:
            attributes:
            - path: cap.attribute.capactio.capact.validation.policy.most-preferred
            requires:
            - path: cap.type.capactio.capact.validation.single-key
          inject:
            requiredTypeInstances:
            - description: Helm backend TypeInstance
              id: ${HELM_STORAGE_TI_2}
        - implementationConstraints:
            path: cap.implementation.capactio.capact.validation.action.passing-a
      - interface:
          path: cap.*
        oneOf:
        - implementationConstraints: {}
    typeInstance:
      rules: []
    ENDOFFILE
    1. Check that backend TypeInstance ID is the same as HELM_STORAGE_TI_2
    $ capact act get inject-storage -ojson | jq '.Actions[0].output.typeInstances'
     [
       {
         "backend": {
           "abstract": false,
           "id": "4344336e-8e52-41fa-b531-8e926f51333e"
         },
         "id": "930053a4-603e-4607-b9a5-4089c4615be1",
         "typeRef": {
           "path": "cap.type.capactio.capact.validation.upload",
           "revision": "0.1.0"
         }
       }
     ]
    $ echo $HELM_STORAGE_TI_2
    4344336e-8e52-41fa-b531-8e926f51333e

Related issue(s)

@pkosiec pkosiec self-assigned this Feb 28, 2022
Copy link
Copy Markdown
Collaborator

@pkosiec pkosiec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't test it, but I noticed a few potential problems with the current implementation.

Before next review iteration, please make sure that:

  • User can override default injections from Global Policy via Action policy (the interface.default are merged - but merged in a way, the typeRefs are unique so there are no uncertainty which TypeInstance will be actually injected in the workflow)
  • User can override default injections (interface.default) using interface.rules[].inject, so that the TypeInstances from interface.rules[].inject are preferred over the ones from interface.default.
  • In the PR description, please write another testing scenario for a storage backend (as this functionality will be mostly used for that). You can get some inspiration from this testing scenario, as it will be mostly the same, but defined in different place of the Policy:
    #630
  • The documentation on capactio/website is updated
  • Make sure the policy merging is tested in unit tests (as it currently lacks any tests for such behavior).
  • The integration test is fixed

Thanks! 🙂

Comment thread internal/k8s-engine/graphql/domain/policy/converter.go Outdated
Comment thread pkg/hub/client/policy_enforced_client.go
Comment thread test/e2e/action_test.go
Comment thread pkg/hub/client/policy_enforced_client.go Outdated
Comment thread pkg/hub/client/policy_merger.go Outdated
@mkuziemko mkuziemko added area/engine Relates to Engine area/hub Relates to Hub WIP Work in progress labels Mar 2, 2022
@mkuziemko mkuziemko force-pushed the common_ti_injection branch from 7e1c1aa to 971f410 Compare March 2, 2022 23:03
@mkuziemko mkuziemko removed the WIP Work in progress label Mar 3, 2022
Copy link
Copy Markdown
Collaborator

@pkosiec pkosiec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a few last items 🙂

Comment thread pkg/hub/client/policy_merger.go Outdated
Comment thread pkg/hub/client/policy_merger_test.go
Comment thread pkg/hub/client/policy_merger_test.go
Comment thread pkg/hub/client/policy_merger.go
@mkuziemko mkuziemko added the WIP Work in progress label Mar 4, 2022
@mkuziemko mkuziemko force-pushed the common_ti_injection branch from f800079 to 599982b Compare March 6, 2022 20:50
@mkuziemko mkuziemko removed the WIP Work in progress label Mar 6, 2022
Comment thread pkg/hub/client/policy_enforced_client.go Outdated
Copy link
Copy Markdown
Collaborator

@pkosiec pkosiec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested with the small commit applied (pkosiec@7fe8a06 - it renames some methods + removes e.mergedPolicy) and works well 👍 Please just apply the commit to make sure we have properly cleaned up our mergedPolicy. Thanks!

Comment thread pkg/hub/client/policy_enforced_client.go Outdated
@mkuziemko mkuziemko force-pushed the common_ti_injection branch from f4ba454 to efcf17c Compare March 7, 2022 22:03
@mkuziemko mkuziemko merged commit 955dd17 into capactio:main Mar 8, 2022
@mkuziemko mkuziemko deleted the common_ti_injection branch March 8, 2022 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/engine Relates to Engine area/hub Relates to Hub

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants