bbva / kapow Goto Github PK
View Code? Open in Web Editor NEWKapow! If you can script it, you can HTTP it.
Home Page: https://kapow.readthedocs.io
License: Apache License 2.0
Kapow! If you can script it, you can HTTP it.
Home Page: https://kapow.readthedocs.io
License: Apache License 2.0
The --url
flag and KAPOW_URL
env var are no longer sufficient because the control server which they pointed to has been split in two: control and data.
Thus, we need to honour this split. Let's be specific:
kapow route
should honour the KAPOW_CONTROL_URL
env var and the --control-url
flag, with a default value of http://localhost:8081
.
kapow server
should honour the --control-bind
flag, with a default value of localhost:8081
.
kapow server
should honour the --bind
flag, or its alias --user-bind
, with a default value of localhost:8080
.
kapow server
should honour the --data-bind
flag, with a default value of localhost:8082
.
kapow get|set
should honour the KAPOW_DATA_URL
env var and the
--data-url
flag, with a default value of http://localhost:8082
.
For completion, although this hasn't changed, kapow get|set
should honour the KAPOW_HANDLER_ID
env var and the --handler-id
flag. No default value.
Note that flags take precedence over env vars.
This is disturbing 😅; please use standard metasyntactic variables (foo, bar, baz...) or descriptive text content (examplebody, exampleheader, ...) as example data for tests.
Ask yourself, what iptables would do?
Maybe avoid a negative index throwing an error?
What should the behaviour be when an error occurs accesing the content of a file?
GO's implementation doesn't make any header key/value encoding validation. We need to add this validation.
*.pow
files can't be executed directly.
They should be executed either running kapow server foo.pow
or within an interactive kapow
shell. Otherwise, it won't work, and it fails with a call stack trace, like this:
$ ./nmap.pow
Traceback (most recent call last):
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/bin/kapow", line 7, in <module>
exec(compile(f.read(), __file__, 'exec'))
File "/home/pancho/sandbox/bbva/kapow/poc/bin/kapow", line 632, in <module>
kapow()
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/pancho/sandbox/bbva/kapow/poc/bin/kapow", line 573, in route_add
"command": source})
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/requests/api.py", line 116, in post
return request('post', url, data=data, json=json, **kwargs)
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/requests/sessions.py", line 519, in request
prep = self.prepare_request(req)
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/requests/sessions.py", line 462, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/requests/models.py", line 313, in prepare
self.prepare_url(url, params)
File "/home/pancho/.local/share/virtualenvs/poc-DayB6nJe/lib/python3.7/site-packages/requests/models.py", line 387, in prepare_url
raise MissingSchema(error)
requests.exceptions.MissingSchema: Invalid URL 'None/routes': No schema supplied. Perhaps you meant http://None/routes?
We should handle this case more gracefully, and return an explicit error message when it happens.
NOTES:
One way to solve this would be:
*.pow
files:#!/usr/bin/env -S kapow server
.KAPOW_URL
is already defined, which happens when running within an interactive kapow
shell.This could be hard to implement, so we could settle for less:
#!/usr/bin/env -S kapow server
is in place and you try to run it within an interactive kapow
shell, exit notifying the user that the .pow
file shoud be run like this: bash -c foo.pow
.In order to simplify the Kapow! endpoint creation process a debug operation flag will be great. In this operation mode Kapow! will respond you with full stacktrace of every error.
This debug operation must be avoid on production environments.
As Kapow admin I want to replicate a running kapow from a newly fresh kapow, even if i have no original script files.
kapow/internal/server/user/state.go
Line 54 in 034a5ab
On an empty env gherking-lint is not found. Maybe need pipenv install --dev and added dependency.
As discussed we let the "client" in this case the control API layer to generate the route ID to allow in the future users to give a custom routeID name.
Maybe the job of the user state layer is only to validate data on append to avoid collisions or malformed inputs.
Related to #39
The GO's implementation doesn't allow to decode form encoded data sent in a request with an arbitrary method and/or content type other than "application/x-www-form-urlencoded". This is needed for Kapow! semantic so it MUST be changed in the future.
Implement a ParseForm function that doesn't care about method nor Content-Type.
GO's current implemetation doesn't allow to set an arbitrary response status trough WriteHeader. We need a way by which circumvent this.
Add a note in the specification syaing that cookie keys are case sensitive.
Add a new /route
branch to the resources tree so the external process can query not only the current request data, but the data of the route its being processed.
As suggested by @hhurtado.
We need to define how are we going to return the values associated to a param (/request/params/{name})
Line 31 in be6a2ef
Using this .pow file:
bash kapow route add -X POST /tools/network/nmap -c 'nmap -v -Pn -n -sS -sS -A "$(request /form/ip)" | response /stream'
After launch Kapow! this above rules and launch 3 executions and cancel them (with a CTRL+C), the Kapow! service reject connections until one nmap execution finishes.
It appears that, when CTRL+C was break the connection with Kapow! serve, it doesn't stop the nmap background process.
Screenshot of curl calling the service:
Screenshot of the Kapow! console:
What should the return code be when there is no form in the target request and access to a field is requested?
Implement a test suite to check any Kapow! implementation compliance against the specification. The test suite must contain at least:
This test suite must be independent of the implementation and cannot be coupled with the current or future implementations under any circumstances.
Line 9 in a865ade
Line 43 in be6a2ef
The code is a PoC, a dirty one. No test. No desing. Just a prof that is possible to do Kapow!.
The best tech stack for Kapow! is out there, and we'll find it.
When you try lo load more than one .pow file, using *.pow, if you don't put "\n" at ending of each file, kapow doesn't works.
As per the spec, this call should return the actual route inserted, with the final values for all its fields.
kapow/internal/server/user/state.go
Line 33 in f5d7521
Co-authored-by: César Gallego [email protected]
Continue the works in branch tutorial
At this moment setResponseHeader adds values to the header with every call (a PUT). Should we use POST for this and PUT to overwrite?
Line 49 in be6a2ef
Implement in the E2E suite the success feature on data spec.
kapow/internal/client/route_remove.go
Line 9 in a865ade
Partially implemented in branch feature/respond.
Add a mechanism to avoid responding when the shell finishes.
Kapow! have no way to recover the original creation info of a given endpoint. This will be a good enhancement because if this endpoint gives you the data with the same format you can feed another Kapow! instance with the info of other Kapow!
GO's implementation doesn't make any cookie key/value encoding validation. We need to add this validation.
The default values for the Route entity must be set on the create/insert handler as the server has all the information needed to do so
At this moment setResponseCookie adds values to the cookie with every call (a PUT). Should we use POST for this and PUT to overwrite?
When the shell started by Kapow! server ends with error this error code is not returned from Kapow! so if exited with error the error code is missed.
Currently Kapow! is a PoC and the interpreter was written in Python.
The idea for a next improved version is: Distribute Kapow! as a static binary without any library dependency to improve the portability
We need to write the route specification to make clear what attibutes are mandatory and the attributes domain (if any is needed)
As per the spec¹, the call should return a JSON body with the info
of the newly created route. Should we consider this in the mocked server
and in the test?
¹: https://github.com/BBVA/kapow/tree/master/spec#insert-a-route
kapow/internal/client/route_add_test.go
Line 24 in ee00a7b
Too specific errors are too complex rigth now. Instead 400 and several 422 throw only a 422 malformed entity.
Currently the data API only allows to set status code, there is no way to set a reason phrase. As said by specification the reason phrase is an important element in order to provide valuable information to human beings so Kapow! users should be allowed to set this value.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.