Skip to content

Commit

Permalink
Merge branch 'feature/exec-pow-files'
Browse files Browse the repository at this point in the history
Closes: #95 and two stones

Co-authored-by: Roberto Abdelkader Martínez Pérez <robertomartinezp@gmail.com>
  • Loading branch information
panchoh and nilp0inter committed Dec 24, 2020
2 parents 989bf2e + 68a25e6 commit 100b41f
Show file tree
Hide file tree
Showing 41 changed files with 271 additions and 175 deletions.
6 changes: 0 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,5 @@ acceptance: install
deps:
@echo "deps here"

docker: build
cp $(BUILD_DIR)/$(BINARY_NAME) $(DOCKER_DIR)/
cp $(DOCS_DIR)/*.pow $(DOCKER_DIR)/
cd $(DOCKER_DIR) && docker build -t kapow .
cd ..

clean:
rm -rf $(BUILD_DIR) $(OUTPUT_DIR) $(DOCKER_DIR)/*
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@ us easily **turn that into an HTTP API**.
### Let's see this with an example

We want to expose **log entries** for files not found on our **Apache Web
Server**, as an HTTP API. With *Kapow!* we just need to write this file:
Server**, as an HTTP API. With *Kapow!* we just need to write this
*executable* script:

```bash
[apache-host]$ cat search-apache-errors.pow
``` console
[apache-host]$ cat search-apache-errors
#!/usr/bin/env sh
kapow route add /apache-errors - <<-'EOF'
cat /var/log/apache2/access.log | grep 'File does not exist' | kapow set /response/body
cat /var/log/apache2/access.log | grep 'File does not exist' | kapow set /response/body
EOF
[apache-host]$ chmod +x search-apache-errors
```

and then, run it using *Kapow!*

```bash
[apache-host]$ kapow server --bind 0.0.0.0:8080 search-apache-errors.pow
[apache-host]$ kapow server --bind 0.0.0.0:8080 search-apache-errors
```

finally, we can read from the just-defined endpoint:
Expand Down
20 changes: 13 additions & 7 deletions docs/source/examples/handling_http_requests.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ In this example we'll be adding the header ``X-Content-Type-Options`` to the res
.. code-block:: console
:linenos:
$ cat sniff.pow
$ cat sniff-route
#!/usr/bin/env sh
kapow route add /sec-hello-world - <<-'EOF'
kapow set /response/headers/X-Content-Type-Options nosniff
kapow set /response/headers/Content-Type text/plain
echo this will be interpreted as plain text | kapow set /response/body
EOF
$ kapow server nosniff.pow
$ kapow server nosniff-route
Testing with :program:`curl`:

Expand Down Expand Up @@ -67,7 +68,8 @@ Uploading a file using *Kapow!* is very simple:
.. code-block:: console
:linenos:
$ cat upload.pow
$ cat upload-route
#!/usr/bin/env sh
kapow route add -X POST /upload-file - <<-'EOF'
kapow get /request/files/data/content | kapow set /response/body
EOF
Expand All @@ -89,7 +91,8 @@ In this example we reply the line count of the file received in the request:
.. code-block:: console
:linenos:
$ cat count-file-lines.pow
$ cat count-file-lines
#!/usr/bin/env sh
kapow route add -X POST /count-file-lines - <<-'EOF'
# Get sent file
Expand Down Expand Up @@ -121,7 +124,8 @@ You can specify custom status code for `HTTP` response:
.. code-block:: console
:linenos:
$ cat error.pow
$ cat error-route
#!/usr/bin/env sh
kapow route add /error - <<-'EOF'
kapow set /response/status 401
echo -n '401 error' | kapow set /response/body
Expand Down Expand Up @@ -158,7 +162,8 @@ In this example we'll redirect our users to `Google`:
.. code-block:: console
:linenos:
$ cat redirect.pow
$ cat redirect
#!/usr/bin/env sh
kapow route add /redirect - <<-'EOF'
kapow set /response/headers/Location https://google.com
kapow set /response/status 301
Expand Down Expand Up @@ -196,7 +201,8 @@ In the next example we'll set a cookie:
.. code-block:: console
:linenos:
$ cat cookie.pow
$ cat cookie
#!/usr/bin/env sh
kapow route add /setcookie - <<-'EOF'
CURRENT_STATUS=$(kapow get /request/cookies/kapow-status)
Expand Down
4 changes: 2 additions & 2 deletions docs/source/examples/https_mtls.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ command line:

.. code-block:: console
$ kapow server --keyfile path/to/keyfile --certfile path/to/certfile foobar.pow
$ kapow server --keyfile path/to/keyfile --certfile path/to/certfile foobar-route
Now *Kapow!* is listening on its default port (8080) accepting requests over
HTTPS. You can test it with the following command:
Expand All @@ -60,7 +60,7 @@ CA certificate issuing the client certificates we want to accept with the

.. code-block:: console
$ kapow server --keyfile path/to/keyfile --certfile path/to/certfile --clientauth=true --clientcafile path/to/clientCAfile foobar.pow
$ kapow server --keyfile path/to/keyfile --certfile path/to/certfile --clientauth=true --clientcafile path/to/clientCAfile foobar-route
With this configuration *Kapow!* will reject connections that do not present a
client certificate or one certificate not issued by the specified CA. You can
Expand Down
8 changes: 5 additions & 3 deletions docs/source/examples/shell_tricks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ from query params:
.. code-block:: console
:linenos:
$ cat parallel.pow
$ cat parallel-route
#!/usr/bin/env sh
kapow route add '/parallel/{ip1}/{ip2}' - <<-'EOF'
ping -c 1 -- "$(kapow get /request/matches/ip1)" | kapow set /response/body &
ping -c 1 -- "$(kapow get /request/matches/ip2)" | kapow set /response/body &
Expand All @@ -30,5 +31,6 @@ Script debugging
Bash provides the ``set -x`` builtin command that "After expanding each simple command,
for command, case command, select command, or arithmetic for command, display the
expanded value of PS4, followed by the command and its expanded arguments or associated
word list". This feature can be used to help debugging the `.pow` scripts and, together
the ``--debug`` option in the server sub-command, the scripts executed in user requests.
word list". This feature can be used to help debugging the init programs and,
together the ``--debug`` option in the server sub-command, the scripts executed
in user requests.
2 changes: 1 addition & 1 deletion docs/source/examples/toc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Examples

.. toctree::

working_with_pow_files
working_with_init_programs
managing_routes
handling_http_requests
using_json
Expand Down
8 changes: 5 additions & 3 deletions docs/source/examples/using_json.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ Example #1
++++++++++

In this example our *Kapow!* service will receive a `JSON` value with an incorrect
date, then our ``pow`` file will fix it and return the correct value to the user.
date, then our init program will fix it and return the correct value to the user.

.. code-block:: console
:linenos:
$ cat fix_date.pow
$ cat fix_date
#!/usr/bin/env sh
kapow route add -X POST /fix-date - <<-'EOF'
kapow set /response/headers/Content-Type application/json
kapow get /request/body | jq --arg newdate "$(date +'%Y-%m-%d_%H-%M-%S')" '.incorrectDate=$newdate' | kapow set /response/body
Expand All @@ -46,7 +47,8 @@ order to generate a two-attribute `JSON` response.

.. code-block:: console
$ cat echo-attribute.pow
$ cat echo-attribute
#!/usr/bin/env sh
kapow route add -X POST /echo-attribute - <<-'EOF'
JSON_WHO=$(kapow get /request/body | jq -r .name)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,60 +1,48 @@
Working with pow Files
======================
Working with Init Scripts
=========================

Starting *Kapow!* using a pow file
----------------------------------
Starting *Kapow!* using an init script
--------------------------------------

A :file:`pow` file is just a :command:`bash` script, where you make calls to the
``kapow route`` command.
An init program, which can be just a shell script, allows you to make calls to
the ``kapow route`` command.

.. code-block:: console
:linenos:
$ kapow server example.pow
$ kapow server example-init-program
With the :file:`example.pow`:
With the :file:`example-init-program`:

.. code-block:: console
:linenos:
$ cat example.pow
$ cat example-init-program
#!/usr/bin/env sh
#
# This is a simple example of a pow file
# This is a simple example of an init program
#
echo '[*] Starting my script'
echo '[*] Starting my init program'
# We add 2 Kapow! routes
kapow route add /my/route -c 'echo hello world | kapow set /response/body'
kapow route add -X POST /echo -c 'kapow get /request/body | kapow set /response/body'
.. note::

*Kapow!* can be fully configured using just :file:`pow` files
*Kapow!* can be fully configured using just init scripts


Load More Than One pow File
---------------------------
Writing Multiline Routes
------------------------

You can load more than one :file:`pow` file at time. This can help you keep
your :file:`pow` files tidy.
If you need to write more complex actions, you can leverage multiline routes:

.. code-block:: console
:linenos:
$ ls pow-files/
example-1.pow example-2.pow
$ kapow server <(cat pow-files/*.pow)
Writing Multiline pow Files
---------------------------

If you need to write more complex actions, you can leverage multiline commands:

.. code-block:: console
:linenos:
$ cat multiline.pow
$ cat multiline-route
#!/usr/bin/env sh
kapow route add /log_and_stuff - <<-'EOF'
echo this is a quite long sentence and other stuff | tee log.txt | kapow set /response/body
cat log.txt | kapow set /response/body
Expand All @@ -77,43 +65,45 @@ Keeping Things Tidy
Sometimes things grow, and keeping things tidy is the only way to mantain the
whole thing.

You can distribute your endpoints in several pow files. And you can keep the
whole thing documented in one html file, served with *Kapow!*.
You can distribute your endpoints in several init programs. And you can keep
the whole thing documented in one html file, served with *Kapow!*.

.. code-block:: console
:linenos:
$ cat index.pow
$ cat index-route
#!/usr/bin/env sh
kapow route add / - <<-'EOF'
cat howto.html | kapow set /response/body
EOF
source ./info_stuff.pow
source ./other_endpoints.pow
source ./info_stuff
source ./other_endpoints
You can import other shell script libraries with `source`.

As you can see, the `pow` files can be imported into another `pow` file using
source. In fact, a `pow` file is just a regular shell script.

Debugging scripts
-----------------
Debugging Init Programs/Scripts
-------------------------------

Since *Kapow!* redirects the standard output and the standard error of the `pow`
file given on server startup to its own, you can leverage ``set -x`` to see the
commands that are being executed, and use that for debugging.
Since *Kapow!* redirects the standard output and the standard error of the init
program given on server startup to its own, you can leverage ``set -x`` to see
the commands that are being executed, and use that for debugging.

To support debugging user request executions, the server subcommand has a
``--debug`` option flag that prompts *Kapow!* to redirect both the script's
standard output and standard error to *Kapow!*'s standard output, so you can
leverage ``set -x`` the same way as with `pow` files.
leverage ``set -x`` the same way as with init programs.


.. code-block:: console
$ cat withdebug.pow
$ cat withdebug-route
#!/usr/bin/env sh
kapow route add / - <<-'EOF'
set -x
echo "This will be seen in the log"
echo "Hi HTTP" | kapow set /response/body
EOF
$ kapow server --debug withdebug.pow
$ kapow server --debug withdebug-route
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Contents
:maxdepth: 2
:caption: Usage Examples

examples/working_with_pow_files
examples/working_with_init_programs
examples/managing_routes
examples/handling_http_requests
examples/using_json
Expand Down
2 changes: 1 addition & 1 deletion docs/source/the_project/install_and_configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ After building the image you can run the container with:

.. code-block:: console
$ docker run --rm -i -p 8080:8080 -v $(pwd)/whatever.pow:/opt/whatever.pow kapow:latest server /opt/whatever.pow
$ docker run --rm -i -p 8080:8080 -v $(pwd)/whatever-route:/opt/whatever-route kapow:latest server /opt/whatever-route
With the ``-v`` parameter we map a local file into the container's filesystem so
we can use it to configure our *Kapow!* server on startup.
Expand Down
19 changes: 12 additions & 7 deletions docs/source/the_project/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,10 @@ Install *Kapow!*
Follow the :ref:`installation instructions <installation>`.


Write a :file:`ping.pow` File
+++++++++++++++++++++++++++++
Write an Init Program :file:`ping-route`
+++++++++++++++++++++++++++++++++++++++

*Kapow!* uses plain text files (called `pow` files) where the endpoints you want
*Kapow!* uses init programs/scripts where the endpoints you want
to expose are defined.

For each endpoint, you can decide which commands get executed.
Expand All @@ -128,11 +128,15 @@ For our example we need a file like this:

.. code-block:: console
$ cat ping.pow
$ chmod +x ping-route
$ cat ping-route
#!/usr/bin/env sh
kapow route add /ping -c 'ping -c 1 10.10.10.100 | kapow set /response/body'
Let's dissect this beast piece by piece:

#. ``#!/usr/bin/env sh`` - shebang line so that the kernel knows which
interpreter to use
#. ``kapow route add /ping`` - adds a new `HTTP API` endpoint at ``/ping``
path in the *Kapow!* server. You have to use the ``GET`` method to invoke
the endpoint.
Expand All @@ -147,18 +151,19 @@ Let's dissect this beast piece by piece:
Launch the Service
++++++++++++++++++

At this point, we only need to launch :program:`kapow` with our :file:`ping.pow`:
At this point, we only need to launch :program:`kapow` with our
:file:`ping-route`:

.. code-block:: console
$ kapow server ping.pow
$ kapow server ping-route
*Kapow!* can expose the user interface through HTTPS, to do this provide the
corresponding key and certificates chain paths at startup:

.. code-block:: console
$ kapow server --keyfile path/to/keyfile --certfile path/to/certfile ping.pow
$ kapow server --keyfile path/to/keyfile --certfile path/to/certfile ping-route
Consume the Service
Expand Down
Loading

0 comments on commit 100b41f

Please sign in to comment.