Any good docs around http action runners

(Hnanchahal) #1

I am trying to create a workflow with some chained actions. To start i created a basic action that executes a GET and returns a string. If i take the url and invoke it through core.http everything works fine but when i register an action i see “Unable to schedule action” error.

Here is my yaml for the action

---
description: xxx
# Action to retrieve oauth token from the oauth api.
enabled: true
entry_point: ''
name: oauth
parameters:
  auth:
    type: string
  headers:
    type: object
  method:
    default: GET
    type: string
    enum:
    - GET
    - POST
    - PUT
    - DELETE
    immutable: true
  params:
    type: string
  timeout:
    default: 60
    type: integer
  url:
    type: string
runner_type: "http-request"
(Hnanchahal) #2

Here is the code for my action from the UI

{
  "description": "Fetch oAuth Token for API calls",
  "runner_type": "http-request",
  "tags": [],
  "enabled": true,
  "metadata_file": "actions/oauth.yaml",
  "pack": "sre_automation",
  "entry_point": "",
  "notify": {},
  "output_schema": {},
  "uid": "action:sre_automation:oauth",
  "parameters": {
    "username": {
      "type": "string",
      "description": "Username required by basic authentication."
    },
    "cookies": {
      "type": "object",
      "description": "Optional cookies to send with the request."
    },
    "headers": {
      "type": "object",
      "description": "HTTP headers for the request."
    },
    "url": {
      "required": true,
      "type": "string",
      "description": "URL to the HTTP endpoint."
    },
    "http_proxy": {
      "type": "string",
      "description": "URL of HTTP proxy to use (e.g. http://10.10.1.10:3128)."
    },
    "auth": {
      "type": "string"
    },
    "https_proxy": {
      "type": "string",
      "description": "URL of HTTPS proxy to use (e.g. http://10.10.1.10:3128)."
    },
    "params": {
      "type": "string"
    },
    "timeout": {
      "default": 60,
      "type": "integer"
    },
    "allow_redirects": {
      "default": false,
      "type": "boolean",
      "description": "Set to True if POST/PUT/DELETE redirect following is allowed."
    },
    "password": {
      "secret": true,
      "type": "string",
      "description": "Password required by basic authentication."
    },
    "method": {
      "default": "GET",
      "enum": [
        "GET",
        "POST",
        "PUT",
        "DELETE"
      ],
      "type": "string",
      "immutable": true
    },
    "verify_ssl_cert": {
      "default": true,
      "type": "boolean",
      "description": "Certificate for HTTPS request is verified by default using requests CA bundle which comes from Mozilla. Verification using a custom CA bundle is not yet supported. Set to False to skip verification."
    }
  },
  "ref": "sre_automation.oauth",
  "id": "5caf91b26cb8de5046e5dc76",
  "name": "oauth"
(W Chan) #3

Are there any other message from the api or action runner logs? You can also take a look at this example st2/weather.yaml at master · StackStorm/st2 · GitHub.

(Hnanchahal) #4

I actually took the weather.yaml as the samepl payload and just removed the default url. Since the action is not getting scheduled i don’t see any logs as a don’t have access to any execution id. Any other way i can take a look at the logs?

(W Chan) #5

tail, cat, grep… logs are text files. you can use whatever linux tool at your disposal.

(W Chan) #6

But of course, there’s an option. If you have a subscription for support, you can submit the logs to our support personnel.

(Hnanchahal) #7

Ok will reach out to the support channel. The documentation says:

Writing Custom Actions

An action is composed of two parts:

  1. A YAML metadata file which describes the action, and its inputs.
  2. A script file which implements the action logic

I suppose that http_request runner type would not need a script and the entry point would be blank. Am i correct in my assumption?

Because the action is not even getting scheduled, i don’t see much in the logs too. I cleaned up everything in logs directory and tried to ran this again but didnt saw any log files getting generated.

(Lindsay Hill) #8

Correct, http actions don’t need an entry point. The weather.yaml example is a good one.

Do any of your actions work? e.g. st2 run core.local cmd=date?

Do you see anything unusual when running st2ctl reload --register-actions?

What’s the output of st2 run <yourpack>.<yourhttpaction> <params>?

(Hnanchahal) #9

Thanks for your response. Everything else is working fine. I have custom action executing a shell script in the same pack that is getting triggered correctly.

The reload --register-actions worked fine without errors. In fact the st2 run on the same actions worked fine via cli:

vagrant@stackstorm:/var/log/st2$ st2 run sre_automation.oauth url=“https://automationasaservice.azurewebsites.net/api/FetchTokenFunction?code=****&&name=harsh
2019-04-12 04:21:01,373 WARNING - Unable to retrieve cached token from “/home/vagrant/.st2/token-st2admin” (user vagrant doesn’t have read access to this file). Subsequent requests won’t use a cached token meaning they may be slower.
2019-04-12 04:21:01,387 WARNING - Unable to write token to “/home/vagrant/.st2/token-st2admin” (user vagrant doesn’t have write access to this file). Subsequent requests won’t use a cached token meaning they may be slower.
.
id: 5cb0122d6cb8de3f0af28b6d
status: succeeded
parameters:
url: https://automationasaservice.azurewebsites.net/api/FetchTokenFunction?code=*****************************==&&name=harsh
result:
body: Hello, harsh
headers:
Content-Encoding: gzip
Content-Length: ‘129’
Content-Type: text/plain; charset=utf-8
Date: Fri, 12 Apr 2019 04:21:03 GMT
Vary: Accept-Encoding
parsed: false
status_code: 200

But with the same url when i try to run it via web ui, it gives me an error.

And the developer tools does not gives any details other than:

main.js:1 POST https://10.10.10.10/api/v1/executions 400 (Bad Request)
dispatchXhrRequest @ main.js:1
xhrAdapter @ main.js:1
dispatchRequest @ main.js:1
Promise.then (async)
request @ main.js:1
wrap @ main.js:1
_callee2$ @ main.js:1
tryCatch @ main.js:1
invoke @ main.js:1
prototype.(anonymous function) @ main.js:1
step @ main.js:1
(anonymous) @ main.js:1
F @ main.js:1
(anonymous) @ main.js:1
request @ main.js:1
handleRun @ main.js:1
handleRun @ main.js:1
handleRun @ main.js:1
onClick @ main.js:1
da @ main.js:1
ka @ main.js:1
la @ main.js:1
xa @ main.js:1
Ba @ main.js:1
za @ main.js:1
Ea @ main.js:1
Gd @ main.js:1
Nh @ main.js:1
Ob @ main.js:1
Jd @ main.js:1
Ph @ main.js:1
Id @ main.js:1
main.js:1 Unable to schedule action “sre_automation.oauth”.
main.js:1 Error: Request failed with status code 400
at createError (main.js:1)
at settle (main.js:1)
at XMLHttpRequest.handleLoad (main.js:1)

(Hnanchahal) #10

Any pointers as to why the actions would succeed via cli but fail to schedule via UI?

(Lindsay Hill) #11

It’s not a failure case I’ve seen before. If I was debugging it, I would start by clearing browser cache, testing again, if it still fails, then looking at what nginx & st2api logs say.

The only other thing I can think of would be something related to how the client-side JS is capturing & encoding that url parameter. Just for kicks, try it with a very simple URL? (google.com or similar) I saw some client-side JS bugs about 18 months ago related to certain http runner handling, but I thought they were all fixed a while ago.

(Hnanchahal) #12

I will try digging into he logs. I did tried with google.com and had the same failure. The strange thing was that the same url succeeds when i use the core http action.

(Hnanchahal) #13

Here is the snapshot of history for those action runs when i run them using cli. So technically i don’t see the action as the culprit. Would it be possible for you to take this yaml and install the action at your end and try to replicate this, just passing google.com:


description: Test Http runner
enabled: true
entry_point: ‘’
name: oauth
parameters:
auth:
type: string
headers:
type: object
method:
default: GET
type: string
enum:
- GET
- POST
- PUT
- DELETE
immutable: true
params:
type: string
timeout:
default: 60
type: integer
url:
type: string
debug:
type: boolean
runner_type: “http-request”

(W Chan) #14

Can you format the YAML correctly above and wrap the code with triple “`”? This at least makes it easier for us to copy and paste if you want us to test. Use the preview in the reply editor to see if you format the code correctly.

Example:

type: string
enum:
  - GET
  - POST
  - PUT
  - DELETE
(Hnanchahal) #15
---
description: Fetch oAuth Token for API calls.
# Action to retrieve oauth token from the oauth api.
enabled: true
entry_point: ''
name: oauth
parameters:
  auth:
    type: string
  headers:
    type: object
  method:
    default: GET
    type: string
    enum:
    - GET
    - POST
    - PUT
    - DELETE
    immutable: true
  params:
    type: string
  timeout:
    default: 60
    type: integer
  url:
    type: string
  debug:
    type: boolean
runner_type: "http-request"
(Lindsay Hill) #16

OK, I did some quick tests, and I can reproduce that behavior. I’m not sure exactly what’s going on, but I suspect it’s something related to the additional parameters you’ve added to oauth.yaml, and possibly the mismatch between those parameter types and what core.http is expecting.

If I reduce oauth.yaml to this, it works:

---
description: Fetch oAuth Token for API calls.
# Action to retrieve oauth token from the oauth api.
enabled: true
entry_point: ''
name: oauth
parameters:
  url:
    type: string
    required: true
runner_type: "http-request"

Note that I’m setting url to required: true, because the underlying http runner expects that parameter.

If you’re writing an action that relies on the http runner, only include the parameters you want to over-ride. All the others will still be there, as they come in from the underlying runner.

My guess is you want to do something like this:

url:
    type: string
    immutable: true
    default: 'some_url'
    required: true
(Lindsay Hill) #17

If you don’t want to set any of the parameters available with core.http to immutable, then you don’t really need a separate action at all.

Just use core.http in your workflows, with input url=

(Hnanchahal) #18

Thanks. Will try these out.