goss-org / goss

Quick and Easy server testing/validation
https://goss.rocks
Apache License 2.0
5.6k stars 472 forks source link

Test http with POST data #375

Closed abgoldberg closed 4 years ago

abgoldberg commented 6 years ago

It looks like the http type of test only does a GET. Is there a known fork or branch that adds support for POST? Is there a drawback to using a command/curl test instead?

Presumably it's not that complex to add standard http POST support, and I could take a stab at it, but I'm not a go developer so might need some pointers in how to rebuild, etc.

jedrzej-andrykowski commented 5 years ago

It will be cool if there will be possibility to check also PUT and PATCH.

Value of key method could overwrites default GET method:

http:
  http://localhost/health:
    method: PUT
    status: 200
jedrzej-andrykowski commented 5 years ago

The workaround is to create .sh with curl and run it as command resource:

http_put.sh:

curl -X PUT --header 'Content-Type: application/json' -d '[ \
   { \
     "foo": "bar"
   } \
 ]' 'http://localhost/health'

goss.yaml

command:
  ./http_put.sh:
    exit-status: 0
    stdout:
      - '{"some":"response"}'

But of course native solution will be better ;)

sshipway commented 4 years ago

The HTTP test really needs to be expanded to allow attributes for -

Additional support to allow the request-body to be specified as key/value pairs to be encoded into JSON would be nice, as well as tests on the returned code as JSON (for API testing), but that is a bit more complex ;)

aelsabbahy commented 4 years ago

This feels like scope creep. Goss is focused on OS testing and is not intended to be a substitute for a rest testing framework, I've recently created a contributing.md to clarify the scope of goss: https://github.com/aelsabbahy/goss/blob/master/.github/CONTRIBUTING.md#feature-requests

There are many tools out there that are specialized in REST testing:

I'm willing to add some features to the http test that are useful for general usecases/os testing, anything beyond that should be delegated to a specialized tool.

sshipway commented 4 years ago

I suppose you could see it that way... we use Goss as a smoketest to run on a system after OS patching or automated install; so we want to run a couple of basic sanity tests of the system, and of connectivity.

I agree that you'd use a different tool for doing a full system test; so Goss support for JSON and REST, cookie preservation or multi-step simulations, are probably a bit too far. Being able to specify the other items (different endpoint from that in URL, authentication, message body, method) is important, though, as properly locked-down systems may not be able to run a simple check without some of these.

It is also very common for a cluster of web servers to be behind a load balancer, so after patching you would want to verify the local server response before rejoining it into the cluster - but the current test would go via the DNS name which points at the load balancer. Some web servers rely on the Host header so you can't just use localhost.

Of course there is a workaround - just writing a shellscript to do the test - but it would be nice to have the settings available for those who need them, if they are not too hard to add.

aelsabbahy commented 4 years ago

Thanks for clarifying your use case.

Agree 100% on your last message and I'm glad we're on the same page (I.e. Goss is testing the local machine it's running on). It's awesome you're using Goss as a smoke test, hope it's doing well in that role and would like Goss to continue to meet your needs.

Can you explain all the different features you'd like in the http test that would aid you in accomplishing that goal?

sshipway commented 4 years ago

We have Goss as an integral part of our operations patching and change processes now; the configuration is built automatically through puppet by merging configuration sets based on host role.

For the HTTP tests, I'd like to be able to do the following -

http:
  servertest:
    url: https://ourapp.company.com/index.html
    credentials:
      user: testuser
      password: testpassword
    server: 127.0.0.1
    port: 8000
    status: 200

This would allow basic auth on the page (simpler to configure than giving the header explicitly) and would enable us to test against just the local member of the cluster (which runs on a nonstandrd port, behind a load balancer). The full URL is necessary to get the Host header handled properly and because the application looks for it. Again, we could define some of the headers explicitly, but this is simpler. Abstracting out the url also allows cases where you want to override the URL but keep all other settings - this more applies to our puppet management of the gossfile which does a deepmerge, but its the same rationale I had for doing this in the exec resource type.

http:
  weakforced:
    url: http://localhost:8084/?command=getDBStats
    method: post
    credentials:
      user: wforce
      password: testpassword
    request-body: |
      {"login":"testuser@testdomain"}
    request-headers:
      - "Content-Type: application/json"
    status: 200
    body:
      - /"blacklisted": false/

So this example allows specifying a POST method and supplying a request body, in order to do a basic sanity test of the Weakforced app. In fact we already do this via goss using a script, but it would be preferable to have the ability built in. Other systems may need PUT, or may use form encoding in the body. By adding request-body and method this sort of test can be done natively.

Being able to perform basic sanity tests against a remote API is useful when testing a host that runs an app which relies on the remote service. We can already perform remote tests against HTTP, DNS, and TCP but being able to do POST and Authentication checks would allow our tests on (e.g.) our mail platform to verify connectivity to the remote weakforced API on which it depends.

aelsabbahy commented 4 years ago

The latest version of goss handles your first use case I think, but requires setting the headers explicitly. (Username, password, Request headers are all supported).

https://github.com/aelsabbahy/goss/blob/master/docs/manual.md#http

Adding the method, request-body, and url seems like a useful enhancement.

I'm not a fan of the server/port attributes though.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

aelsabbahy commented 4 years ago

Consolidating chat to this ticket: https://github.com/aelsabbahy/goss/issues/484