diff --git a/README.rst b/README.rst index bcf6707..7173c17 100644 --- a/README.rst +++ b/README.rst @@ -21,7 +21,7 @@ share programming language. Ye be warned. What is it? =========== -Kapow! is an adapter between the world of Pure UNIX® Shell and a HTTP service. +Kapow! is an adapter between the world of Pure UNIX® Shell and an HTTP service. Some tasks are more convenient in the shell, like cloud interactions, or some administrative tools. On the other hand, some tasks are more convenient as a diff --git a/docs/source/_static/request_life_cycle.png b/docs/source/_static/request_life_cycle.png new file mode 100644 index 0000000..d2638f9 Binary files /dev/null and b/docs/source/_static/request_life_cycle.png differ diff --git a/docs/source/_static/request_life_cycle.xcf b/docs/source/_static/request_life_cycle.xcf new file mode 100644 index 0000000..39a26c4 Binary files /dev/null and b/docs/source/_static/request_life_cycle.xcf differ diff --git a/docs/source/conf.py b/docs/source/conf.py index 8020ecb..329ce3e 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -60,3 +60,6 @@ html_theme_options = { # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] + +# https://stackoverflow.com/a/56448499 +master_doc = 'index' diff --git a/docs/source/examples/greet-json.rst b/docs/source/examples/greet-json.rst new file mode 100644 index 0000000..76d851e --- /dev/null +++ b/docs/source/examples/greet-json.rst @@ -0,0 +1,17 @@ +Working with JSON +================== + +Nowadays webservices are json based so making your script json aware is probably +a good chioce. In order to be able to extract data from and compose json +documents from a script you can use +`jq `_. + +In this example we extract the name field from the incomming json document in +order to generate a two attribute json response. + +.. code-block:: bash + + who=$(kapow get /request/body | jq -r .name) + kapow set /response/headers/Content-Type "application/json" + kapow set /response/status 200 + jq --arg greet "Hello" --arg value "${who:-World}" -n \{greet:\$greet\,to:\$value\} | kapow set /response/body diff --git a/docs/source/examples/upload.rst b/docs/source/examples/upload.rst new file mode 100644 index 0000000..26e73ec --- /dev/null +++ b/docs/source/examples/upload.rst @@ -0,0 +1,20 @@ +Upload a file +============= + +HTTP request allows us to send and receive files by using the Multipart standard. + +Kapow! allow us to handle files received in the request. In this example we +respond back with the line count of the file received in the request. + +.. code-block:: bash + + fname=$(kapow get /request/files/myfile/filename) + lcount=$(kapow get /request/files/myfile/content | wc -l) + kapow set /response/status 200 + echo "$fname has $lcount lines" | kapow set /response/body + +You can try this by using the following curl: + +.. code-block:: bash + + curl -F "myfile=@README.rst" http://localhost:8080/linecount diff --git a/docs/source/index.rst b/docs/source/index.rst index 23f2cbb..cd47276 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,23 +1,25 @@ -.. include:: ../../README.rst +.. toctree:: + :maxdepth: 2 + :caption: Setup + + setup/install-and-configure .. toctree:: :maxdepth: 2 - :caption: TODO - - install - quickstart - -.. toctree:: - :maxdepth: 2 - :caption: Example + :caption: Examples examples/index + examples/greet-json + examples/upload .. toctree:: :maxdepth: 2 - :caption: Tutorial + :caption: Theory - tutorial + theory/interfaces + theory/philosophy + theory/request_life_cycle + theory/resource_tree diff --git a/docs/source/setup/install-and-configure.rst b/docs/source/setup/install-and-configure.rst new file mode 100644 index 0000000..28c95b7 --- /dev/null +++ b/docs/source/setup/install-and-configure.rst @@ -0,0 +1,68 @@ +Installing Kapow! +================= + +Kapow! has a reference implementation in Go that is under active develpment +right now. If you want to start using Kapow! you can: +- Download a binary (linux, at this moment) from our +`releases `_ section +- Install the package with the get command (you need the Go runtime installed +and `configured `) + +.. code-block:: bash + + go get -u github.com/BBVA/kapow + +Using Kapow! +============ + +Kapow! binary gives you both, a way to start the server and a command line +client to interact with it. + +Running the server +------------------ + +You start a Kapow! server by using the server command ``kapow server``. It +automatically binds the three HTTP modules when it starts: + +- The control server: Used to manage the user defined routes. It exposes the +control API and listens by default in the loopback interface at port 8081. You +can change this configurtation by ussing the +--control-bind : parameter. +- The data server: Allows access to the resources tree to the scripts triggered +by user's requests. It exposes the control API and listens by default in the +loopback interface at port 8082. You can change this configurtation by ussing +the --data-bind : parameter. +- The ``user server``: This server is the one that makes available to the +outside all the routes configured through the control server. It listens by +default in the port 8080 of all configured interfaces (0.0.0.0). You can change this +configurtation by ussing the --bind : parameter. + + + +********--------********--------********----------------********--------********--------******** + +You start a Kapow! server by using the server command ``kapow server``. You can +configure the listen address of the different modules by using the +corresponding parameters: + +- --control-bind :: Allows to manage the user +defined routes. Defaults to 'localhost:8081' (loopback interface). +- --data-bind :: Allows access to the resources +tree to the scripts triggered by user's requests. Defailts to 'localhost:8081' +(loopback interface). +- --bind :: Publishes the routes configured +through the control server to the outside world. Defaults to '0.0.0.0:8080' +(all configured host's interfaces.) + + +Managing routes +--------------- + +Kapow!'s route command allows us to manage the routes that we want to publish +to the outside world. In order to contact with the desired Kapow! server you +can use the ``--control-url`` command line parameter or the KAPOW_CONTROL_URL +environmental variable to set the correct value. + +In the same way the ``--data-url`` command line parameter or the KAPOW_DATA_URL +environmental variable will allow you to set to set the server listen address +when accesing the data server, although this case is less frequent. diff --git a/docs/source/theory/index.rst b/docs/source/theory/index.rst deleted file mode 100644 index e69de29..0000000 diff --git a/docs/source/theory/philosophy.rst b/docs/source/theory/philosophy.rst index 9303982..d6b9731 100644 --- a/docs/source/theory/philosophy.rst +++ b/docs/source/theory/philosophy.rst @@ -2,28 +2,30 @@ Philosophy ========== -We Provide a Single Static Binary ---------------------------------- +Single Static Binary +-------------------- -- Because it makes deployments easier. +- Deployment is then as simple as it gets. + +- Docker-friendly. Shell Agnostic -------------- -- Kapow! knows nothing about the shell you are using. -- It only spawns executables. -- You can use anything you want that ends interacting with the `data - api`. -- This helps with multiplatform and with future higher level tools. +- Kapow! knows nothing, and makes no assumptions, about the shell you are using. + It only spawns executables. + +- You are free to implement a client to the Data API directly if you are so + inclined. The spec provides all the necessary details. Not a Silver Bullet ------------------- -You should not use Kapow! for projects with complex business logic. +You should not use Kapow! if your project requires complex business logic. If you try to encode business logic in a shell script, you will **deeply** regret it. -Kapow! is for automating simple stuff. +Kapow! is designed for automating simple stuff. diff --git a/docs/source/theory/request_life_cycle.rst b/docs/source/theory/request_life_cycle.rst index 9d4033e..7e8810b 100644 --- a/docs/source/theory/request_life_cycle.rst +++ b/docs/source/theory/request_life_cycle.rst @@ -2,32 +2,61 @@ Request Life Cycle ================== This section describes the sequence of events happening for each request -answered by the User HTTP Interface. +answered by the `User HTTP Interface`. -#. The user makes a request to the User HTTP Interface +.. image:: ../_static/request_life_cycle.png -#. The request is matched against the route table -#. Kapow! provides a `HANDLER_ID` to identify this request +1. request +---------- -#. Kapow! spawns the binary specified as entrypoint in the matching route +The user makes a request to the `User HTTP Interface`. - The default entrypoint is /bin/sh; we'll explain this workflow for now. +- The request is matched against the route table - The spawned entrypoint is run with the following variables added to its environment: +- ``kapow`` provides a `HANDLER_ID` to identify this request and don't mix it + with other requests that could be running concurrently. - - ``KAPOW_HANDLER_ID``: Containing the `HANDLER_ID` - - ``KAPOW_DATAAPI_URL``: With the URL of the `data interface` - - ``KAPOW_CONTROLAPI_URL``: With the URL of the `control interface` +2. spawn +-------- -#. During the lifetime of the shell, the request and response resources are available via these commands: +``kapow`` spawns the executable specified as entrypoint in the matching +route. - - ``kapow get /request/...`` - - ``kapow set /response/...`` +The default entrypoint is ``/bin/sh``; we'll explain this workflow for now. - These commands use the aforementioned environment variables to read - data of the user request and to write the response. +The spawned entrypoint is run with the following variables added to its +environment: -TODO: link to resource tree +- ``KAPOW_HANDLER_ID``: Containing the `HANDLER_ID` +- ``KAPOW_DATAAPI_URL``: With the URL of the `Data HTTP Interface` +- ``KAPOW_CONTROLAPI_URL``: With the URL of the `Control HTTP Interface` -#. When the shell dies, Kapow! finalizes the original request +3. ``kapow set /response/body banana`` +-------------------------------------- + +During the lifetime of the shell, the request and response resources are +available via these commands: + +- ``kapow get /request/...`` + +- ``kapow set /response/...`` + +These commands use the aforementioned environment variables to read data +from the user request and to write the response. They accept data +either as arguments or from ``stdin``. + +4. exit +------- + +The shell dies. + +5. response +----------- + +``kapow`` finalizes the original request. + + +.. todo:: + + link to resource tree diff --git a/internal/server/user/spawn/spawn.go b/internal/server/user/spawn/spawn.go index 50f4f4d..1f8140a 100644 --- a/internal/server/user/spawn/spawn.go +++ b/internal/server/user/spawn/spawn.go @@ -44,7 +44,7 @@ func Spawn(h *model.Handler, out io.Writer) error { if out != nil { cmd.Stdout = out } - cmd.Env = append(os.Environ(), "KAPOW_URL=http://localhost:8081") + cmd.Env = append(os.Environ(), "KAPOW_DATA_URL=http://localhost:8082") cmd.Env = append(cmd.Env, "KAPOW_HANDLER_ID="+h.ID) err = cmd.Run() diff --git a/internal/server/user/spawn/spawn_test.go b/internal/server/user/spawn/spawn_test.go index 721f1ba..4e8f359 100644 --- a/internal/server/user/spawn/spawn_test.go +++ b/internal/server/user/spawn/spawn_test.go @@ -104,8 +104,8 @@ func TestSpawnSetsKapowURLEnvVar(t *testing.T) { _ = Spawn(h, out) jldata := decodeJailLover(out.Bytes()) - if v, ok := jldata.Env["KAPOW_URL"]; !ok || v != "http://localhost:8081" { - t.Error("KAPOW_URL is not set properly") + if v, ok := jldata.Env["KAPOW_DATA_URL"]; !ok || v != "http://localhost:8082" { + t.Error("KAPOW_DATA_URL is not set properly") } }