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

Chained calls and JSON #19

Closed
marcosQuesada opened this issue Apr 20, 2024 · 1 comment
Closed

Chained calls and JSON #19

marcosQuesada opened this issue Apr 20, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@marcosQuesada
Copy link

marcosQuesada commented Apr 20, 2024

What happened?

I'm implementing a POC with multiple calls, where the first call gets a token, second one uses that token as Authorization Header, I do have doubts about how to handle json responses and patching json body on other requests.

I do have 2 questions:

  • How to extract a value from a DisposableRequest status.response when Json is returned?
  • How to handle Json body data? My intention is to pass in the second request some values patching the body, Is it posible? Example: Patch from a ConfigMap field to a value in the JSON body
    This does not work, body is a Json string, and makes sense...
  - patchesFrom:
      apiVersion: v1
      kind: ConfigMap
      name: foobar
      namespace: default
      fieldPath: data.foo-name
    toFieldPath: spec.forProvider.payload.body.name

Glad to hear any indication about how body is intended to be used with JSON data, or if there's any better way of handling authentication or multiple request please let me know.

How can we reproduce it?

In this simple example the DisposableRequest calls an auth endpoint that returns a token as a string, then the token is patched in Authorization header, works perfect. But, how to handle a json response? example: {"token": "ewjhwekjwh..."} .

Example:

apiVersion: http.crossplane.io/v1alpha1
kind: DisposableRequest
metadata:
  name: auth-request
  namespace: default
spec:
  deletionPolicy: Orphan
  forProvider:
    # The 'expectedResponse' field is optional. If used, also set 'rollbackRetriesLimit', which determines the number of HTTP requests to be sent until the jq query returns true.    
    # expectedResponse: '.Body.job_status == "success"'
    insecureSkipTLSVerify: true
    waitTimeout: 5m
    rollbackRetriesLimit: 5
    url:  http://172.17.0.1:8081/api/v1/auth
    method: GET
    body: ""
    headers:
      Content-Type:
      - "application/json"
  providerConfigRef:
    name: http-conf
---
apiVersion: kubernetes.crossplane.io/v1alpha2
kind: Object
metadata:
  name: multi-request
spec:
  references:
  - dependsOn:
      apiVersion: http.crossplane.io/v1alpha1
      kind: DisposableRequest
      name: auth-request
      namespace: default  
  - patchesFrom:
      apiVersion: http.crossplane.io/v1alpha1
      kind: DisposableRequest
      name: auth-request
      namespace: default  
      fieldPath: status.response.body
    toFieldPath: spec.forProvider.headers.Authorization[0]
  forProvider:
    manifest:
      apiVersion: http.crossplane.io/v1alpha1
      kind: Request
      metadata:
        name: cmd-request
      spec:
        forProvider:
          headers:
            Content-Type:
              - "application/json"
            Accept:
              - "application/json"
            Authorization:
              - "Basic BASE64_ENCODED_USER_CREDENTIALS"
          payload:
            baseUrl: http://172.17.0.1:8081/api/v1/pets
            body: |
              {
                "id": 111344321112,
                "name": "zzxxxxxxxxxxxxx",
                "color": "color-12",
                "price": 1232119,
                "state": "foo-state-2"
              }

          mappings:
            - method: "POST"
              url: .payload.baseUrl
              body: |
                {
                  "id": .payload.body.id,
                  "name": .payload.body.name, 
                  "color": .payload.body.color,
                  "price": .payload.body.price,
                  "state": .payload.body.state
                }
            - method: "GET"
              url: (.payload.baseUrl + "/" + .response.body.name)
            - method: "PUT"
              url: (.payload.baseUrl + "/" + .response.body.name)
              body: |
                {
                  "id": .payload.body.id,
                  "name": .payload.body.name, 
                  "color": .payload.body.color,
                  "price": .payload.body.price,
                  "state": .payload.body.state
                }
            - method: "DELETE"
              url: (.payload.baseUrl + "/" + .response.body.name)
        providerConfigRef:
          name: http-conf     
  providerConfigRef:
    name: kubernetes-provider

What environment did it happen in?

Crossplane version: 1.14.0

Using:

  • provider-http: v0.2.0
  • provider-kubernetes: crossplanecontrib/provider-kubernetes:main
  • kind cluster
@marcosQuesada marcosQuesada added the bug Something isn't working label Apr 20, 2024
@arielsepton
Copy link
Member

arielsepton commented Apr 21, 2024

Regarding your first question, since you're using provider-kubernetes patches-from-resource, you might want to open an issue there, perhaps requesting a "transforms" key similar to what is supported in compositions nowadays. You can refer to this example for context: link to example.

Also, there are plans to add patches-from-secrets feature in both DisposableRequest and Request.

In the meantime, perhaps using compositions (specifically function-go-templating) can help solve your patching problem. Simply create a composition of both requests and patch data from the first request to the second using the following syntax:

token: Bearer {{ (.observed.resources.loginrequest.resource.status.response.body | fromJson).token }}

As for your second question, your implementation looks good and should work fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants