capactio / capact

Simple way to manage applications and infrastructure.
https://capact.io
Apache License 2.0
80 stars 19 forks source link

Add common TypeInstance injection #646

Closed mkuziemko closed 2 years ago

mkuziemko commented 2 years ago

Description

Changes proposed in this pull request:

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')
    2. 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
    3. 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)