From 682cb198c91e059f973b070ded37174bae237f95 Mon Sep 17 00:00:00 2001 From: Cristovao Cordeiro Date: Fri, 26 Nov 2021 17:33:30 +0100 Subject: [PATCH 1/6] add docs for v2 and re-organize menu --- docs/_includes/old_nuvlabox_warning.html | 2 +- ...detail.png => nuvlabox-engine-arch-v1.png} | Bin docs/assets/img/nuvlabox-engine-arch-v2.png | Bin 0 -> 358509 bytes .../{v1 => }/contributing/agent-api.md | 3 +- .../custom-peripheral-managers.md | 3 +- docs/nuvlabox/{v1 => }/contributing/index.md | 5 +- .../{v2 => }/deploying-apps/first-app.md | 2 +- .../nuvlabox/{v2 => }/deploying-apps/index.md | 4 +- docs/nuvlabox/{v2 => }/how-to-choose.md | 4 +- docs/nuvlabox/nuvlabox-engine/index.md | 17 ++ .../v1}/architecture.md | 10 +- .../v1}/configuration.md | 9 +- docs/nuvlabox/nuvlabox-engine/v1/index.md | 51 +++++ .../nuvlabox-engine/v1/installation/index.md | 10 + .../install-with-compose-files.md | 92 ++++++++ .../v1/installation/install-with-usb-stick.md | 118 ++++++++++ .../v1}/requirements.md | 17 +- .../nuvlabox-engine/v1/troubleshooting.md | 19 ++ .../nuvlabox-engine/v2/architecture.md | 34 +++ .../nuvlabox-engine/v2/configuration.md | 34 +++ docs/nuvlabox/nuvlabox-engine/v2/index.md | 35 +++ .../nuvlabox-engine/v2/installation/index.md | 11 + .../install-with-compose-files.md | 103 +++++++++ .../v2/installation/install-with-usb-stick.md | 117 ++++++++++ .../nuvlabox-engine/v2/requirements.md | 55 +++++ .../nuvlabox-engine/v2/troubleshooting.md | 20 ++ docs/nuvlabox/{v2 => }/nuvlabox-os/index.md | 4 +- docs/nuvlabox/v1/deploying-apps/first-app.md | 36 ---- docs/nuvlabox/v1/deploying-apps/index.md | 18 -- docs/nuvlabox/v1/how-to-choose.md | 22 -- docs/nuvlabox/v1/index.md | 17 -- docs/nuvlabox/v1/nuvlabox-engine/index.md | 55 ----- .../nuvlabox/v1/nuvlabox-engine/quickstart.md | 203 ----------------- docs/nuvlabox/v1/nuvlabox-os/index.md | 12 -- docs/nuvlabox/v2/contributing/agent-api.md | 151 ------------- .../custom-peripheral-managers.md | 182 ---------------- docs/nuvlabox/v2/contributing/index.md | 23 -- docs/nuvlabox/v2/index.md | 18 -- .../v2/nuvlabox-engine/architecture.md | 27 --- .../v2/nuvlabox-engine/configuration.md | 32 --- docs/nuvlabox/v2/nuvlabox-engine/index.md | 56 ----- .../nuvlabox/v2/nuvlabox-engine/quickstart.md | 204 ------------------ .../v2/nuvlabox-engine/requirements.md | 56 ----- 43 files changed, 744 insertions(+), 1147 deletions(-) rename docs/assets/img/{nuvlabox-os-arch-detail.png => nuvlabox-engine-arch-v1.png} (100%) create mode 100644 docs/assets/img/nuvlabox-engine-arch-v2.png rename docs/nuvlabox/{v1 => }/contributing/agent-api.md (99%) rename docs/nuvlabox/{v1 => }/contributing/custom-peripheral-managers.md (99%) rename docs/nuvlabox/{v1 => }/contributing/index.md (94%) rename docs/nuvlabox/{v2 => }/deploying-apps/first-app.md (98%) rename docs/nuvlabox/{v2 => }/deploying-apps/index.md (91%) rename docs/nuvlabox/{v2 => }/how-to-choose.md (96%) create mode 100644 docs/nuvlabox/nuvlabox-engine/index.md rename docs/nuvlabox/{v1/nuvlabox-engine => nuvlabox-engine/v1}/architecture.md (79%) rename docs/nuvlabox/{v1/nuvlabox-engine => nuvlabox-engine/v1}/configuration.md (94%) create mode 100644 docs/nuvlabox/nuvlabox-engine/v1/index.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v1/installation/index.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v1/installation/install-with-compose-files.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v1/installation/install-with-usb-stick.md rename docs/nuvlabox/{v1/nuvlabox-engine => nuvlabox-engine/v1}/requirements.md (75%) create mode 100644 docs/nuvlabox/nuvlabox-engine/v1/troubleshooting.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v2/architecture.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v2/configuration.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v2/index.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v2/installation/index.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v2/installation/install-with-compose-files.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v2/installation/install-with-usb-stick.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v2/requirements.md create mode 100644 docs/nuvlabox/nuvlabox-engine/v2/troubleshooting.md rename docs/nuvlabox/{v2 => }/nuvlabox-os/index.md (85%) delete mode 100644 docs/nuvlabox/v1/deploying-apps/first-app.md delete mode 100644 docs/nuvlabox/v1/deploying-apps/index.md delete mode 100644 docs/nuvlabox/v1/how-to-choose.md delete mode 100644 docs/nuvlabox/v1/index.md delete mode 100644 docs/nuvlabox/v1/nuvlabox-engine/index.md delete mode 100644 docs/nuvlabox/v1/nuvlabox-engine/quickstart.md delete mode 100644 docs/nuvlabox/v1/nuvlabox-os/index.md delete mode 100644 docs/nuvlabox/v2/contributing/agent-api.md delete mode 100644 docs/nuvlabox/v2/contributing/custom-peripheral-managers.md delete mode 100644 docs/nuvlabox/v2/contributing/index.md delete mode 100644 docs/nuvlabox/v2/index.md delete mode 100644 docs/nuvlabox/v2/nuvlabox-engine/architecture.md delete mode 100644 docs/nuvlabox/v2/nuvlabox-engine/configuration.md delete mode 100644 docs/nuvlabox/v2/nuvlabox-engine/index.md delete mode 100644 docs/nuvlabox/v2/nuvlabox-engine/quickstart.md delete mode 100644 docs/nuvlabox/v2/nuvlabox-engine/requirements.md diff --git a/docs/_includes/old_nuvlabox_warning.html b/docs/_includes/old_nuvlabox_warning.html index 6e29b49..8c82d02 100644 --- a/docs/_includes/old_nuvlabox_warning.html +++ b/docs/_includes/old_nuvlabox_warning.html @@ -1 +1 @@ -
Warning: this is not the documentation of the latest version of the NuvlaBox. Go here to access the latest version.
+
Warning: this is not the documentation of the latest version of the NuvlaBox. Go here to access the latest version.
diff --git a/docs/assets/img/nuvlabox-os-arch-detail.png b/docs/assets/img/nuvlabox-engine-arch-v1.png similarity index 100% rename from docs/assets/img/nuvlabox-os-arch-detail.png rename to docs/assets/img/nuvlabox-engine-arch-v1.png diff --git a/docs/assets/img/nuvlabox-engine-arch-v2.png b/docs/assets/img/nuvlabox-engine-arch-v2.png new file mode 100644 index 0000000000000000000000000000000000000000..ca45a494e45aea7fa951287fadfd94bc9a261f69 GIT binary patch literal 358509 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 z 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
    gFdOg}OWe<+x3M38ZM|pH$qp1Jl=ZBA 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

    eRpA8iKX@YUcNi*-L}3a{aSw?ihH(o* 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

    K?<@nltxuA&IZz9|BJ-}xsn2)8qC;i_ii~Q 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 xv&(G-%Ff>Q1M%>G2BROGYTxk{$LT)p^S` and download the compose files from [GitHub](https://github.com/nuvlabox/deployment/releases) +3. copy the given `docker-compose -p nuvlabox ...` command from Nuvla, and on your device, alongside the compose files retrieved in step 2. above, paste and run the command +4. after a few seconds, you should see your new NuvlaBox edge device becoming green in [Nuvla](https://nuvla.io/ui/edge), and if you run `docker ps` in your device, you should find (amongst others) something like: + ```bash + 865403c5d7f2 nuvlabox/system-manager:0.4.0 "./app.py" 3 weeks ago Up 6 hours (healthy) 127.0.0.1:3636->3636/tcp, 0.0.0.0:3637->3637/tcp nuvlabox_system-manager_1 + ``` + +### Halt the NuvlaBox + +In an edge environment, halting your devices is sometimes necessary. + +**When rebooting** your edge device, the NuvlaBox will resume by itself, alongside your device's Docker service, so you don't need to do anything. + +**When manually halting** the NuvlaBox, you can simply find the original compose files in your edge device, re-export the original environment variables (if not exported already), and run `docker-compose -p nuvlabox down`. Then **to resume**, simply run `docker-compose -p nuvlabox up -d`. Remember to specific the compose files in this command, whenever peripheral managers are also to be halted. + + +### Upgrade/Downgrade the NuvlaBox + +#### From Nuvla + +The NBE can be updated directly from Nuvla. On the user interface, in each NuvlaBox page, you'll find an action called "Update NuvlaBox" (as depicted below) + +![nb-update-nuvla.png](/assets/img/nb-update-nuvla.png) + +By clicking on it, you can specify which version of the NuvlaBox Engine is the target for the release. Please note that this is an asynchronous action that can take a few minutes, depending on your edge device's network. + +**Troubleshooting**: Please note that the update capability was only introduced in [NuvlaBox Engine v1.14.0](https://github.com/nuvlabox/deployment/releases/tag/1.14.0). You can still update your NuvlaBox to/from an older NuvlaBox Engine version, **however**, since the persistency of NB installation parameters was only introduced in v1.14.0, we can not guarantee that the final update will result in a similarly configured NBE! If you're updating to/from a NBE version <1.14.0, we recommend taking note of all the environment variables and Docker Compose arguments used during the installation, just in case a manual intervention is needed after an unsuccessful update. + +--- + +#### Manually + +You can also SSH into your edge device, and find the original project folder where you saved your Compose files. + +If you've initially installed the NuvlaBox Engine according to the instructions above, then you should see all of its components by running: + +```bash +# if there are also peripheral managers installed, remember to add "-f docker-compose..yml" to this command +# where "" is the type of peripheral manager you've installed above +$ docker-compose -p nuvlabox ps +``` + +You should get something like this: + +``` + Name Command State Ports +-------------------------------------------------------------------------------------------------- +datagateway /entrypoint.sh --entrypoin ... Up 80/tcp +nbmosquitto /docker-entrypoint.sh /usr ... Up (healthy) 1883/tcp +nuvlabox_agent_1 ./app.py Up 5000/tcp +nuvlabox_compute-api_1 ./api.sh Up 0.0.0.0:5000->5000/tcp +nuvlabox_management-api_1 ./app.py Up (healthy) 0.0.0.0:5001->5001/tcp +nuvlabox_network-manager_1 /opt/nuvlabox/network-mana ... Up 1194/udp +nuvlabox_system-manager_1 ./app.py Up (healthy) 127.0.0.1:3636->3636/tcp +vpn-client ./openvpn-client.sh Up +``` + +- **Cherry picking a NuvlaBox Engine component to be upgraded/downgraded:** let's say, as an example, that we want to upgrade the NuvlaBox Engine's Agent component. Then: + 1. open the `docker-compose.yml` file and find the `agent` service + 2. replace the corresponding Docker image tag (nuvlabox/agent:X.Y.Z)with the target version number. Save the file + 3. re-import all the necessary environment variables for the component being upgraded. In this case, make sure that at least NUVLABOX_UUID is set (if you're using [Nuvla.io](https://nuvla.io) + 4. execute `docker-compose -p nuvlabox up -d agent` + + This is valid for any NuvlaBox Engine component + +- **Upgrade/Downgrade the entire NuvlaBox Engine installation**: let's say we want to upgrade our existing NuvlaBox Engine installation to the latest release in [GitHub](https://github.com/nuvlabox/deployment/releases). Then: + 1. halt the NuvlaBox with `docker-compose -p nuvlabox down`, as explained [above](#halt-the-nuvlabox) + 2. move (or delete) the Compose files from the project folder you are in + 3. download the Compose files from the [target release in GitHub](https://github.com/nuvlabox/deployment/releases) + 4. resume the NuvlaBox Engine installation by running `docker-compose -p nuvlabox up -d` + + +### Uninstall the NuvlaBox + +To completely and **permanently** uninstall the NuvlaBox from your edge device, simply find your original compose files in the edge device, and run `docker-compose -p nuvlabox down -v --remove-orphans`. + +To re-install a new NuvlaBox from scratch in the same edge device, you'll need to go through the installation steps from above. + diff --git a/docs/nuvlabox/nuvlabox-engine/v1/installation/install-with-usb-stick.md b/docs/nuvlabox/nuvlabox-engine/v1/installation/install-with-usb-stick.md new file mode 100644 index 0000000..cd3545b --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v1/installation/install-with-usb-stick.md @@ -0,0 +1,118 @@ +--- +layout: nuvlabox +title: USB Stick +nav_order: 2 +parent: Installation +grand_parent: v1 +old_version: true +--- + +# Install via USB stick + +If your are looking to streamline the installation of the NuvlaBox Engine in your edge devices, then this is the best choice for you. + +The advantages of this installation method are: +- **NO** need for an external display +- **NO** need for SSH access to the device +- The same USB stick can be used **as many times** as needed +- **NO** technical expertise required + +Unlike the Compose file bundle, the USB stick installation method does not require manual user intervention, and thus does not support manual configuration of the NBE environment variable. **NUVLABOX_UUID**, **NUVLA_ENDPOINT** and **NUVLA_ENDPOINT_INSECURE** are automatically defined for you by Nuvla, during the installation process. + +It is _not_ yet possible to define variables like **HOSTNAME** and **VPN_INTERFACE_NAME** with this installation method. All possible NBE configurations for this installation method are set from Nuvla, at the time of creation of the USB stick file. + +### Additional requirements + +This installation method requires a specific NuvlaBox plugin to be installed in your Operating System, which will trigger the USB-based installation whenever you plug the flash drive. + +- if your devices **are running** a [NuvlaBox OS](/nuvlabox/nuvlabox-os.html), then you're good! You can jump straight to the [installation procedure below](#procedure) + +- if your devices **are NOT running** a [NuvlaBox OS](/nuvlabox/nuvlabox-os.html), then you **must** first prepare your operating system as follows: + + 1. make sure you are running a Linux distribution with `systemd` installed (we recommend using Debian or Ubuntu) + 2. get the latest version of the NuvlaBox USB Auto-installer plugin from GitHub: + + ```bash + git clone https://github.com/nuvlabox/nuvlabox-os.git /tmp/nuvlabox-os + + cd /tmp/nuvlabox-os + ``` + + 3. you'll find different NuvlaBox OS distributions here. These are enclosed within folders like `raspberrypi` (for a Raspbian-like NuvlaBox OS) or `generic` (for generic amd64 Debian-like NuvlaBox OS). Navigate to the folder that it closer to your own distribution + + ```bash + cd /tmp/nuvlabox-os/ + ``` + + 4. inside you'll find a `99_usb-auto-installer` folder + + ```bash + ls 99_usb-auto-installer + ``` + + 5. for all distros, inside the `99_usb-auto-installer` folder, you'll find an `.howToInstall` file. Run it + + ```bash + sudo sh .howToInstall + ``` + +You can now automate the installation of the NuvlaBox Engine into your fleet of edge devices. + +### Procedure + +If the OS of your edge device meets the [requirements](#additional-requirements), then all you have to do is to prepare your USB flash drive. + +Just follow these steps: + +1. go to [Nuvla](https://nuvla.io) and login +2. on the NuvlaBox tab, click `+add` and select the **USB stick** installation method + + ![nuvlabox-install-usb](/assets/img/nuvlabox-add-usb.png) + + With this method, a new API key credential is generated for you, and embedded into your USB stick. You can choose for how long this credentials should be valid. By default, this value is set for 30 days. After that, the credential expires and the corresponding USB stick becomes invalid. + +3. click `create` and wait. A new API key credential will be created and you'll be given a "trigger" file to download + + ![nuvlabox-add-usb-trigger](/assets/img/nuvlabox-add-usb-trigger.png) + +4. download the Trigger file, and copy it into your USB stick. You can place it anywhere within. + + **IMPORTANT:** make your your USB stick's filesystem is formatted as one of the following: _vfat, ext2, ext3, ext4, hfsplus_ or _ntfs_. + +5. plug your USB stick into your edge device. + +6. the NuvlaBox Auto-installer plugin that is installed in your device's OS will automatically be triggered by the USB stick, and kickstart the installation of the NuvlaBox Engine. At this stage, all you need to do is wait... + + It shouldn't take more than a few seconds for the process to start. Depending on your hardware, you might be able to get some external feedback on the progress of the installation. This feedback signal works for the following machine types: + - `raspberrypi`: + - **CONSTANT GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **started** and you can safely remove your USB stick + + ![rpi-nb-start](/assets/img/rpi-nb-start.gif) + + - **HEARTBEAT GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **finished** successfully + + ![rpi-nb-success](/assets/img/rpi-nb-success.gif) + + - **PULSING GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **failed** + + ![rpi-nb-error](/assets/img/rpi-nb-error.gif) + +7. go back to the NuvlaBox tab in [Nuvla](https://nuvla.io) and your new NuvlaBox resource will appear. + + +### Upgrade the NuvlaBox Engine + +It is also possible to use the USB stick method to upgrade your NuvlaBox Engine installation. + +The procedure is the same as described [above](#procedure). If in Nuvla, you select a different NuvlaBox Engine version than the one you have already installed in your devices, then, when you plug the USB stick into the device, the NuvlaBox Auto-installer will upgrade all the outdated NuvlaBox Engine components, according to your desired version. + + +### Overwrite an existing installation + +It is also possible to use the USB stick method to completely delete and re-install your NuvlaBox Engine installation. However, in order to avoid damaging an existing installation, this process can only happen if the following conditions are met: + +- your previous NuvlaBox Engine installation is misconfigured, or +- your NuvlaBox resource is DECOMMISSIONED or in ERROR in [Nuvla](https://nuvla.io/ui/edge), or +- your NuvlaBox resource does not exist anymore in [Nuvla](https://nuvla.io/ui/edge), + +then the NuvlaBox Auto-installer will completely remove the existing NuvlaBox Engine installation from your device, and install a fresh new one. diff --git a/docs/nuvlabox/v1/nuvlabox-engine/requirements.md b/docs/nuvlabox/nuvlabox-engine/v1/requirements.md similarity index 75% rename from docs/nuvlabox/v1/nuvlabox-engine/requirements.md rename to docs/nuvlabox/nuvlabox-engine/v1/requirements.md index 8f93b2c..36840dd 100644 --- a/docs/nuvlabox/v1/nuvlabox-engine/requirements.md +++ b/docs/nuvlabox/nuvlabox-engine/v1/requirements.md @@ -1,9 +1,9 @@ --- layout: nuvlabox title: Requirements -nav_order: 1 -parent: NuvlaBox Engine -grand_parent: v1 +nav_order: 2 +parent: v1 +grand_parent: NuvlaBox Engine old_version: true --- @@ -14,13 +14,12 @@ To ensure a smooth and fully functional installation of the NuvlaBox Engine (**N ## OS Requirements +The NuvlaBox Engine is compliant with any OS that officially and fully supports Docker. We recommend one of the following: +- Ubuntu +- CentOS +- Debian (and Debian variants like Raspbian and Raspberry Pi OS) -Ideally, you should be running one of the following: - - Ubuntu - - CentOS - - Debian (and Debian variants like Raspbian and Raspberry Pi OS) - -Other Linux distributions should also work, but will require testing. +Other Docker-compliant Linux distributions should also work, but the NuvlaBox functionality will be subject to the level of Docker support the OS provides. Functionalities like the automatic discovery and categorization of peripherals are **not** ensured for macOS and Windows. diff --git a/docs/nuvlabox/nuvlabox-engine/v1/troubleshooting.md b/docs/nuvlabox/nuvlabox-engine/v1/troubleshooting.md new file mode 100644 index 0000000..367744d --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v1/troubleshooting.md @@ -0,0 +1,19 @@ +--- +layout: nuvlabox +title: Troubleshooting +nav_order: 6 +parent: v1 +grand_parent: NuvlaBox Engine +old_version: true +--- + +# Troubleshooting + +

    Failed to upgrade/downgrade my NuvlaBox Engine from/to v1.14.0 or lower + +
    +Please note that the update capability was only introduced in [NuvlaBox Engine v1.14.0](https://github.com/nuvlabox/deployment/releases/tag/1.14.0). You can still update your NuvlaBox to/from an older NuvlaBox Engine version, **however**, since the persistency of NB installation parameters was only introduced in v1.14.0, we can not guarantee that the final update will result in a similarly configured NBE! If you're updating to/from a NBE version <1.14.0, we recommend taking note of all the environment variables and Docker Compose arguments used during the installation, just in case a manual intervention is needed after an unsuccessful update. + +
    + +
    \ No newline at end of file diff --git a/docs/nuvlabox/nuvlabox-engine/v2/architecture.md b/docs/nuvlabox/nuvlabox-engine/v2/architecture.md new file mode 100644 index 0000000..8c1fb20 --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v2/architecture.md @@ -0,0 +1,34 @@ +--- +layout: nuvlabox +title: Architecture +nav_order: 1 +parent: v2 +grand_parent: NuvlaBox Engine +redirect_from: + - /nuvlabox/latest/nuvlabox-engine/architecture +--- + +Architecture +======== + +![nuvlabox-os-arch-detail](/assets/img/nuvlabox-engine-arch-v2.png) + +| NBE Component | Description | +|-: |- | +| AGENT | The `agent` is the beating heart of the NBE. It is responsible for the NB activation, commissioning and monitoring procedures. All outgoing communication towards Nuvla shall pass by the `agent`, via its internal REST API | +| SYSTEM MANAGER | The `system-manager` is the NBE's watchdog. It runs independently of all the other components. During the NBE bootstrap, it double checks that the device has the minimum requirements to support a NB, and if so, it starts scanning the whole NB on a periodic basis, searching for faulty NBE containers and trying to fix them automatically. It also provides an internal dashboard on the host's `127.0.0.1:3636` endpoint, with the overall status of the NB | +| COMPUTE CREDENTIALS MANAGER | Also referred to as the "COMPUTE API", this component makes sure all synchronous communications between Nuvla and the NuvlaBox, for application management, are secured | +| VPN CLIENT | The standalone `vpn-client` component is solely responsible for picking up an OpenVPN configuration set by the `agent` and establishing a secure VPN tunnel with SixSq's VPN server (or any other desired VPN server), ensuring that the NB is always remotely accessible | +| SECURITY | The `security` component is an autonomous self-assessment entity which scans the edge device on a configurable periodic basis, looking for vulnerabilities. Each potential vulnerability is compared with public reference databases (like the CVE) for a full categorization of the problem. These databases are also kept up to date via an internal synchronization procedure which is also scheduled with a configurable frequency. The most critical vulnerabilities are sent to Nuvla (via the `agent`) | +| DATA GATEWAY | The NBE `data-gateway` is an abstraction layer between user applications and IoT sensors/actuators. This component consists of an MQTT Broker (i.e. Mosquitto) which sits behind an internal shared network (the `nuvlabox-shared-network`). Depending on whether the NuvlaBox is operating in cluster mode or not, this component can either take the form of a standalone container behind a bridge network, or a load balanced service behind an overlay network. This configuration switch is handled automatically by the System Manager. Additionaly, and **optionally**, the NBE can also be deployed with the Data Gateway's FIWARE Processor, which is a sidekick micro-service that validates the schema of MQTT data, against FIWARE's data models, and upon successful validation, forwards data to a configurable outgoing endpoint | +| JOB ENGINE LITE | The Job Engine Lite is a lightweight version of the job processing engine behind Nuvla. Its introduction to the NuvlaBox Engine architecture allows users to remotely schedule operations to be executed inside the NuvlaBox, even if the edge device happens to be unreachable at the time of the command | +| PERIPHERAL MANAGER | The NBE has the concept of Peripheral Managers. These are **optional** micro-services which perform automatic detection and categorization of peripherals that *are* or *can be* connected to the edge device. Such peripheral information can then be used to activate sensor data acquisition throught the Data Gateway. Examples of existing peripheral managers are: `peripheral-manager-usb`, `peripheral-manager-bluetooth`, `peripheral-manager-modbus`, `peripheral-manager-gpu`, `peripheral-manager-network`, and others | + + +Deprecated Components +======== + +The following components have been deprecated with respect to the previous version of the NuvlaBox Engine, v1: + + - **Network Manager**: this component's functionality has been distributed over multiple components, including the System Manager, Agent and VPN Client; + - **Management API**: the NuvlaBox Engine v2 no longer exposes a dedicated API endpoint for remote management. Instead, with the introduction of the Job Engine Lite, all remote management operations are now done asynchronously, in the form of jobs that are scheduled from Nuvla and then pulled by the Agent for local execution within the NuvlaBox; \ No newline at end of file diff --git a/docs/nuvlabox/nuvlabox-engine/v2/configuration.md b/docs/nuvlabox/nuvlabox-engine/v2/configuration.md new file mode 100644 index 0000000..1262569 --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v2/configuration.md @@ -0,0 +1,34 @@ +--- +layout: nuvlabox +title: Configuration +nav_order: 3 +parent: v2 +grand_parent: NuvlaBox Engine +redirect_from: + - /nuvlabox/latest/nuvlabox-engine/configuration +--- + +When installing the NBE, there are a number of environment variable which can be set in order to customize the NuvlaBox. +Once installed, the NBE's configuration can only be changed through an update on full re-installation of the NBE. + + +## Environment Variables + +When installing the NBE, you can customize your NB via environment variables: + +- **NUVLABOX_UUID**: the unique Nuvla ID given to your NuvlaBox. Nuvla will provide this UUID. Also, if you've downloaded the compose files from Nuvla, this environment variable will already be set for you, otherwise, **you must set it** via `export NUVLABOX_UUID=`. Please note that the value of the variable can be given both in the form of `nuvlabox/` or simply ``; +- **NUVLABOX_DATA_GATEWAY_IMAGE**: name of the container image to be used for the MQTT Broker behind the NuvlaBox Data Gateway. You should only change this variable if you are sure the resulting Data Gateway functionality is not affected. To define a new MQTT broker image, simply run `export NUVLABOX_DATA_GATEWAY_IMAGE=` before the installation; +- **NUVLABOX_API_KEY**: when the NuvlaBox Engine is successfully installed, Nuvla will issue a unique API Key/Secret credential for that NuvlaBox to be able to securily communicate with Nuvla. This credential's key and secret are stored locally within the NuvlaBox Engine's data volume, which means that if for some reason, the volume is lost, so is the NuvlaBox, and you'll have to create a new one. With this variable, if your NuvlaBox local data is completely lost and but you know what its API Key and Secret were, you can still recover it by running `export NUVLABOX_API_KEY=credential/` and re-doing the NuvlaBox Engine installation steps. **NOTE**: this variable also needs NUVLABOX_API_SECRET to be set; +- **NUVLABOX_API_SECRET**: the secret corresponding to the NUVLABOX_API_KEY mentioned above. Please note that API secrets are not stored in Nuvla, so you can only get this value from your NuvlaBox's local data volume; +- **NUVLA_ENDPOINT**: endpoint for a Nuvla instance. By default it points to https://nuvla.io. But if you have your own Nuvla instance, you can point your NuvlaBox to it by running `export NUVLA_ENDPOINT=` before launching it; +- **NUVLA_ENDPOINT_INSECURE**: indicates whether to allow insecure (ignore TLS verification) communication between the NuvlaBox and Nuvla. By default it is set to **_false_**. In cases where you might have your own Nuvla instance, running on self-signed certificates, make sure you run `export NUVLA_ENDPOINT_INSECURE=True` before launching the NuvlaBox; +- **NUVLABOX_SSH_PUB_KEY**: it adds the provided string as a public SSH key into the host's `${HOME}/.ssh/authorized_keys` file. Please **note** that once set, this variable is no longer taken into consideration (e.g. during NuvlaBox Engine updates). This SSH key is immutable; +- **HOME**: defaults to your system user's HOME path. It is used for SSH key management. You should not edit this variable; +- **HOSTNAME**: used to generate the compute API credentials used by Nuvla to manage applications on the NuvlaBox. You should not edit this variable; +- **VPN_INTERFACE_NAME**: the NuvlaBox will have its own VPN client. By default, it will create a new network interface called **_vpn_**. If this conflicts with your existing network configuration, then please run `export VPN_INTERFACE_NAME=` before launching the NuvlaBox; +- **SKIP_MINIMUM_REQUIREMENTS**: when set to "True", it forces the installation of the NuvlaBox Engine without checking the system and software requirements. **Note**: this is not recommended, as the NuvlaBox might not behave as expected if the system requirements do not fulfill the minimum expectations; +- **EXTERNAL_CVE_VULNERABILITY_DB**: it consists of a link to an external CVE database, in CSV format and compressed, to be used as the reference database for the vulnerability scans. By default it points to an [aggregated CVE databased compiled by SixSq](https://github.com/nuvla/vuln-db/blob/main/databases/all.aggregated.csv.gz), from multiple trusted sources. If you want to use your own CVE database, then simply `export EXTERNAL_CSV_VULNERABILITY_DB=`; +- **EXTERNAL_CVE_VULNERABILITY_DB_UPDATE_INTERVAL**: the NBE Security component will periodically check for updates on the external CVE database defined in `EXTERNAL_CVE_VULNERABILITY_DB`. You can control how frequently these check for updates and synchronizations are performed. By default this interval is set to 86400 seconds (1 day). If you'd like to change it (please consider the consequences of the network load caused by such an update, in case your DB is large), please run `export EXTERNAL_CVE_VULNERABILITY_DB_UPDATE_INTERVAL=`. Please also **note** that this check for updates also relies on Nuvla, meaning that whatever `EXTERNAL_CVE_VULNERABILITY_DB` is chosen, it shall also be recognized by Nuvla. If it is not, please contact us; +- **SECURITY_SCAN_INTERVAL**: defines how regular the security scans are. By default, the scans are performed every 1800 seconds (30 min). If you'd like to change this, simply `export SECURITY_SCAN_INTERVAL=`. Bare in mind that depending on the `EXTERNAL_CSV_VULNERABILITY_DB`'s size, a security scan can take some time (order of minutes) and consume quite a bit of CPU, so take caution when increasing the frequency of the scans; + +_NOTE_: you can set these environment variables by either replacing them directly in the NuvlaBox Engine's Compose Files, or by running `export =` directly on your terminal prior to the installation \ No newline at end of file diff --git a/docs/nuvlabox/nuvlabox-engine/v2/index.md b/docs/nuvlabox/nuvlabox-engine/v2/index.md new file mode 100644 index 0000000..71f4d54 --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v2/index.md @@ -0,0 +1,35 @@ +--- +layout: nuvlabox +title: v2 +nav_order: 1 +parent: NuvlaBox Engine +has_children: true +redirect_from: +- /nuvlabox/latest +--- + +## Compatibility Matrix for the NuvlaBox Engine v2 + +**NOTE**: this table is only relevant in case you have your own instance of Nuvla. When working with [Nuvla.io](https://nuvla.io), +all NuvlaBox Engine versions are supported. + +When installing the NBE, please make sure the target release is supported by the Nuvla instance being used ([Nuvla.io](https://nuvla.io) by default). + +NOTE: you can check Nuvla's version number on the page's footer, or at the "about" page (eg. [Nuvla.io current version](https://nuvla.io/ui/about)) + + +| NBE Release | Nuvla Release | +| :----: | :----: | +| 2.1.0 | 2.2.25+ | +| 2.0.6* | 2.2.25+ | +| 2.0.5* | 2.2.24+ | +| 2.0.4* | 2.2.24+ | +| 2.0.1* | 2.2.23+ | +| 2.0.0* | 2.2.20+ | + +\* **pre-release**: should not be used in production + + + + + diff --git a/docs/nuvlabox/nuvlabox-engine/v2/installation/index.md b/docs/nuvlabox/nuvlabox-engine/v2/installation/index.md new file mode 100644 index 0000000..b29856b --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v2/installation/index.md @@ -0,0 +1,11 @@ +--- +layout: nuvlabox +title: Installation +nav_order: 4 +parent: v2 +has_children: true +redirect_from: +- /nuvlabox/latest/nuvlabox-engine/quickstart +--- + +The NBE installation starts from Nuvla's [edge panel](https://nuvla.io/ui/edge). From there you can opt for one of two available installation methods: Compose Files bundle, or USB stick. diff --git a/docs/nuvlabox/nuvlabox-engine/v2/installation/install-with-compose-files.md b/docs/nuvlabox/nuvlabox-engine/v2/installation/install-with-compose-files.md new file mode 100644 index 0000000..6d820e7 --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v2/installation/install-with-compose-files.md @@ -0,0 +1,103 @@ +--- +layout: nuvlabox +title: Compose Files +nav_order: 1 +parent: Installation +grand_parent: v2 +--- + +# Install via Compose Files bundle + +1. login into [nuvla.io](https://nuvla.io) +2. from the [edge panel](https://nuvla.io/ui/edge), add a new `nuvlabox`, and either + 1. download the compose files from Nuvla, or + 2. copy the NuvlaBox UUID, and on your device, run `export NUVLABOX_UUID=` and download the compose files from [here](https://github.com/nuvlabox/deployment/releases) +3. copy the given `docker-compose -p nuvlabox ...` command from Nuvla, and on your device, in the same folder as the compose files from step 2., paste and run the command +4. after a few seconds, you should see your new NuvlaBox edge device becoming green in [Nuvla](https://nuvla.io/ui/edge), and if you run `docker ps` in your device, you should find (amongst others) something like: + ```bash + 9ca2441396d0 eclipse-mosquitto:1.6.12 "sh -c 'sleep 10 && …" 3 days ago Up 3 days 1883/tcp data-gateway.1.pgukfkffcn6ahooafaovzn6eq + 072743d2229a nuvladev/agent:master "./app.py" 3 weeks ago Up 3 days (healthy) 127.0.0.1:5080->80/tcp nuvlabox_agent_1 + 478817a492f2 nuvladev/compute-api:master "./api.sh" 3 weeks ago Up 3 days (healthy) 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp compute-api + 7d71e78eaf2b nuvlabox/vpn-client:1.0.0 "./openvpn-client.sh" 3 weeks ago Up 3 days vpn-client + c2ef3b427eae nuvlabox/system-manager:2.1.5 "./run.py" 3 weeks ago Up 3 days (healthy) 127.0.0.1:3636->3636/tcp nuvlabox_system-manager_1 + d561b3bbdc7f nuvla/job-lite:2.18.0 "/app/pause.py" 3 weeks ago Up 3 days (Paused) nuvlabox-job-engine-lite + f92b151430e3 nuvlabox/security:1.2.0 "./app.py" 3 weeks ago Up 3 days nuvlabox_security_1 + 24226c6f802c nuvlabox/peripheral-manager-network:1.1.4 "python manager.py" 3 weeks ago Up 3 days nuvlabox_peripheral-manager-network_1 + abd12f371adb nuvlabox/peripheral-manager-usb:2.0.4 "peripheral-manager-…" 3 weeks ago Up 3 days nuvlabox_peripheral-manager-usb_1 + 3b9114d398cd nuvlabox/on-stop:1.0.1 "./run.py pause" 3 weeks ago Up 3 days (Paused) nuvlabox-on-stop + ``` + +If this is not the case, please consult the [Troubleshooting page](/nuvlabox/latest/nuvlabox-engine/troubleshooting). + +### Halt the NuvlaBox + +In an edge environment, halting your devices is sometimes necessary. Halting **does not mean** you will delete the NuvlaBox nor its local data, but rather stop its services temporarily. + +**When rebooting** your edge device, the NuvlaBox will resume by itself, alongside your device's Docker service, so you don't need to do anything. + +**When manually halting** the NuvlaBox, you **must** find (or re-download) the original compose files in your edge device, and run `docker-compose -p nuvlabox down`. Then **to resume**, simply run `docker-compose -p nuvlabox up -d`. Please note that `` must correspond to the list of compose files you have used during the first installation. In our case, looking at the `docker ps` output from above, `` should be replaced by `-f docker-compose.yml -f docker-compose.usb.yml -f docker-compose.network.yml` (e.g., to halt the NuvlaBox we'd then run `docker-compose -p nuvlabox -f docker-compose.yml -f docker-compose.usb.yml -f docker-compose.network.yml down`) + + +### Upgrade/Downgrade the NuvlaBox + +**NOTE**: automated migrations are not currently supported. If you must upgrade from a NuvlaBox Engine v1 to v2, or vice versa, please contact us. + +#### From Nuvla + +The NBE can be updated directly from Nuvla. On the user interface, in each NuvlaBox page, you'll find an action called "Update NuvlaBox" (as depicted below) + +![nb-update-nuvla.png](/assets/img/nb-update-nuvla.png) + +By clicking on it, you can specify which version of the NuvlaBox Engine is the target for the release. Please note that this is an asynchronous action that can take a few minutes, depending on your edge device's network. + +--- + +#### Manually + +You can also SSH into your edge device, and find the original project folder where you saved your Compose files. + +If you've initially installed the NuvlaBox Engine according to the instructions above, then you should see all of its components by running: + +```bash +$ docker-compose -p nuvlabox -f docker-compose.yml -f docker-compose.usb.yml -f docker-compose.network.yml ps +``` + +You should get something like this: + +``` + Name Command State Ports +-------------------------------------------------------------------------------------------------------------------------- +compute-api ./api.sh Up (healthy) 0.0.0.0:5000->5000/tcp,:::5000->5000/tcp +deployment_agent_1 ./app.py Up (healthy) 127.0.0.1:5080->80/tcp +deployment_peripheral-manager-network_1 python manager.py Up +deployment_peripheral-manager-usb_1 peripheral-manager-usb Up +deployment_security_1 ./app.py Up +deployment_system-manager_1 ./run.py Up (healthy) 127.0.0.1:3636->3636/tcp +nuvlabox-job-engine-lite /app/pause.py Paused +nuvlabox-on-stop ./run.py pause Paused +vpn-client ./openvpn-client.sh Up +``` + +- **Cherry picking a NuvlaBox Engine component to be upgraded/downgraded:** let's say, as an example, that we want to upgrade the NuvlaBox Engine's Agent component. Then: + 1. open the `docker-compose.yml` file and find the `agent` service + 2. replace the corresponding Docker image tag (nuvlabox/agent:X.Y.Z) with the target version number. Save the file + 4. execute `docker-compose -p nuvlabox -f docker-compose.yml -f docker-compose.usb.yml -f docker-compose.network.yml up -d agent` + + This is valid for any NuvlaBox Engine component + +- **Upgrade/Downgrade the entire NuvlaBox Engine installation**: let's say we want to upgrade our existing NuvlaBox Engine installation to the latest release in [GitHub](https://github.com/nuvlabox/deployment/releases). Then: + 1. halt the NuvlaBox, as explained [above](#halt-the-nuvlabox) + 2. backup the Compose files from the project folder you are in into a different folder (just in case you need to rollback) + 3. download the Compose files from the [target release in GitHub](https://github.com/nuvlabox/deployment/releases) + 4. resume the NuvlaBox Engine installation by running `docker-compose -p nuvlabox -f docker-compose.yml -f docker-compose.usb.yml -f docker-compose.network.yml up -d` + 1. if your goal is also to add a new peripheral manager to the existing NuvlaBox, then simply add its compose file to this command. For example, to also start managing Bluetooth peripherals, run `docker-compose -p nuvlabox -f docker-compose.yml -f docker-compose.usb.yml -f docker-compose.network.yml -f docker-compose.bluetooth.yml up -d` + 2. if your goal is also to remove an existing peripheral manager from the NuvlaBox installation, then remove its compose file from this command, and add `--remove-orphans`. For example, to also stop managing Network peripherals, run `docker-compose -p nuvlabox -f docker-compose.yml -f docker-compose.usb.yml up -d --remove-orphans` + + +### Uninstall the NuvlaBox + +**NOTE**: this action is permanent, **unless** you keep a copy of the NuvlaBox's API Key/Secret credential. This credential can be found at `/var/lib/docker/volumes/nuvlabox_nuvlabox-db/_data/.activated`. + +To completely and **permanently** uninstall the NuvlaBox from your edge device, simply find your original compose files in the edge device, and run `docker-compose -p nuvlabox down -v`. The `-v` will remove the NuvlaBox local data volume, so all of its data will be lost. + +To re-install a new NuvlaBox from scratch in the same edge device, you'll need to go through the installation steps from above. If you have the API Key/Secret from the NuvlaBox you've just deleted, then you also have the choice to recover it, even from a different device, via the configuration variables `NUVLABOX_API_KEY` and `NUVLABOX_API_SECRET`. See the [NuvlaBox Engine configuration](/nuvlabox/nuvlabox-engine/v2/configuration/) for more details. diff --git a/docs/nuvlabox/nuvlabox-engine/v2/installation/install-with-usb-stick.md b/docs/nuvlabox/nuvlabox-engine/v2/installation/install-with-usb-stick.md new file mode 100644 index 0000000..d862748 --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v2/installation/install-with-usb-stick.md @@ -0,0 +1,117 @@ +--- +layout: nuvlabox +title: USB Stick +nav_order: 2 +parent: Installation +grand_parent: v2 +--- + +# Install via USB stick + +If your are looking to streamline the installation of the NuvlaBox Engine in your edge devices, then this is the best choice for you. + +The advantages of this installation method are: +- **NO** need for an external display +- **NO** need for SSH access to the device +- The same USB stick can be used **as many times** as needed +- **NO** technical expertise required + +Unlike the Compose file bundle, the USB stick installation method does not require manual user intervention, and thus does not support manual configuration of the NBE environment variable. **NUVLABOX_UUID**, **NUVLA_ENDPOINT** and **NUVLA_ENDPOINT_INSECURE** are automatically defined for you by Nuvla, during the installation process. + +It is _not_ yet possible to define variables like **HOSTNAME** and **VPN_INTERFACE_NAME** with this installation method. All possible NBE configurations for this installation method are set from Nuvla, at the time of creation of the USB stick file. + +### Additional requirements + +This installation method requires a specific NuvlaBox plugin to be installed in your Operating System, which will trigger the USB-based installation whenever you plug the flash drive. + +- if your devices **are running** a [NuvlaBox OS](/nuvlabox/nuvlabox-os.html), then you're good! You can jump straight to the [installation procedure below](#procedure) + +- if your devices **are NOT running** a [NuvlaBox OS](/nuvlabox/nuvlabox-os.html), then you **must** first prepare your operating system as follows: + + 1. make sure you are running a Linux distribution with `systemd` installed (we recommend using Debian or Ubuntu) + 2. get the latest version of the NuvlaBox USB Auto-installer plugin from GitHub: + + ```bash + git clone https://github.com/nuvlabox/nuvlabox-os.git /tmp/nuvlabox-os + + cd /tmp/nuvlabox-os + ``` + + 3. you'll find different NuvlaBox OS distributions here. These are enclosed within folders like `raspberrypi` (for a Raspbian-like NuvlaBox OS) or `generic` (for generic amd64 Debian-like NuvlaBox OS). Navigate to the folder that it closer to your own distribution + + ```bash + cd /tmp/nuvlabox-os/ + ``` + + 4. inside you'll find a `99_usb-auto-installer` folder + + ```bash + ls 99_usb-auto-installer + ``` + + 5. for all distros, inside the `99_usb-auto-installer` folder, you'll find an `.howToInstall` file. Run it + + ```bash + sudo sh .howToInstall + ``` + +You can now automate the installation of the NuvlaBox Engine into your fleet of edge devices. + +### Procedure + +If the OS of your edge device meets the [requirements](#additional-requirements), then all you have to do is to prepare your USB flash drive. + +Just follow these steps: + +1. go to [Nuvla](https://nuvla.io) and login +2. on the NuvlaBox tab, click `+add` and select the **USB stick** installation method + + ![nuvlabox-install-usb](/assets/img/nuvlabox-add-usb.png) + + With this method, a new API key credential is generated for you, and embedded into your USB stick. You can choose for how long this credentials should be valid. By default, this value is set for 30 days. After that, the credential expires and the corresponding USB stick becomes invalid. + +3. click `create` and wait. A new API key credential will be created and you'll be given a "trigger" file to download + + ![nuvlabox-add-usb-trigger](/assets/img/nuvlabox-add-usb-trigger.png) + +4. download the Trigger file, and copy it into your USB stick. You can place it anywhere within. + + **IMPORTANT:** make your your USB stick's filesystem is formatted as one of the following: _vfat, ext2, ext3, ext4, hfsplus_ or _ntfs_. + +5. plug your USB stick into your edge device. + +6. the NuvlaBox Auto-installer plugin that is installed in your device's OS will automatically be triggered by the USB stick, and kickstart the installation of the NuvlaBox Engine. At this stage, all you need to do is wait... + + It shouldn't take more than a few seconds for the process to start. Depending on your hardware, you might be able to get some external feedback on the progress of the installation. This feedback signal works for the following machine types: + - `raspberrypi`: + - **CONSTANT GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **started** and you can safely remove your USB stick + + ![rpi-nb-start](/assets/img/rpi-nb-start.gif) + + - **HEARTBEAT GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **finished** successfully + + ![rpi-nb-success](/assets/img/rpi-nb-success.gif) + + - **PULSING GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **failed** + + ![rpi-nb-error](/assets/img/rpi-nb-error.gif) + +7. go back to the NuvlaBox tab in [Nuvla](https://nuvla.io) and your new NuvlaBox resource will appear. + + +### Upgrade the NuvlaBox Engine + +It is also possible to use the USB stick method to upgrade your NuvlaBox Engine installation. + +The procedure is the same as described [above](#procedure). If in Nuvla, you select a different NuvlaBox Engine version than the one you have already installed in your devices, then, when you plug the USB stick into the device, the NuvlaBox Auto-installer will upgrade all the outdated NuvlaBox Engine components, according to your desired version. + + +### Overwrite an existing installation + +It is also possible to use the USB stick method to completely delete and re-install your NuvlaBox Engine installation. However, in order to avoid damaging an existing installation, this process can only happen if the following conditions are met: + +- your previous NuvlaBox Engine installation is misconfigured, or +- your NuvlaBox resource is DECOMMISSIONED or in ERROR in [Nuvla](https://nuvla.io/ui/edge), or +- your NuvlaBox resource does not exist anymore in [Nuvla](https://nuvla.io/ui/edge), + +then the NuvlaBox Auto-installer will completely remove the existing NuvlaBox Engine installation from your device, and install a fresh new one. diff --git a/docs/nuvlabox/nuvlabox-engine/v2/requirements.md b/docs/nuvlabox/nuvlabox-engine/v2/requirements.md new file mode 100644 index 0000000..3345705 --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v2/requirements.md @@ -0,0 +1,55 @@ +--- +layout: nuvlabox +title: Requirements +nav_order: 2 +parent: v2 +grand_parent: NuvlaBox Engine +redirect_from: + - /nuvlabox/latest/nuvlabox-engine/requirements +--- + +# Requirements + +To ensure a smooth and fully functional installation of the NuvlaBox Engine (**NBE**), please make sure you comply with the following system requirements. + + +## OS Requirements + +The NuvlaBox Engine is compliant with any OS that officially and fully supports Docker. We recommend one of the following: +- Ubuntu +- CentOS +- Debian (and Debian variants like Raspbian and Raspberry Pi OS) + +Other Docker-compliant Linux distributions should also work, but the NuvlaBox functionality will be subject to the level of Docker support the OS provides. + +Functionalities like the automatic discovery and categorization of peripherals are **not** guaranteed for macOS and Windows. + + +## Hardware Requirements + +In order to install the NBE and ensure its smooth execution over time, your device should have at least: + +- 1GB of RAM +- 2GB of free disk space + + +## Software Requirements + +Before you can install the NBE, please make sure you have: + +- [Docker Engine (version 18 or higher)](https://docs.docker.com/install/#supported-platforms), running in [Swarm mode](https://docs.docker.com/engine/swarm/swarm-tutorial/) +- [Docker Compose (version 1.27.4 or higher)](https://docs.docker.com/compose/install/) + + +## Network Requirements + +You need **an internet connection**. + +The NBE requires the following ports to be opened: + +| Port | Reason | +|-: |- | +| 3636 | This port is used by the `system-manager` to publish the internal NB dashboard | +| 5000 | Used by the `compute-api` as the relay endpoint for Docker. Ingress must be allowed | +| 5080 | This port is used by the `agent` to provide the internal REST API for other NB components to speak with, internally | +| 1194 | (optional) UDP connections must be allowed on this port in case you'd like to remotely establish a tunnel to the edge device, via the VPN Client | diff --git a/docs/nuvlabox/nuvlabox-engine/v2/troubleshooting.md b/docs/nuvlabox/nuvlabox-engine/v2/troubleshooting.md new file mode 100644 index 0000000..2a3a14c --- /dev/null +++ b/docs/nuvlabox/nuvlabox-engine/v2/troubleshooting.md @@ -0,0 +1,20 @@ +--- +layout: nuvlabox +title: Troubleshooting +nav_order: 6 +parent: v2 +grand_parent: NuvlaBox Engine +redirect_from: + - /nuvlabox/latest/nuvlabox-engine/troubleshooting +--- + +# Troubleshooting + + +
    Failed to downgrade my NuvlaBox Engine to v1 + +
    +Automated migrations are not currently supported. So even if it looks like your NuvlaBox Engine downgrade finished successfully, you'll soon realize, from Nuvla, that your NuvlaBox is not healthy. If you must downgrade from a NuvlaBox Engine v2 to v1, please contact us. +
    + +
    \ No newline at end of file diff --git a/docs/nuvlabox/v2/nuvlabox-os/index.md b/docs/nuvlabox/nuvlabox-os/index.md similarity index 85% rename from docs/nuvlabox/v2/nuvlabox-os/index.md rename to docs/nuvlabox/nuvlabox-os/index.md index e40f813..b8585a5 100644 --- a/docs/nuvlabox/v2/nuvlabox-os/index.md +++ b/docs/nuvlabox/nuvlabox-os/index.md @@ -1,8 +1,8 @@ --- layout: nuvlabox title: NuvlaBox OS -nav_order: 2 -parent: v2 +nav_order: 3 +parent: NuvlaBox has_children: false redirect_from: - /nuvlabox/latest/nuvlabox-os diff --git a/docs/nuvlabox/v1/deploying-apps/first-app.md b/docs/nuvlabox/v1/deploying-apps/first-app.md deleted file mode 100644 index 47989a1..0000000 --- a/docs/nuvlabox/v1/deploying-apps/first-app.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -layout: nuvlabox -title: Your First NuvlaBox App -nav_order: 1 -parent: Apps Deployment -grand_parent: v1 -has_children: false -old_version: true ---- - -# Deploying your first NuvlaBox Application - -Once you've installed either the NuvlaBox Engine or NuvlaBox OS, you'll find yourself with an Edge Computing capable device, that you can remotely manage from Nuvla. - -If your NuvlaBox installation was successful, you should now see the following in Nuvla: - - - from the [Edge panel](https://nuvla.io/ui/edge), your NuvlaBox is online - - in the [Infrastructures panel](https://nuvla.io/ui/infrastructures) you'll now see a new Docker Swarm infrastructure, named after your NuvlaBox - - in the [Credentials panel](https://nuvla.io/ui/credentials) you'll find the credentials for this infrastructure - ---- - -So, **let's deploy a Nuvla App into your NuvlaBox**: - - 1. login into [nuvla.io](https://nuvla.io) and go to the [App Store](https://nuvla.io/ui/apps) - - ![nuvla-app-store](/assets/img/app-store.png) - - 2. find your desired application (let's say Nginx for example) - 3. after making sure that App is compatible with your NuvlaBox's architecture, click `launch` - - ![nuvla-launch-app](/assets/img/launch-app.png) - - 4. select the right Credential for the NuvlaBox infrastructure you're deploying to - 5. if applicable, define any environment variables, configuration files and/or other runtime parameters that might be required by your app - 6. click `launch`, and you'll be redirected to your dashboard, where you can follow the state of your deployment diff --git a/docs/nuvlabox/v1/deploying-apps/index.md b/docs/nuvlabox/v1/deploying-apps/index.md deleted file mode 100644 index 5bd6930..0000000 --- a/docs/nuvlabox/v1/deploying-apps/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: nuvlabox -title: Apps Deployment -nav_order: 4 -parent: v1 -has_children: true -old_version: true ---- - -Deployment of Applications on NuvlaBox -======== - -This section provides examples on deployment of user applications on NuvlaBox. - -![nuvlabox-os-arch-detail](/assets/img/nuvlabox-os-arch-detail.png) - - - diff --git a/docs/nuvlabox/v1/how-to-choose.md b/docs/nuvlabox/v1/how-to-choose.md deleted file mode 100644 index e437b1e..0000000 --- a/docs/nuvlabox/v1/how-to-choose.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -layout: nuvlabox -title: NuvlaBox... Engine or OS? -nav_order: 1 -parent: v1 -old_version: true ---- - -# NuvlaBox Engine or OS? - -NuvlaBox allows you to create a smart edge device, such that you can share its computing power for all sorts of edge processing tasks. You have two ways of achieving this goal. - -#### NuvlaBox Engine - -> you can take an existing functional device (with an OS and Docker Engine already installed), and turn it into an Edge device. [Follow these instructions](/nuvlabox/v1/nuvlabox-engine). - - -#### NuvlaBox OS - -> if you have a hardware platform without an Operating System (OS) installed, you can install the NuvlaBox OS, a dedicated and optimised OS for the edge. [Follow these instructions](/nuvlabox/v1/nuvlabox-os). - -Both options will result in a functional NuvlaBox, connected to a Nuvla service, able to deliver an edge computing solution, at scale. diff --git a/docs/nuvlabox/v1/index.md b/docs/nuvlabox/v1/index.md deleted file mode 100644 index 16a944a..0000000 --- a/docs/nuvlabox/v1/index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -layout: nuvlabox -title: v1 -nav_order: 2 -description: "Secure and intelligent edge computing solution" -parent: NuvlaBox -has_children: true -old_version: true ---- - -![nuvlabox-logo](/assets/img/nuvlabox-logo.png){: .center-image } - -With NuvlaBox (**NB**), you can transform most ARM and x86 hardware platforms into a smart edge device, to be managed by a Nuvla service. - -To ensure a smooth edge deployment and operation, SixSq has certified a number of [hardware platforms](https://sixsq.com/products-and-services/nuvlabox/tech-spec), including x86 and ARM based systems, from HPE, Dell, Logic Supply, Raspberry Pi and Nvidia. - -But if you prefer to run on a different platform, SixSq offers a certification service, which will ensure you are able to deploy to this platform, at scale, without issues. Further, SixSq can also certify base operating systems (OS). Therefore, if you have your own operating system, as long as it supports Docker, SixSq also offers a certification process, ensuring that your operating system can run as a NuvlaBox OS. diff --git a/docs/nuvlabox/v1/nuvlabox-engine/index.md b/docs/nuvlabox/v1/nuvlabox-engine/index.md deleted file mode 100644 index e0632c3..0000000 --- a/docs/nuvlabox/v1/nuvlabox-engine/index.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -layout: nuvlabox -title: NuvlaBox Engine -nav_order: 1 -parent: v1 -has_children: true -old_version: true ---- - -NuvlaBox Engine -======== - -The NuvlaBox Engine (**NBE**) is the heart of the NuvlaBox (**NB**). It provides the foundation services of the NB, which in turn ensure a robust, feature-rich and secure remote management from Nuvla. - -The NBE is implemented as a set of loosely coupled, open-source and containerised micro-services. You can find NBE's source code in [NuvlaBox's GitHub organisation](https://github.com/nuvlabox). - -You can find all releases of the NBE at [https://github.com/nuvlabox/deployment](https://github.com/nuvlabox/deployment). - - -## Compatibility Matrix - -When installing the NBE, please make sure the target release is supported by the Nuvla instance being used ([Nuvla.io](https://nuvla.io) by default). - -_NOTE: you can check Nuvla's version number on the page's footer, or at the "about" page (eg. [Nuvla.io current version](https://nuvla.io/ui/about))_ - - -| NBE Release | Nuvla Release | -| :----: | :----: | -| 1.15.2 | 2.2.12+ | -| 1.15.1 | 2.2.12+ | -| 1.15.0 | 2.2.12+ | -| 1.14.0 | 2.2.12+ | -| 1.13.0 | 2.2.10+ | -| 1.12.0 | 2.2.10+ | -| 1.11.0 | 2.2.10+ | -| 1.10.0 | 2.2.7+ | -| 1.9.2 | 2.2.1+ | -| 1.9.1 | 2.2.1+ | -| 1.9.0 | 2.2.0+ | -| 1.8.0 | 2.1.17+ | -| 1.7.0 | 2.1.15+ | -| 1.6.0 | 2.1.12+ | -| 1.5.0 | 2.1.12+ | -| 1.4.0 | 2.1.10+ | -| 1.3.1 | 2.1.10+ | -| 1.3.0 | 2.1.9+ | -| 1.2.0 | 2.1.9+ | -| 1.1.0 | 2.1.3+ | -| 1.0.0 | 2.0.0+ | - - - - - - diff --git a/docs/nuvlabox/v1/nuvlabox-engine/quickstart.md b/docs/nuvlabox/v1/nuvlabox-engine/quickstart.md deleted file mode 100644 index 5c011f4..0000000 --- a/docs/nuvlabox/v1/nuvlabox-engine/quickstart.md +++ /dev/null @@ -1,203 +0,0 @@ ---- -layout: nuvlabox -title: Installation -nav_order: 4 -parent: NuvlaBox Engine -grand_parent: v1 -old_version: true ---- - -The NBE installation starts from Nuvla's [edge panel](https://nuvla.io/ui/edge). From there you can opt for one of two available installation methods: Compose file bundle, or USB stick. - -# Install via Compose file bundle - - 1. login into [nuvla.io](https://nuvla.io) - 2. from the [edge panel](https://nuvla.io/ui/edge), add a new `nuvlabox`, and either - 1. download the compose files from Nuvla, or - 2. copy the NuvlaBox UUID, and on your device, run `export NUVLABOX_UUID=` and download the compose files from [GitHub](https://github.com/nuvlabox/deployment/releases) - 3. copy the given `docker-compose -p nuvlabox ...` command from Nuvla, and on your device, alongside the compose files retrieved in step 2. above, paste and run the command - 4. after a few seconds, you should see your new NuvlaBox edge device becoming green in [Nuvla](https://nuvla.io/ui/edge), and if you run `docker ps` in your device, you should find (amongst others) something like: - ```bash - 865403c5d7f2 nuvlabox/system-manager:0.4.0 "./app.py" 3 weeks ago Up 6 hours (healthy) 127.0.0.1:3636->3636/tcp, 0.0.0.0:3637->3637/tcp nuvlabox_system-manager_1 - ``` - -### Halt the NuvlaBox - -In an edge environment, halting your devices is sometimes necessary. - -**When rebooting** your edge device, the NuvlaBox will resume by itself, alongside your device's Docker service, so you don't need to do anything. - -**When manually halting** the NuvlaBox, you can simply find the original compose files in your edge device, re-export the original environment variables (if not exported already), and run `docker-compose -p nuvlabox down`. Then **to resume**, simply run `docker-compose -p nuvlabox up -d`. - - -### Upgrade/Downgrade the NuvlaBox - -#### From Nuvla - -The NBE can be updated directly from Nuvla. On the user interface, in each NuvlaBox page, you'll find an action called "Update NuvlaBox" (as depicted below) - -![nb-update-nuvla.png](/assets/img/nb-update-nuvla.png) - -By clicking on it, you can specify which version of the NuvlaBox Engine is the target for the release. Please note that this is an asynchronous action that can take a few minutes, depending on your edge device's network. - -**Troubleshooting**: Please note that the update capability was only introduced in [NuvlaBox Engine v1.14.0](https://github.com/nuvlabox/deployment/releases/tag/1.14.0). You can still update your NuvlaBox to/from an older NuvlaBox Engine version, **however**, since the persistency of NB installation parameters was only introduced in v1.14.0, we can not guarantee that the final update will result in a similarly configured NBE! If you're updating to/from a NBE version <1.14.0, we recommend taking note of all the environment variables and Docker Compose arguments used during the installation, just in case a manual intervention is needed after an unsuccessful update. - ---- - -#### Manually - -You can also SSH into your edge device, and find the original project folder where you saved your Compose files. - -If you've initially installed the NuvlaBox Engine according to the instructions above, then you should see all of its components by running: - -```bash -$ docker-compose -p nuvlabox ps -``` - -You should get something like this: - -``` - Name Command State Ports --------------------------------------------------------------------------------------------------- -datagateway /entrypoint.sh --entrypoin ... Up 80/tcp -nbmosquitto /docker-entrypoint.sh /usr ... Up (healthy) 1883/tcp -nuvlabox_agent_1 ./app.py Up 5000/tcp -nuvlabox_compute-api_1 ./api.sh Up 0.0.0.0:5000->5000/tcp -nuvlabox_management-api_1 ./app.py Up (healthy) 0.0.0.0:5001->5001/tcp -nuvlabox_network-manager_1 /opt/nuvlabox/network-mana ... Up 1194/udp -nuvlabox_system-manager_1 ./app.py Up (healthy) 127.0.0.1:3636->3636/tcp -vpn-client ./openvpn-client.sh Up -``` - - - **Cherry picking a NuvlaBox Engine component to be upgraded/downgraded:** let's say, as an example, that we want to upgrade the NuvlaBox Engine's Agent component. Then: - 1. open the `docker-compose.yml` file and find the `agent` service - 2. replace the corresponding Docker image tag (nuvlabox/agent:X.Y.Z)with the target version number. Save the file - 3. re-import all the necessary environment variables for the component being upgraded. In this case, make sure that at least NUVLABOX_UUID is set (if you're using [Nuvla.io](https://nuvla.io) - 4. execute `docker-compose -p nuvlabox up -d agent` - - This is valid for any NuvlaBox Engine component - - - **Upgrade/Downgrade the entire NuvlaBox Engine installation**: let's say we want to upgrade our existing NuvlaBox Engine installation to the latest release in [GitHub](https://github.com/nuvlabox/deployment/releases). Then: - 1. halt the NuvlaBox with `docker-compose -p nuvlabox down`, as explained [above](#halt-the-nuvlabox) - 2. move (or delete) the Compose files from the project folder you are in - 3. download the Compose files from the [target release in GitHub](https://github.com/nuvlabox/deployment/releases) - 4. resume the NuvlaBox Engine installation by running `docker-compose -p nuvlabox up -d` - - -### Uninstall the NuvlaBox - -To completely and **permanently** uninstall the NuvlaBox from your edge device, simply find your original compose files in the edge device, and run `docker-compose -p nuvlabox down -v`. - -To re-install a new NuvlaBox from scratch in the same edge device, you'll need to go through the installation steps from above. - - - -# Install via USB stick - -If your are looking to streamline the installation of the NuvlaBox Engine in your edge devices, then this is the best choice for you. - -The advantages of this installation method are: - - **NO** need for an external display - - **NO** need for SSH access to the device - - The same USB stick can be used **as many times** as needed - - **NO** technical expertise required - -Unlike the Compose file bundle, the USB stick installation method does not require manual user intervention, and thus does not support manual configuration of the NBE environment variable. **NUVLABOX_UUID**, **NUVLA_ENDPOINT** and **NUVLA_ENDPOINT_INSECURE** are automatically defined for you by Nuvla, during the installation process. - -It is _not_ yet possible to define variables like **HOSTNAME** and **VPN_INTERFACE_NAME** with this installation method. All possible NBE configurations for this installation method are set from Nuvla, at the time of creation of the USB stick file. - -### Additional requirements - -This installation method requires a specific NuvlaBox plugin to be installed in your Operating System, which will trigger the USB-based installation whenever you plug the flash drive. - - - if your devices **are running** a [NuvlaBox OS](/nuvlabox/v1/nuvlabox-os), then you're good! You can jump straight to the [installation procedure below](#procedure) - - - if your devices **are NOT running** a [NuvlaBox OS](/nuvlabox/v1/nuvlabox-os), then you **must** first prepare your operating system as follows: - - 1. make sure you are running a Linux distribution with `systemd` installed (we recommend using Debian or Ubuntu) - 2. get the latest version of the NuvlaBox USB Auto-installer plugin from GitHub: - - ```bash - git clone https://github.com/nuvlabox/nuvlabox-os.git /tmp/nuvlabox-os - - cd /tmp/nuvlabox-os - ``` - - 3. you'll find different NuvlaBox OS distributions here. These are enclosed within folders like `raspberrypi` (for a Raspbian-like NuvlaBox OS) or `generic` (for generic amd64 Debian-like NuvlaBox OS). Navigate to the folder that it closer to your own distribution - - ```bash - cd /tmp/nuvlabox-os/ - ``` - - 4. inside you'll find a `99_usb-auto-installer` folder - - ```bash - ls 99_usb-auto-installer - ``` - - 5. for all distros, inside the `99_usb-auto-installer` folder, you'll find an `.howToInstall` file. Run it - - ```bash - sudo sh .howToInstall - ``` - -You can now automate the installation of the NuvlaBox Engine into your fleet of edge devices. - -### Procedure - -If the OS of your edge device meets the [requirements](#additional-requirements), then all you have to do is to prepare your USB flash drive. - -Just follow these steps: - - 1. go to [Nuvla](https://nuvla.io) and login - 2. on the NuvlaBox tab, click `+add` and select the **USB stick** installation method - - ![nuvlabox-install-usb](/assets/img/nuvlabox-add-usb.png) - - With this method, a new API key credential is generated for you, and embedded into your USB stick. You can choose for how long this credentials should be valid. By default, this value is set for 30 days. After that, the credential expires and the corresponding USB stick becomes invalid. - - 3. click `create` and wait. A new API key credential will be created and you'll be given a "trigger" file to download - - ![nuvlabox-add-usb-trigger](/assets/img/nuvlabox-add-usb-trigger.png) - - 4. download the Trigger file, and copy it into your USB stick. You can place it anywhere within. - - **IMPORTANT:** make your your USB stick's filesystem is formatted as one of the following: _vfat, ext2, ext3, ext4, hfsplus_ or _ntfs_. - - 5. plug your USB stick into your edge device. - - 6. the NuvlaBox Auto-installer plugin that is installed in your device's OS will automatically be triggered by the USB stick, and kickstart the installation of the NuvlaBox Engine. At this stage, all you need to do is wait... - - It shouldn't take more than a few seconds for the process to start. Depending on your hardware, you might be able to get some external feedback on the progress of the installation. This feedback signal works for the following machine types: - - `raspberrypi`: - - **CONSTANT GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **started** and you can safely remove your USB stick - - ![rpi-nb-start](/assets/img/rpi-nb-start.gif) - - - **HEARTBEAT GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **finished** successfully - - ![rpi-nb-success](/assets/img/rpi-nb-success.gif) - - - **PULSING GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **failed** - - ![rpi-nb-error](/assets/img/rpi-nb-error.gif) - - 7. go back to the NuvlaBox tab in [Nuvla](https://nuvla.io) and your new NuvlaBox resource will appear. - - -### Upgrade the NuvlaBox Engine - -It is also possible to use the USB stick method to upgrade your NuvlaBox Engine installation. - -The procedure is the same as described [above](#procedure). If in Nuvla, you select a different NuvlaBox Engine version than the one you have already installed in your devices, then, when you plug the USB stick into the device, the NuvlaBox Auto-installer will upgrade all the outdated NuvlaBox Engine components, according to your desired version. - - -### Overwrite an existing installation - -It is also possible to use the USB stick method to completely delete and re-install your NuvlaBox Engine installation. However, in order to avoid damaging an existing installation, this process can only happen if the following conditions are met: - - - your previous NuvlaBox Engine installation is misconfigured, or - - your NuvlaBox resource is DECOMMISSIONED or in ERROR in [Nuvla](https://nuvla.io/ui/edge), or - - your NuvlaBox resource does not exist anymore in [Nuvla](https://nuvla.io/ui/edge), - -then the NuvlaBox Auto-installer will completely remove the existing NuvlaBox Engine installation from your device, and install a fresh new one. diff --git a/docs/nuvlabox/v1/nuvlabox-os/index.md b/docs/nuvlabox/v1/nuvlabox-os/index.md deleted file mode 100644 index c0dcc8e..0000000 --- a/docs/nuvlabox/v1/nuvlabox-os/index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -layout: nuvlabox -title: NuvlaBox OS -nav_order: 2 -parent: v1 -has_children: false -redirect_from: - - /nuvlabox/nuvlabox-os/nuvlabox-os -old_version: true ---- - -![nuvlabox-os-arch-overview](/assets/img/nuvlabox-os-arch-overview.png) diff --git a/docs/nuvlabox/v2/contributing/agent-api.md b/docs/nuvlabox/v2/contributing/agent-api.md deleted file mode 100644 index 9f9d705..0000000 --- a/docs/nuvlabox/v2/contributing/agent-api.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -layout: nuvlabox -title: Before Starting -nav_order: 1 -parent: Contributing -grand_parent: v2 -has_children: false -redirect_from: - - /nuvlabox/latest/contributing/agent-api ---- - -Before you start contributing to the NuvlaBox software stack, you must be acquainted not only with the NB and NBE architectures and features, but also with the internal functionalities offered specifically for allowing the interaction between NBE micro-services. - -# The NBE Agent API - -As mentioned in the [NBE Architecture](/nuvlabox/v2/nuvlabox-engine/architecture), the NBE Agent is one of the most critical components of the NB. - -All outgoing communication to Nuvla pass through the `agent`. For that, it provides an internal REST API for other NBE micro-services to speak with when they need to reach out to Nuvla. - -This ensures that whatever new micro-services are added to the NB, they won't need to manipulate Nuvla credentials in order to reach out to Nuvla. Instead, the `agent` will validate and broker their requests, sanitizing whatever information is being passed. - -So in short, if you are building a new component that will run alongside the NBE as a micro-service, and you need to interact with Nuvla, you need to use the NBE Agent API as follows: - -## REST API - -The NBE Agent API can only be reached from inside the NuvlaBox! - - - If your micro-service is **running on the same local Docker network** as the `agent` (typically this network is called `nuvlabox_default`, otherwise you can double check its name by running `docker network ls`), then you can reach the API at `http://agent/api` - - or, - - - if your micro-service is **running in host mode** (same network scope as any other process on the host device), then you can reach the API at `http://127.0.0.1:5080` - ---- - - -### Get agent healthcheck - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='GET' endpoint='/api/healthcheck' maincolor='none' prefix='allowed:' lettercolor='black' %} - -Returns something if the agent and respective API are already up and running. This call is meant to be used as a healthcheck for other components that are waiting for the agent to be ready. - -**_Examples:_** - -{% include request_snippet.md file='api/agent-api-healthcheck.sh' actions='GET' endpoint='/api/healthcheck' %} - -{% include code_snippet.md file='api/agent-api-healthcheck.sh' language='shell' %} - -{% include response_snippet.md file='api/agent-api-healthcheck-response.md' %} - ---- - -### Re-commission the NuvlaBox - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST' endpoint='/api/commission' maincolor='none' prefix='allowed:' lettercolor='black' %} - -It might happen that due to a change in the NuvlaBox or a need to refresh certain credentials and/or system configurations, the NuvlaBox needs to be re-commissioned so that Nuvla can propagate the new changes. This call will trigger a NuvlaBox re-commissioning, according to the request payload. - -This call is tailored to be used by specific NuvlaBox components like the Network Manager. - -However, **if you must use it**, you'll need to POST a JSON payload compliant with the NuvlaBox `commission` schema described [here](https://github.com/nuvla/api-server/blob/master/code/src/sixsq/nuvla/server/resources/nuvlabox/workflow_utils.clj). - -**_Examples:_** - -{% include request_snippet.md file='api/agent-api-commission.sh' actions='POST' endpoint='/api/commission' %} - -{% include code_snippet.md file='api/agent-api-commission.sh' language='shell' %} - -{% include response_snippet.md file='api/agent-api-commission-response.md' %} - ---- - -### Manage a peripheral - - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='GET POST PUT DELETE' endpoint='/api/peripheral/' maincolor='none' prefix='allowed:' lettercolor='black' %} - -Provides reading and editing capabilities for peripherals. - -**_Examples:_** - -#### Get a list of all peripheral identifiers already registered: - -{% include request_snippet.md file='api/agent-api-peripheral-get.sh' actions='GET' endpoint='/api/peripheral' %} - -{% include code_snippet.md file='api/agent-api-peripheral-get.sh' language='shell' %} - -{% include response_snippet.md file='api/agent-api-peripheral-get-response.md' %} - -
    - - -#### Get the description of a specific peripheral, by identifier: - -{% include request_snippet.md file='api/agent-api-peripheral-get-specific.sh' actions='GET' endpoint='/api/peripheral/`identifier`' %} - -{% include code_snippet.md file='api/agent-api-peripheral-get-specific.sh' language='shell' %} - -{% include response_snippet.md file='api/agent-api-peripheral-get-specific-response.md' %} - -
    - -#### Add a new peripheral: - -{% include request_snippet.md file='api/agent-api-peripheral-post.sh' actions='POST' endpoint='/api/peripheral' %} - -{% include code_snippet.md file='api/agent-api-peripheral-post.sh' language='shell' %} - -{% include response_snippet.md file='api/agent-api-peripheral-post-response.md' %} - -
    - -#### Search for a peripheral by attribute: - -{% include request_snippet.md file='api/agent-api-peripheral-search.sh' actions='GET' endpoint='/api/peripheral?' %} - -{% include code_snippet.md file='api/agent-api-peripheral-search.sh' language='shell' %} - -{% include response_snippet.md file='api/agent-api-peripheral-search-response.md' %} - -
    - - -#### Search for a peripheral by identifier regex: - -{% include request_snippet.md file='api/agent-api-peripheral-search-regex.sh' actions='GET' endpoint='/api/peripheral?' %} - -{% include code_snippet.md file='api/agent-api-peripheral-search-regex.sh' language='shell' %} - -{% include response_snippet.md file='api/agent-api-peripheral-search-regex-response.md' %} - -
    - -#### Edit an existing peripheral - -{% include request_snippet.md file='api/agent-api-peripheral-put.sh' actions='PUT' endpoint='/api/peripheral/`identifier`' %} - -{% include code_snippet.md file='api/agent-api-peripheral-put.sh' language='shell' %} - -{% include response_snippet.md file='api/agent-api-peripheral-put-response.md' %} - -
    - - -#### Delete an existing peripheral - -{% include request_snippet.md file='api/agent-api-peripheral-delete.sh' actions='DELETE' endpoint='/api/peripheral/`identifier`' %} - -{% include code_snippet.md file='api/agent-api-peripheral-delete.sh' language='shell' %} - -{% include response_snippet.md file='api/agent-api-peripheral-delete-response.md' %} \ No newline at end of file diff --git a/docs/nuvlabox/v2/contributing/custom-peripheral-managers.md b/docs/nuvlabox/v2/contributing/custom-peripheral-managers.md deleted file mode 100644 index f2542bf..0000000 --- a/docs/nuvlabox/v2/contributing/custom-peripheral-managers.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -layout: nuvlabox -title: Custom Peripheral Managers -nav_order: 2 -parent: Contributing -has_children: false -grand_parent: v2 -redirect_from: - - /nuvlabox/latest/contributing/custom-peripheral-managers ---- - -Building your own NuvlaBox Peripheral Manager -======== - -There is a set of natively supported peripheral managers that you can opt to add to your NuvlaBox at installation time. Those are also open-source and can be found on GitHub [here](https://github.com/nuvlabox?q=peripheral-manager-). - -NuvlaBox Peripheral Managers are completely optional and should only be used if you'd like to have an automated mechanism to discover, register and manage peripheral devices that are attached to your NuvlaBox. Once registered, these peripheral devices can be visualized, managed and sometimes even directly controlled from Nuvla (like USB webcams). - -Due to the wide variety of IoT sensors/actuators and generic peripheral devices, it would be an impossible task for us at SixSq to develop all the NuvlaBox Peripheral Managers to support every single peripheral out there. - -## **This is where you come in!!** -{:style="text-align: center;"} - -Let's say you need a new NuvlaBox Peripheral Manager for a specific peripheral device. There are two ways you can go about it: - - 1. email us at [Support](mailto:support@sixsq.com) with your request and we'll try our best to accommodate your needs - - 2. develop your own NuvlaBox Peripheral Manager microservice - -If you go option 2., you should host your code in your own public/private repository, and then deploy alongside the NuvlaBox Engine. - -We support community-built NuvlaBox Peripheral Managers, so you can let us know about it and we can work together to make it official and available off the shelf from Nuvla! - ---- - -Building a new NuvlaBox Peripheral Manager is quite simple. We have built a transparent and generic REST API within the NuvlaBox Engine core installation that allows you to register and manage your peripheral devices in the Nuvla-NuvlaBox ecosystem without any in-depth knowledge nor code dependencies. - -There are only **2 requirements** for having your microservice functioning correctly as a NuvlaBox Peripheral Manager: - - a. _Your microservice needs to be on the same Docker network as the [NuvlaBox Agent component](https://github.com/nuvlabox/agent). This is usually guaranteed when you deploy all components at once, as described in the [Installation Quickstart](/nuvlabox/v2/nuvlabox-engine/quickstart)_ - - b. _Your code must manage the NuvlaBox peripheral devices through the management interface provided by the NuvlaBox Agent on port 80. The specification for this API can be found [here](https://github.com/nuvlabox/agent#manage-nuvlabox-peripherals)_ - - -Mocking a NuvlaBox Peripheral Manager ---------- - -Here's an example of a mock peripheral manager, that you can use as a starting point to build your own. - - -### Step 1 - -Create a working environment (local folder, GitHub repository, etc.) where you can put your code. - -We have created a [peripheral manager mock](https://github.com/nuvlabox/peripheral-manager-mock) for this exercise. - - -### Step 2 - -In that working environment, create your custom peripheral manager script. In our case, we're using a simple Shell script, so let's name our main manager script `peripheral-manager-mock.sh`. - -_peripheral-manager-mock.sh:_ -{% include code_snippet.md file='/nuvlabox-peripherals/peripheral-manager-mock_1.sh' language=shell %} - -#### Step 2.1 - -**Since this is an example**, we make certain assumptions. One of those is that we assume we know in advance the unique local identifier of our mock peripheral device. - -_peripheral-manager-mock.sh:_ -{% include code_snippet.md file='/nuvlabox-peripherals/peripheral-manager-mock_2.sh' language=shell %} - -**IMPORTANT**: unless you have a very special case, you should try to infer the peripheral identifier dynamically. - - -### Step 3 - -Our script needs to interact with the NuvlaBox Agent API for managing the mock peripheral, so let's build a couple of functions to help us to that. - -**NOTE**: these two functions are generic, so in most cases you can literally copy and paste them into your own scripts. - -_peripheral-manager-mock.sh:_ -{% include code_snippet.md file='/nuvlabox-peripherals/peripheral-manager-mock_3.sh' language=shell %} - - -### Step 4 - -Now to the actual peripheral discovery part of our script. According to our assumptions, our mock peripheral can be discovered via the existence of a certain file in the filesystem - _/dev/video0_. - -So it's quite a simple use case - all we need to do is to continuously watch that file, and trigger one of the functions from [Step 3](#step-3) above whenever the file is created or deleted. - -The `inotify-tools` package gives us a very useful tool for this purpose: `inotifywait` - -So our main code block would look something like this: -```shell -inotifywait -m -e create -e delete /dev | -while read -r directory event file -do - # We assume we only care about /dev/video0 - if [[ "${file}" = "video0" ]] - then - # If the mock peripheral was plugged in, then we want to register the new NuvlaBox peripheral - # otherwise, we want to remove it - if [[ "${event}" = "CREATE" ]] - then - #...do something - fi - - if [[ "${event}" = "DELETE" ]] - then - #...do something - fi - fi -done -``` - -Whenever the mock peripheral device is plugged, the CREATE event will be triggered and we'll need to: - 1. build the nuvlabox-resource JSON payload for that peripheral, according to the schema represented in [Nuvla API schema for NuvlaBox peripherals](https://nuvla.io/ui/documentation/nuvlabox-peripheral-1-1) - 2. send a POST request to the NuvlaBox Agent API, to register the new peripheral - -And, whenever the mock peripheral is unplugged, the DELETE event will be triggered, so we need to: - 1. send a DELETE request to the NuvlaBox Agent API with the corresponding peripheral identifier - -**Here's our final _peripheral-manager-mock.sh_ script!** - -_peripheral-manager-mock.sh:_ -{% include code_snippet.md file='/nuvlabox-peripherals/peripheral-manager-mock_4.sh' language=shell %} - - -### Step 5 - -Now that we've built our custom NuvlaBox Peripheral Manager for Mock peripherals (congrats), it's time to package our code. - -Let's build a Docker image that can be installed with the rest of the NuvlaBox Engine component. - -We want it to be **small**. So let's use Alpine, install our dependencies(`jq` and `curl` for the NuvlaBox Agent API functions, plus `inotify-tools` for watching the mock peripheral file), and copy our script into it. - -Build the following Dockerfile. - -_Dockerfile:_ -{% include code_snippet.md file='/nuvlabox-peripherals/Dockerfile' language=makefile %} - -### Step 6 - -We are now ready to build our Docker image. - -#### Simple build - -Just run `docker build . -t `. And the push the Docker image: `docker push `. - -#### Multi-platform build - -Make sure you have `docker buildx`. If not, have a look at: https://docs.docker.com/buildx/working-with-buildx/ - -```shell -# Create the build context: -docker buildx create --name multiplatformbuilder --use - -# Bootstrap the context and make sure you're targeted platforms are supported by it -docker buildx inspect --bootstrap - -# Build and push the Docker image -# Feel free to replace the platforms below by the ones you're targeting -docker buildx build --platform linux/arm/v6,linux/arm/v7,linux/amd64,linux/arm64 -t . --push -``` - -### Step 7 - - -We need a compose file to go alongside the other NuvlaBox Engine compose files. Remember to use **your Docker image** from [Step 6](#step-6), and to bind mount (read-only) the host's _/dev_ directory. - -_docker-compose.mock.yml:_ -{% include code_snippet.md file='/nuvlabox-peripherals/docker-compose.mock.yml' language=yaml %} - - -### Step 8 - -Finally, we can launch the custom NuvlaBox Peripheral Manager for Mock peripherals. - -Just add `-f docker-compose.mock.yml` to your NuvlaBox Engine installation command (as described in [NuvlaBox Installation](/nuvlabox/v2/nuvlabox-engine/quickstart) and that's it! - -**NOTE**: if you want to deploy your custom NuvlaBox Peripheral Manager after the NuvlaBox Engine has been installed, then please make sure that your container runs within the same Docker network as the NuvlaBox Agent. To do so, check in which Docker network your NuvlaBox Agent is running, via `docker network ls` and `docker inspect `, and add that network to your peripheral manager container, via the Compose property `networks` (see [Docker Compose docs](https://docs.docker.com/compose/compose-file/#networks)). - diff --git a/docs/nuvlabox/v2/contributing/index.md b/docs/nuvlabox/v2/contributing/index.md deleted file mode 100644 index 6284ae8..0000000 --- a/docs/nuvlabox/v2/contributing/index.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -layout: nuvlabox -title: Contributing -nav_order: 6 -parent: v2 -has_children: true -redirect_from: - - /nuvlabox/latest/contributing ---- - -Contributing to NuvlaBox -======== - -The NuvlaBox is a fully open-source project - [NuvlaBox in GitHub](https://github.com/nuvlabox/) - with all its components licensed under Apache 2.0. - -If you'd like to participate in the development of the NuvlaBox, either by writing new code or simply reporting issues and feature requests, you are free and encouraged to do so. - -For each NuvlaBox component, you'll find a Contributing guide within the respective GitHub repository. Here's an example for a [generic Contributing guide](https://github.com/nuvlabox/agent/blob/master/CONTRIBUTING.md). - -![for-contributors](/assets/img/uncle-sam.png){:.center-image } - - - diff --git a/docs/nuvlabox/v2/index.md b/docs/nuvlabox/v2/index.md deleted file mode 100644 index e1c0e82..0000000 --- a/docs/nuvlabox/v2/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -layout: nuvlabox -title: v2 -nav_order: 1 -description: "Secure and intelligent edge computing solution" -parent: NuvlaBox -has_children: true -redirect_from: - - /nuvlabox/latest ---- - -![nuvlabox-logo](/assets/img/nuvlabox-logo.png){: .center-image } - -With NuvlaBox (**NB**), you can transform most ARM and x86 hardware platforms into a smart edge device, to be managed by a Nuvla service. - -To ensure a smooth edge deployment and operation, SixSq has certified a number of [hardware platforms](https://sixsq.com/products-and-services/nuvlabox/tech-spec), including x86 and ARM based systems, from HPE, Dell, Logic Supply, Raspberry Pi and Nvidia. - -But if you prefer to run on a different platform, SixSq offers a certification service, which will ensure you are able to deploy to this platform, at scale, without issues. Further, SixSq can also certify base operating systems (OS). Therefore, if you have your own operating system, as long as it supports Docker, SixSq also offers a certification process, ensuring that your operating system can run as a NuvlaBox OS. diff --git a/docs/nuvlabox/v2/nuvlabox-engine/architecture.md b/docs/nuvlabox/v2/nuvlabox-engine/architecture.md deleted file mode 100644 index d888521..0000000 --- a/docs/nuvlabox/v2/nuvlabox-engine/architecture.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -layout: nuvlabox -title: Architecture -nav_order: 1 -parent: NuvlaBox Engine -grand_parent: v2 -redirect_from: - - /nuvlabox/latest/nuvlabox-engine/architecture ---- - -NuvlaBox Engine Architecture -======== - -The NuvlaBox Engine (**NBE**) runs as a set of loosely coupled containers. Under the hood, containers form the NBE components described in the following image: - -![nuvlabox-os-arch-detail](/assets/img/nuvlabox-os-arch-detail.png) - -| NBE Component | Description | -|-: |- | -| AGENT | The `agent` is the beating heart of the NBE. It is responsible for the NB activation, commissioning and monitoring procedures. All outgoing communication towards Nuvla shall pass by the `agent`, via its internal REST API | -| SYSTEM MANAGER | The `system-manager` is the NBE's watchdog. It runs independently of all the other components. During the NBE bootstrap, it double checks that the device has the minimum requirements to support a NB, and if so, it starts scanning the whole NB on a periodic basis, searching for faulty NBE containers and trying to fix them automatically. It also provides an internal dashboard on the host's `127.0.0.1:3636` endpoint, with the overall status of the NB | -| API | There are 2 externally accessible APIs managed by the NBE: the `compute-api` provides a TLS-encrypted relay point to Docker (for app & container management) on the host's `:5000` endpoint; and the `management-api` provides a TLS-encrypted and NB-specific management API for remote control of the NB, on the host's `:5001` endpoint | -| NETWORK MANAGER | The `network-manager` is responsible for ensuring a correct configuration of the host's network stack, in such a way that it supports the NBE's connectivity needs (such as the establishment of a VPN connection) | -| VPN CLIENT | The standalone `vpn-client` component is solely responsible for picking up an OpenVPN configuration set by the `network-manager` and establishing a secure VPN tunnel with SixSq's VPN server (or any other desired VPN server), ensuring that the NB is always remotely accessible | -| SECURITY | The `security` component is an autonomous self-assessment agent which scans the edge device on a configurable periodic basis, looking for vulnerabilities. Each potential vulnerability is compared with public reference databases (like the CVE) for a full categorization of the problem. These databases are also kept up to date due to internal synchronization procedure which are also scheduled with a configurable frequency. The most critical vulnerabilities are sent to Nuvla (via the `agent`) | -| DATA GATEWAY | The NBE `data-gateway` is a combination of micro-services which provides an abstraction layer between user applications and IoT sensors/actuators. Is is equipped with communication layer mechanisms (like an MQTT broker and a Reverse Proxy) which can, on demand, serve raw sensor data to any existing user applications, thus preventing users from having to embed complex sensor-specific data acquisition interfaces into their applications. Additionaly, and **optionally**, the NBE can also be deployed with the Data Gateway's FIWARE Processor, which is a sidekick micro-service that validates the schema of MQTT data, against FIWARE's data models, and upon successful validation, forwards data to a configurable outgoing endpoint. Learn how to make use of the Data Gateway in [this video](https://youtu.be/x7RKQWVq1Mc) | -| * PERIPHERAL MANAGER | The NBE has the concept of Peripheral Managers. These are **optional** micro-services which perform automatic detection and categorization of peripherals that *are* or *can be* connected to the edge device. Such peripheral information can then be used to activate sensor data acquisition throught the Data Gateway. Examples of existing peripheral managers are: `peripheral-manager-usb`, `peripheral-manager-bluetooth`, `peripheral-manager-modbus`, `peripheral-manager-gpu`, `peripheral-manager-network`, and others | \ No newline at end of file diff --git a/docs/nuvlabox/v2/nuvlabox-engine/configuration.md b/docs/nuvlabox/v2/nuvlabox-engine/configuration.md deleted file mode 100644 index bc47059..0000000 --- a/docs/nuvlabox/v2/nuvlabox-engine/configuration.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -layout: nuvlabox -title: Configuration -nav_order: 3 -parent: NuvlaBox Engine -grand_parent: v2 -redirect_from: - - /nuvlabox/latest/nuvlabox-engine/configuration ---- - -# NuvlaBox Engine (NBE) Configuration - -Before installing the NBE, you should be acquainted with all the configuration options available. Once installed, the NBE's configuration can only be changed through an update on full re-installation of the NBE. - - -## Environment Variables - -When installing the NBE, you can customize your NB via environment variables: - - - **NUVLABOX_UUID**: the unique Nuvla ID given to your NuvlaBox. Nuvla will provide this UUID. Also, if you've downloaded the compose files from Nuvla, this environment variable will already be set for you, otherwise, **you must set it** via `export NUVLABOX_UUID=`; - - **NUVLA_ENDPOINT**: endpoint for a Nuvla instance. By default it points to https://nuvla.io. But if you have your own Nuvla instance, you can point your NuvlaBox to it by running `export NUVLA_ENDPOINT=` before launching it; - - **NUVLA_ENDPOINT_INSECURE**: indicated whether to allow insecure (ignore TLS verification) communication between the NuvlaBox and Nuvla. By default it is set to **_false_**. In cases where you might have your own Nuvla instance, running on self-signed certificates, make sure you run `export NUVLA_ENDPOINT_INSECURE=True` before launching the NuvlaBox; - - **HOST**: your device's hostname. This is optional, and sometimes take by default from your `env`, if the variable `$HOSTNAME` exists. It is used to generate the self-signed NuvlaBox certificates; - - **VPN_INTERFACE_NAME**: introduced in v1.3.0. The NuvlaBox will have its own VPN client. By default it will create a new network interface called **_vpn_**. If this conflicts with your existing network configuration, then please run `export VPN_INTERFACE_NAME=` before launching the NuvlaBox (use `export NUVLABOX_VPN_IFACE=` for versions <1.16.1); - - **NUVLABOX_SSH_PUB_KEY**: introduced in v1.9.0. If set, it add the provided string as a public SSH key into the host's `${HOME}/.ssh/authorized_keys` file; - - **HOST_USER**: introduced in v1.9.0 and meant to be dynamically defined at installation time, to match the host's user who is installing the NuvlaBox Engine. This value is important for the SSH key management workflow and thus should only be manually fixed under very special circumstances, at the user's own risk. **Deprecated** in v1.16.1; - - **HOST_HOME**: introduced in v1.16.1, as a replacement for the deprecated `$HOST_USER`. This variable is taken automatically from the underlying host environment. It is used as part of the SSH key management mechanism; - - **SKIP_MINIMUM_REQUIREMENTS**: introduced in v1.10.0, when set to "True", it forces the installation of the NuvlaBox Engine without checking the system and software requirements. **Note**: this is not recommended, as the NuvlaBox might not behave as expected if the system requirements do not fulfil the minimum expectations; - - **NUVLABOX_ENGINE_VERSION**: introduced in v1.10.0. This is a variable which is set upstream and thus should not be changed by the user. Changing it manually can result in reporting and operational inconsistencies when managing and using the NuvlaBox; - - **EXTERNAL_CVE_VULNERABILITY_DB**: introduced in v1.11.0. It consists of a link to an external CVE database, in CSV format and compressed, to be used as the reference database for the vulnerability scans. By default it points to an [aggregated CVE databased compiled by SixSq](https://github.com/nuvla/vuln-db/blob/main/databases/all.aggregated.csv.gz), from multiple trusted sources. If you want to use your own CVE database, then simply `export EXTERNAL_CSV_VULNERABILITY_DB=`; - - **EXTERNAL_CVE_VULNERABILITY_DB_UPDATE_INTERVAL**: introduced in v1.11.0. The NBE Security component will periodically check for updates on the external CVE database defined in `EXTERNAL_CVE_VULNERABILITY_DB`. You can control for frequently these check for updates and synchronization are performed. By default this interval is set to 86400 seconds (1 day). If you'd like to change it (please consider the consequences of the network load caused by such an update, in case your DB is large), please run `export EXTERNAL_CVE_VULNERABILITY_DB_UPDATE_INTERVAL=`. Please also **note** that this check for updates also relies on Nuvla, meaning that whatever `EXTERNAL_CVE_VULNERABILITY_DB` is chosen, it shall also be recognized by Nuvla. If it is not, please contact us; - - **SECURITY_SCAN_INTERVAL**: introduced in v1.11.0. Defines how regular the security scans are. By default, the scans are performed every 1800 seconds (30 min). If you'd like to change this, simply `export SECURITY_SCAN_INTERVAL=`. Bare in mind that depending on the `EXTERNAL_CSV_VULNERABILITY_DB`'s size, a security scan can take some time (order of minutes) and consume quite a bit of CPU, so take caution when increasing the frequency of the scans; \ No newline at end of file diff --git a/docs/nuvlabox/v2/nuvlabox-engine/index.md b/docs/nuvlabox/v2/nuvlabox-engine/index.md deleted file mode 100644 index f57de9d..0000000 --- a/docs/nuvlabox/v2/nuvlabox-engine/index.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -layout: nuvlabox -title: NuvlaBox Engine -nav_order: 1 -parent: v2 -has_children: true -redirect_from: - - /nuvlabox/latest/nuvlabox-engine ---- - -NuvlaBox Engine -======== - -The NuvlaBox Engine (**NBE**) is the heart of the NuvlaBox (**NB**). It provides the foundation services of the NB, which in turn ensure a robust, feature-rich and secure remote management from Nuvla. - -The NBE is implemented as a set of loosely coupled, open-source and containerised micro-services. You can find NBE's source code in [NuvlaBox's GitHub organisation](https://github.com/nuvlabox). - -You can find all releases of the NBE at [https://github.com/nuvlabox/deployment](https://github.com/nuvlabox/deployment). - - -## Compatibility Matrix - -When installing the NBE, please make sure the target release is supported by the Nuvla instance being used ([Nuvla.io](https://nuvla.io) by default). - -_NOTE: you can check Nuvla's version number on the page's footer, or at the "about" page (eg. [Nuvla.io current version](https://nuvla.io/ui/about))_ - - -| NBE Release | Nuvla Release | -| :----: | :----: | -| 1.15.2 | 2.2.12+ | -| 1.15.1 | 2.2.12+ | -| 1.15.0 | 2.2.12+ | -| 1.14.0 | 2.2.12+ | -| 1.13.0 | 2.2.10+ | -| 1.12.0 | 2.2.10+ | -| 1.11.0 | 2.2.10+ | -| 1.10.0 | 2.2.7+ | -| 1.9.2 | 2.2.1+ | -| 1.9.1 | 2.2.1+ | -| 1.9.0 | 2.2.0+ | -| 1.8.0 | 2.1.17+ | -| 1.7.0 | 2.1.15+ | -| 1.6.0 | 2.1.12+ | -| 1.5.0 | 2.1.12+ | -| 1.4.0 | 2.1.10+ | -| 1.3.1 | 2.1.10+ | -| 1.3.0 | 2.1.9+ | -| 1.2.0 | 2.1.9+ | -| 1.1.0 | 2.1.3+ | -| 1.0.0 | 2.0.0+ | - - - - - - diff --git a/docs/nuvlabox/v2/nuvlabox-engine/quickstart.md b/docs/nuvlabox/v2/nuvlabox-engine/quickstart.md deleted file mode 100644 index fb1e69a..0000000 --- a/docs/nuvlabox/v2/nuvlabox-engine/quickstart.md +++ /dev/null @@ -1,204 +0,0 @@ ---- -layout: nuvlabox -title: Installation -nav_order: 4 -parent: NuvlaBox Engine -grand_parent: v2 -redirect_from: - - /nuvlabox/latest/nuvlabox-engine/quickstart ---- - -The NBE installation starts from Nuvla's [edge panel](https://nuvla.io/ui/edge). From there you can opt for one of two available installation methods: Compose file bundle, or USB stick. - -# Install via Compose file bundle - - 1. login into [nuvla.io](https://nuvla.io) - 2. from the [edge panel](https://nuvla.io/ui/edge), add a new `nuvlabox`, and either - 1. download the compose files from Nuvla, or - 2. copy the NuvlaBox UUID, and on your device, run `export NUVLABOX_UUID=` and download the compose files from [GitHub](https://github.com/nuvlabox/deployment/releases) - 3. copy the given `docker-compose -p nuvlabox ...` command from Nuvla, and on your device, alongside the compose files retrieved in step 2. above, paste and run the command - 4. after a few seconds, you should see your new NuvlaBox edge device becoming green in [Nuvla](https://nuvla.io/ui/edge), and if you run `docker ps` in your device, you should find (amongst others) something like: - ```bash - 865403c5d7f2 nuvlabox/system-manager:0.4.0 "./app.py" 3 weeks ago Up 6 hours (healthy) 127.0.0.1:3636->3636/tcp, 0.0.0.0:3637->3637/tcp nuvlabox_system-manager_1 - ``` - -### Halt the NuvlaBox - -In an edge environment, halting your devices is sometimes necessary. - -**When rebooting** your edge device, the NuvlaBox will resume by itself, alongside your device's Docker service, so you don't need to do anything. - -**When manually halting** the NuvlaBox, you can simply find the original compose files in your edge device, re-export the original environment variables (if not exported already), and run `docker-compose -p nuvlabox down`. Then **to resume**, simply run `docker-compose -p nuvlabox up -d`. - - -### Upgrade/Downgrade the NuvlaBox - -#### From Nuvla - -The NBE can be updated directly from Nuvla. On the user interface, in each NuvlaBox page, you'll find an action called "Update NuvlaBox" (as depicted below) - -![nb-update-nuvla.png](/assets/img/nb-update-nuvla.png) - -By clicking on it, you can specify which version of the NuvlaBox Engine is the target for the release. Please note that this is an asynchronous action that can take a few minutes, depending on your edge device's network. - -**Troubleshooting**: Please note that the update capability was only introduced in [NuvlaBox Engine v1.14.0](https://github.com/nuvlabox/deployment/releases/tag/1.14.0). You can still update your NuvlaBox to/from an older NuvlaBox Engine version, **however**, since the persistency of NB installation parameters was only introduced in v1.14.0, we can not guarantee that the final update will result in a similarly configured NBE! If you're updating to/from a NBE version <1.14.0, we recommend taking note of all the environment variables and Docker Compose arguments used during the installation, just in case a manual intervention is needed after an unsuccessful update. - ---- - -#### Manually - -You can also SSH into your edge device, and find the original project folder where you saved your Compose files. - -If you've initially installed the NuvlaBox Engine according to the instructions above, then you should see all of its components by running: - -```bash -$ docker-compose -p nuvlabox ps -``` - -You should get something like this: - -``` - Name Command State Ports --------------------------------------------------------------------------------------------------- -datagateway /entrypoint.sh --entrypoin ... Up 80/tcp -nbmosquitto /docker-entrypoint.sh /usr ... Up (healthy) 1883/tcp -nuvlabox_agent_1 ./app.py Up 5000/tcp -nuvlabox_compute-api_1 ./api.sh Up 0.0.0.0:5000->5000/tcp -nuvlabox_management-api_1 ./app.py Up (healthy) 0.0.0.0:5001->5001/tcp -nuvlabox_network-manager_1 /opt/nuvlabox/network-mana ... Up 1194/udp -nuvlabox_system-manager_1 ./app.py Up (healthy) 127.0.0.1:3636->3636/tcp -vpn-client ./openvpn-client.sh Up -``` - - - **Cherry picking a NuvlaBox Engine component to be upgraded/downgraded:** let's say, as an example, that we want to upgrade the NuvlaBox Engine's Agent component. Then: - 1. open the `docker-compose.yml` file and find the `agent` service - 2. replace the corresponding Docker image tag (nuvlabox/agent:X.Y.Z)with the target version number. Save the file - 3. re-import all the necessary environment variables for the component being upgraded. In this case, make sure that at least NUVLABOX_UUID is set (if you're using [Nuvla.io](https://nuvla.io) - 4. execute `docker-compose -p nuvlabox up -d agent` - - This is valid for any NuvlaBox Engine component - - - **Upgrade/Downgrade the entire NuvlaBox Engine installation**: let's say we want to upgrade our existing NuvlaBox Engine installation to the latest release in [GitHub](https://github.com/nuvlabox/deployment/releases). Then: - 1. halt the NuvlaBox with `docker-compose -p nuvlabox down`, as explained [above](#halt-the-nuvlabox) - 2. move (or delete) the Compose files from the project folder you are in - 3. download the Compose files from the [target release in GitHub](https://github.com/nuvlabox/deployment/releases) - 4. resume the NuvlaBox Engine installation by running `docker-compose -p nuvlabox up -d` - - -### Uninstall the NuvlaBox - -To completely and **permanently** uninstall the NuvlaBox from your edge device, simply find your original compose files in the edge device, and run `docker-compose -p nuvlabox down -v`. - -To re-install a new NuvlaBox from scratch in the same edge device, you'll need to go through the installation steps from above. - - - -# Install via USB stick - -If your are looking to streamline the installation of the NuvlaBox Engine in your edge devices, then this is the best choice for you. - -The advantages of this installation method are: - - **NO** need for an external display - - **NO** need for SSH access to the device - - The same USB stick can be used **as many times** as needed - - **NO** technical expertise required - -Unlike the Compose file bundle, the USB stick installation method does not require manual user intervention, and thus does not support manual configuration of the NBE environment variable. **NUVLABOX_UUID**, **NUVLA_ENDPOINT** and **NUVLA_ENDPOINT_INSECURE** are automatically defined for you by Nuvla, during the installation process. - -It is _not_ yet possible to define variables like **HOSTNAME** and **VPN_INTERFACE_NAME** with this installation method. All possible NBE configurations for this installation method are set from Nuvla, at the time of creation of the USB stick file. - -### Additional requirements - -This installation method requires a specific NuvlaBox plugin to be installed in your Operating System, which will trigger the USB-based installation whenever you plug the flash drive. - - - if your devices **are running** a [NuvlaBox OS](/nuvlabox/v2/nuvlabox-os), then you're good! You can jump straight to the [installation procedure below](#procedure) - - - if your devices **are NOT running** a [NuvlaBox OS](/nuvlabox/v2/nuvlabox-os), then you **must** first prepare your operating system as follows: - - 1. make sure you are running a Linux distribution with `systemd` installed (we recommend using Debian or Ubuntu) - 2. get the latest version of the NuvlaBox USB Auto-installer plugin from GitHub: - - ```bash - git clone https://github.com/nuvlabox/nuvlabox-os.git /tmp/nuvlabox-os - - cd /tmp/nuvlabox-os - ``` - - 3. you'll find different NuvlaBox OS distributions here. These are enclosed within folders like `raspberrypi` (for a Raspbian-like NuvlaBox OS) or `generic` (for generic amd64 Debian-like NuvlaBox OS). Navigate to the folder that it closer to your own distribution - - ```bash - cd /tmp/nuvlabox-os/ - ``` - - 4. inside you'll find a `99_usb-auto-installer` folder - - ```bash - ls 99_usb-auto-installer - ``` - - 5. for all distros, inside the `99_usb-auto-installer` folder, you'll find an `.howToInstall` file. Run it - - ```bash - sudo sh .howToInstall - ``` - -You can now automate the installation of the NuvlaBox Engine into your fleet of edge devices. - -### Procedure - -If the OS of your edge device meets the [requirements](#additional-requirements), then all you have to do is to prepare your USB flash drive. - -Just follow these steps: - - 1. go to [Nuvla](https://nuvla.io) and login - 2. on the NuvlaBox tab, click `+add` and select the **USB stick** installation method - - ![nuvlabox-install-usb](/assets/img/nuvlabox-add-usb.png) - - With this method, a new API key credential is generated for you, and embedded into your USB stick. You can choose for how long this credentials should be valid. By default, this value is set for 30 days. After that, the credential expires and the corresponding USB stick becomes invalid. - - 3. click `create` and wait. A new API key credential will be created and you'll be given a "trigger" file to download - - ![nuvlabox-add-usb-trigger](/assets/img/nuvlabox-add-usb-trigger.png) - - 4. download the Trigger file, and copy it into your USB stick. You can place it anywhere within. - - **IMPORTANT:** make your your USB stick's filesystem is formatted as one of the following: _vfat, ext2, ext3, ext4, hfsplus_ or _ntfs_. - - 5. plug your USB stick into your edge device. - - 6. the NuvlaBox Auto-installer plugin that is installed in your device's OS will automatically be triggered by the USB stick, and kickstart the installation of the NuvlaBox Engine. At this stage, all you need to do is wait... - - It shouldn't take more than a few seconds for the process to start. Depending on your hardware, you might be able to get some external feedback on the progress of the installation. This feedback signal works for the following machine types: - - `raspberrypi`: - - **CONSTANT GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **started** and you can safely remove your USB stick - - ![rpi-nb-start](/assets/img/rpi-nb-start.gif) - - - **HEARTBEAT GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **finished** successfully - - ![rpi-nb-success](/assets/img/rpi-nb-success.gif) - - - **PULSING GREEN LED** for 10 sec. This means the NuvlaBox Engine installation process has **failed** - - ![rpi-nb-error](/assets/img/rpi-nb-error.gif) - - 7. go back to the NuvlaBox tab in [Nuvla](https://nuvla.io) and your new NuvlaBox resource will appear. - - -### Upgrade the NuvlaBox Engine - -It is also possible to use the USB stick method to upgrade your NuvlaBox Engine installation. - -The procedure is the same as described [above](#procedure). If in Nuvla, you select a different NuvlaBox Engine version than the one you have already installed in your devices, then, when you plug the USB stick into the device, the NuvlaBox Auto-installer will upgrade all the outdated NuvlaBox Engine components, according to your desired version. - - -### Overwrite an existing installation - -It is also possible to use the USB stick method to completely delete and re-install your NuvlaBox Engine installation. However, in order to avoid damaging an existing installation, this process can only happen if the following conditions are met: - - - your previous NuvlaBox Engine installation is misconfigured, or - - your NuvlaBox resource is DECOMMISSIONED or in ERROR in [Nuvla](https://nuvla.io/ui/edge), or - - your NuvlaBox resource does not exist anymore in [Nuvla](https://nuvla.io/ui/edge), - -then the NuvlaBox Auto-installer will completely remove the existing NuvlaBox Engine installation from your device, and install a fresh new one. diff --git a/docs/nuvlabox/v2/nuvlabox-engine/requirements.md b/docs/nuvlabox/v2/nuvlabox-engine/requirements.md deleted file mode 100644 index c6a7bf5..0000000 --- a/docs/nuvlabox/v2/nuvlabox-engine/requirements.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -layout: nuvlabox -title: Requirements -nav_order: 1 -parent: NuvlaBox Engine -grand_parent: v2 -redirect_from: - - /nuvlabox/latest/nuvlabox-engine/requirements ---- - -# Requirements - -To ensure a smooth and fully functional installation of the NuvlaBox Engine (**NBE**), please make sure you comply with the following system requirements. - - -## OS Requirements - - -Ideally, you should be running one of the following: - - Ubuntu - - CentOS - - Debian (and Debian variants like Raspbian and Raspberry Pi OS) - -Other Linux distributions should also work, but will require testing. - -Functionalities like the automatic discovery and categorization of peripherals are **not** ensured for macOS and Windows. - - -## Hardware Requirements - -In order to install the NBE and ensure its smooth execution over time, your device should have at least: - - - 1GB of RAM - - 2GB of free disk space - - -## Software Requirements - -Before you can install the NBE, please make sure you have: - - - [Docker Engine (version 18 or higher)](https://docs.docker.com/install/#supported-platforms), running in [Swarm mode](https://docs.docker.com/engine/swarm/swarm-tutorial/) - - [Docker Compose (version 1.27.4 or higher)](https://docs.docker.com/compose/install/) - - -## Network Requirements - -You need **an internet connection**. - -The NBE requires the following ports to be opened: - -| Port | Reason | -|-: |- | -| 3636 | Used by the `system-manager` to publish the internal NB dashboard | -| 5000 | Used by the `compute-api` as the relay endpoint for Docker | -| 5001 | Used by the `management-api` for the NB remote management REST API | - From 77a157557a90f29b3eaa544d4f596df82174ca8b Mon Sep 17 00:00:00 2001 From: Cristovao Cordeiro Date: Fri, 3 Dec 2021 16:16:43 +0100 Subject: [PATCH 2/6] add troubleshooting item --- .../nuvlabox-engine/v1/troubleshooting.md | 16 ++++++++++++++++ .../nuvlabox-engine/v2/troubleshooting.md | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/docs/nuvlabox/nuvlabox-engine/v1/troubleshooting.md b/docs/nuvlabox/nuvlabox-engine/v1/troubleshooting.md index 367744d..d3592f0 100644 --- a/docs/nuvlabox/nuvlabox-engine/v1/troubleshooting.md +++ b/docs/nuvlabox/nuvlabox-engine/v1/troubleshooting.md @@ -14,6 +14,22 @@ old_version: true
    Please note that the update capability was only introduced in [NuvlaBox Engine v1.14.0](https://github.com/nuvlabox/deployment/releases/tag/1.14.0). You can still update your NuvlaBox to/from an older NuvlaBox Engine version, **however**, since the persistency of NB installation parameters was only introduced in v1.14.0, we can not guarantee that the final update will result in a similarly configured NBE! If you're updating to/from a NBE version <1.14.0, we recommend taking note of all the environment variables and Docker Compose arguments used during the installation, just in case a manual intervention is needed after an unsuccessful update. +
    + + +--- + + +
    ERROR: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection + +
    +If you are getting this error while installing the NuvlaBox Engine: + +```bash +ERROR: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) +``` + +then you might be experiencing some networking issues with your setup. Try restarting your Docker Daemon (e.g. `systemctl restart docker` on Ubuntu), or ultimately, restart your device. If none of these solutions work, have a look at this [thread](https://forums.docker.com/t/docker-pull-results-in-request-canceled-while-waiting-for-connection-client-timeout-exceeded-while-awaiting-headers/73064/27)
    \ No newline at end of file diff --git a/docs/nuvlabox/nuvlabox-engine/v2/troubleshooting.md b/docs/nuvlabox/nuvlabox-engine/v2/troubleshooting.md index 2a3a14c..0ee2e44 100644 --- a/docs/nuvlabox/nuvlabox-engine/v2/troubleshooting.md +++ b/docs/nuvlabox/nuvlabox-engine/v2/troubleshooting.md @@ -17,4 +17,21 @@ redirect_from: Automated migrations are not currently supported. So even if it looks like your NuvlaBox Engine downgrade finished successfully, you'll soon realize, from Nuvla, that your NuvlaBox is not healthy. If you must downgrade from a NuvlaBox Engine v2 to v1, please contact us. + + +--- + + +
    ERROR: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection + +
    +If you are getting this error while installing the NuvlaBox Engine: + +```bash +ERROR: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) +``` + +then you might be experiencing some networking issues with your setup. Try restarting your Docker Daemon (e.g. `systemctl restart docker` on Ubuntu), or ultimately, restart your device. If none of these solutions work, have a look at this [thread](https://forums.docker.com/t/docker-pull-results-in-request-canceled-while-waiting-for-connection-client-timeout-exceeded-while-awaiting-headers/73064/27) +
    +
    \ No newline at end of file From f0ea9be518e0965794c1abdf685188de0f7f70b7 Mon Sep 17 00:00:00 2001 From: schaubl Date: Mon, 13 Dec 2021 16:35:17 +0100 Subject: [PATCH 3/6] Updated network requirements and v2 compatibility matrix. --- docs/nuvlabox/nuvlabox-engine/v1/requirements.md | 4 ++-- docs/nuvlabox/nuvlabox-engine/v2/index.md | 5 +++-- docs/nuvlabox/nuvlabox-engine/v2/requirements.md | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/nuvlabox/nuvlabox-engine/v1/requirements.md b/docs/nuvlabox/nuvlabox-engine/v1/requirements.md index 36840dd..c109bd3 100644 --- a/docs/nuvlabox/nuvlabox-engine/v1/requirements.md +++ b/docs/nuvlabox/nuvlabox-engine/v1/requirements.md @@ -50,5 +50,5 @@ The NBE requires the following ports to be opened: |-: |- | | 3636 | Used by the `system-manager` to publish the internal NB dashboard | | 5000 | Used by the `compute-api` as the relay endpoint for Docker | -| 5001 | Used by the `management-api` for the NB remote management REST API | - +| 5001 | Used by the `management-api` for the NB remote management REST API | +| 1194 | (optional) outgoing UDP connections to vpn.nuvlabox.com must be allowed on this port in case you'd like to remotely connect to the edge device, via the VPN Client | diff --git a/docs/nuvlabox/nuvlabox-engine/v2/index.md b/docs/nuvlabox/nuvlabox-engine/v2/index.md index 71f4d54..a9d9fe7 100644 --- a/docs/nuvlabox/nuvlabox-engine/v2/index.md +++ b/docs/nuvlabox/nuvlabox-engine/v2/index.md @@ -19,8 +19,9 @@ NOTE: you can check Nuvla's version number on the page's footer, or at the "abou | NBE Release | Nuvla Release | -| :----: | :----: | -| 2.1.0 | 2.2.25+ | +| :----: | :----: | +| 2.1.1 | 2.2.25+ | +| 2.1.0 | 2.2.25+ | | 2.0.6* | 2.2.25+ | | 2.0.5* | 2.2.24+ | | 2.0.4* | 2.2.24+ | diff --git a/docs/nuvlabox/nuvlabox-engine/v2/requirements.md b/docs/nuvlabox/nuvlabox-engine/v2/requirements.md index 3345705..25ff0a7 100644 --- a/docs/nuvlabox/nuvlabox-engine/v2/requirements.md +++ b/docs/nuvlabox/nuvlabox-engine/v2/requirements.md @@ -52,4 +52,4 @@ The NBE requires the following ports to be opened: | 3636 | This port is used by the `system-manager` to publish the internal NB dashboard | | 5000 | Used by the `compute-api` as the relay endpoint for Docker. Ingress must be allowed | | 5080 | This port is used by the `agent` to provide the internal REST API for other NB components to speak with, internally | -| 1194 | (optional) UDP connections must be allowed on this port in case you'd like to remotely establish a tunnel to the edge device, via the VPN Client | +| 1194 | (optional) outgoing UDP connections to vpn.nuvlabox.com must be allowed on this port in case you'd like to remotely connect to the edge device, via the VPN Client | From 0b9433141df0dcc4ed39cf0d044220ba5db861ab Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Tue, 21 Dec 2021 16:13:07 +0100 Subject: [PATCH 4/6] wip --- docs/nuvla/installation.md | 2 +- docs/nuvla/user-guide/api.md | 437 ------------------ docs/nuvla/user-guide/api/credential.md | 99 ++++ docs/nuvla/user-guide/api/deployment.md | 24 + docs/nuvla/user-guide/api/index.md | 15 + .../api/infrastructure-service-group.md | 28 ++ .../user-guide/api/infrastructure-service.md | 74 +++ docs/nuvla/user-guide/api/principle.md | 216 +++++++++ docs/nuvla/user-guide/api/session.md | 37 ++ docs/nuvla/user-guide/api/to-be-deleted.md | 46 ++ docs/nuvla/user-guide/api/user.md | 34 ++ .../{user-guide.md => user-guide/index.md} | 2 +- 12 files changed, 575 insertions(+), 439 deletions(-) delete mode 100644 docs/nuvla/user-guide/api.md create mode 100644 docs/nuvla/user-guide/api/credential.md create mode 100644 docs/nuvla/user-guide/api/deployment.md create mode 100644 docs/nuvla/user-guide/api/index.md create mode 100644 docs/nuvla/user-guide/api/infrastructure-service-group.md create mode 100644 docs/nuvla/user-guide/api/infrastructure-service.md create mode 100644 docs/nuvla/user-guide/api/principle.md create mode 100644 docs/nuvla/user-guide/api/session.md create mode 100644 docs/nuvla/user-guide/api/to-be-deleted.md create mode 100644 docs/nuvla/user-guide/api/user.md rename docs/nuvla/{user-guide.md => user-guide/index.md} (86%) diff --git a/docs/nuvla/installation.md b/docs/nuvla/installation.md index 5f72886..aa941fd 100644 --- a/docs/nuvla/installation.md +++ b/docs/nuvla/installation.md @@ -1,7 +1,7 @@ --- layout: page title: Installation -nav_order: 1 +nav_order: 12 parent: Nuvla has_children: true permalink: /nuvla/installation diff --git a/docs/nuvla/user-guide/api.md b/docs/nuvla/user-guide/api.md deleted file mode 100644 index a9df300..0000000 --- a/docs/nuvla/user-guide/api.md +++ /dev/null @@ -1,437 +0,0 @@ ---- -layout: page -title: API -parent: User Guide -grand_parent: Nuvla -nav_order: 12 -permalink: /nuvla/api ---- - -- [REST API](#rest-api) - * [Understanding the Nuvla REST API output format](#understanding-the-nuvla-rest-api-output-format) - * [API Syntax](#api-syntax) - * [Resources](#resources) - + [cloud-entry-point](#cloud-entry-point) - + [Get the cloud entry point](#get-the-cloud-entry-point) - + [credential](#credential) - + [API key credential](#generate-an-api-key-credential) - + [Docker Swarm token credential](#docker-swarm-token-credential) - + [Infrastructure Service S3 credential](#infrastructure-service-s3-credential) - + [Infrastructure Service Docker Swarm HTTP API credential](#infrastructure-service-docker-swarm-http-api-credential) - + [Infrastructure Service Kubernetes HTTP API credential](#infrastructure-service-kubernetes-http-api-credential) - + [deployment](#deployment) - + [Start/Stop an application](#startstop-an-application) - + [evidence-record](#evidence-record) - + [Create an evidence record](#create-an-evidence-record) - + [infrastructure-service](#infrastructure-service) - + [Create Docker Swarm infrastructure service](#create-docker-swarm-infrastructure-service) - + [Create Kubernetes infrastructure service](#create-kubernetes-infrastructure-service) - + [Create S3 infrastructure service](#create-s3-infrastructure-service) - + [Create generic infrastructure service](#create-generic-infrastructure-service) - + [infrastructure-service-group](#infrastructure-service-group) - + [Create an infrastructure-service-group](#create-an-infrastructure-service-group) - + [session](#session) - + [Login with username and password](#login-with-username-and-password) - + [Login with API keys](#login-with-api-keys) - + [user](#user) - + [Create a user with an email and a password](#create-a-user-with-an-email-and-a-password) - + [voucher](#voucher) - + [Create a new voucher](#create-a-new-voucher) -- [Python API](#python-api) - - -# REST API - -Nuvla provides a uniform and extensible HTTP-based RESTful API, for the management of Nuvla resources. A Nuvla resource can be anything you can perform an action on, through Nuvla, like your own user profile, a Nuvla application, credentials, etc. - -Users have at their disposal all the usual CRUD (Create, Read, Update, Delete) operations, plus Searching and Querying. - - -| Action | HTTP Method | Target | -| --- | --- | --- | -| Search | GET or PUT | resource collection | -| Add (create) | POST | resource collection | -| Read | GET | resource | -| Edit (update) | PUT | resource | -| Delete | DELETE | resource | - -Finally, due to its versatility, Nuvla's API also provide custom operations for certain resources. These will be covered individually in the subsections below. - -Here are a few examples on how to construct the different HTTP requests: - - - **GET** all the resources of a specific type: - - `GET /api/` - - - **GET** a specific resource: - - `GET /api//` - - - **CREATE** a new resource: - - ``` -POST /api/ - HEADERS Content-type:application/json - DATA - ``` - - - **EDIT** an existing resource: - - ``` -PUT /api// - HEADERS Content-type:application/json - DATA - ``` - - - **DELETE** a resource: - - `DELETE /api//` - - - -## Understanding the Nuvla REST API output format - -All the Nuvla API calls will return a JSON output, and you'll notice that all of these outputs contain a set of common attributes: - - - _**id**_: unique resource identifier, defined by the API server - - _**acl**_: fine-grained access-control list, used for managing authorization process for each resource and its collections of resources. If not defined by the user, the API server will default it based on the requesting user credentials. - - _**created**_: timestamp of creation, defined by the API server - - _**updated**_: timestamp of the last update, defined by the API server - - _**resource-type**_: type of resource, defined by the API server - - _**operations**_: set of available operations for that resource, defined by the API server - - _**name**_: optional user-friendly name for a specific resource, defined by the user or defaulted to `None` if undefined - - _**description**_: optional verbose description for a specific resource, defined by the user or defaulted to `None` if undefined - - -## API Syntax - -The Nuvla REST API endpoints are constructed with the following pattern: - -`/api////` - -where - - - `` is the Kebab Case name of the resource collection you're accessing, - - `` is the unique identifier for the specific resource you're managing, - - `` is a custom additional operation that might be allowed for that resource. - -On top of that, Nuvla's REST API also offers searching and querying through a parameter-based set of keywords: - -`/api/?param=value¶m=value...` - -where - -| Parameter | Description | Examples | -| --- | --- | --- | -| `filter` | Used to return only the set of resources that have an `attribute` matching a certain `value` | `?filter=name="my-resource"`

    `?filter=people/gender!="male" and people/age>=21`

    `?filter=application-name^="my-app-"` | -| `orderby` | To order the returned resources by the specified attribute | `?orderby=created:desc`

    `?orderby=people/surname:asc` | -| `aggregation` | On top of the requested resources, it will also return on-the-fly aggregations based on the specified function. Available functions: `avg`, `max`, `min`, `sum`, `cardinality`, `terms`, `stats`, `extendedstats`, `percentiles`, `value_count`, `missing` | `?aggregation=avg:people/age` | -| `last` and `first` | Returns a range of resources by setting the first and last (1-based) query parameters | `?first=10&last=20` | -| `select` | Selects only certain attributes to be returned by the server. Avoiding sending information that will not be useful reduces the load on the network and the server | `?select=people/id` | - - -## Resources - -Resources are managed individually, which means that the data schemas and available operations might defer from one to the other. These options are all explained and exemplified in the following sections. - - -### cloud-entry-point - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='GET' endpoint='/api/cloud-entry-point' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The primary directory of resources is the Cloud Entry Point (CEP), which contains a list of named resource collections and their URLs (in the href field) relative to the baseURI value. The CEP also contains some other metadata. - -The endpoint is accessible for all registered and anonymous Nuvla users. - ---- - -_Examples_ - -##### Get the cloud entry point - -{% include request_snippet.md file='api/cep.sh' actions='GET' endpoint='/api/cloud-entry-point' %} - -{% include code_snippet.md file='api/cep.sh' language='shell' %} - -{% include response_snippet.md file='api/cep-response.md' %} - - -### credential - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/credential/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The `credential` resource is used to save all the credentials necessary to -manage your Nuvla resources. From API keys, to Container Orchestration Engine -credentials, TLS certificates, etc. Most of the credentials are expected to be -provided by the user, some are generated by Nuvla (e.g. API key). - ---- -_Examples_ - -##### Generate an API key credential - -{% include request_snippet.md file='api/credential-apikey.sh' actions='POST' endpoint='/api/credential' %} - -{% include code_snippet.md file='api/credential-apikey.sh' language='shell' %} - -{% include response_snippet.md file='api/credential-apikey-response.md' %} - - - -##### Docker Swarm token credential - -{% include request_snippet.md file='api/credential-swarmtoken.sh' actions='POST' endpoint='/api/credential' %} - -{% include code_snippet.md file='api/credential-swarmtoken.sh' language='shell' %} - -{% include response_snippet.md file='api/credential-swarmtoken-response.md' %} - - -##### Infrastructure Service S3 credential - -{% include request_snippet.md file='api/credential-s3.sh' actions='POST' endpoint='/api/credential' %} - -{% include code_snippet.md file='api/credential-s3.sh' language='shell' %} - -{% include response_snippet.md file='api/credential-s3-response.md' %} - - -##### Infrastructure Service Docker Swarm HTTP API credential - -{% include request_snippet.md file='api/credential-swarm.sh' actions='POST' endpoint='/api/credential' %} - -{% include code_snippet.md file='api/credential-swarm.sh' language='shell' %} - -{% include response_snippet.md file='api/credential-swarm-response.md' %} - - -##### Infrastructure Service Kubernetes HTTP API credential - -{% include request_snippet.md file='api/credential-kubernetes.sh' actions='POST' endpoint='/api/credential' %} - -{% include code_snippet.md file='api/credential-kubernetes.sh' language='shell' %} - -{% include response_snippet.md file='api/credential-kubernetes-response.md' %} - - -### deployment - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/deployment/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The `deployment` resource allows you to deploy an instance of a `module`. - ---- -_Examples_ - -##### Start/Stop an application - -{% include request_snippet.md file='api/deployment.sh' actions='POST PUT GET' endpoint='/api/deployment' %} - -{% include code_snippet.md file='api/deployment.sh' language='shell' %} - -{% include response_snippet.md file='api/deployment-response.md' %} - - - - -### evidence-record - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/evidence-record/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The `evidence-record` resource allows you to create and manage audit evidence records that can afterwards help you keep track of your infrastructures' compliance to certain standards and certification schemas. - ---- -_Examples_ - -##### Create an evidence record - -{% include request_snippet.md file='api/evidence-record.sh' actions='POST' endpoint='/api/evidencerecord' %} - -{% include code_snippet.md file='api/evidencerecord.sh' language='shell' %} - -{% include response_snippet.md file='api/evidencerecord-response.md' %} - - - - -### infrastructure-service - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/infrastructure-service/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The `infrastructure-service` resource represents any manageable service with a working endpoint. This resource is templated, which means, like `session` and `credential`, you can also create infrastructure-services of different types. - ---- -_Examples_ - - -##### Create Docker Swarm infrastructure service - -{% include request_snippet.md file='api/infrastructure-service.sh' actions='POST' endpoint='/api/infrastructure-service-swarm' %} - -{% include code_snippet.md file='api/infrastructure-service-swarm.sh' language='shell' %} - -{% include response_snippet.md file='api/infrastructure-service-swarm-response.md' %} - - -##### Create Kubernetes infrastructure service - -{% include request_snippet.md file='api/infrastructure-service-k8s.sh' actions='POST' endpoint='/api/infrastructure-service' %} - -{% include code_snippet.md file='api/infrastructure-service-k8s.sh' language='shell' %} - -{% include response_snippet.md file='api/infrastructure-service-k8s-response.md' %} - - -##### Create S3 infrastructure service - -{% include request_snippet.md file='api/infrastructure-service-s3.sh' actions='POST' endpoint='/api/infrastructure-service' %} - -{% include code_snippet.md file='api/infrastructure-service-s3.sh' language='shell' %} - -{% include response_snippet.md file='api/infrastructure-service-s3-response.md' %} - - -##### Create generic infrastructure service - -{% include request_snippet.md file='api/infrastructure-service.sh' actions='POST' endpoint='/api/infrastructure-service' %} - -{% include code_snippet.md file='api/infrastructure-service.sh' language='shell' %} - -{% include response_snippet.md file='api/infrastructure-service-response.md' %} - - -### infrastructure-service-group - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET DELETE' endpoint='/api/infrastructure-service-group/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The `infrastructure-service-group` resource is a logical container for your infrastructure-service and respective credential and data resources. - - ---- -_Examples_ - - -##### Create an infrastructure-service-group - -{% include request_snippet.md file='api/infrastructure-service-group.sh' actions='POST' endpoint='/api/infrastructure-service-group' %} - -{% include code_snippet.md file='api/infrastructure-service-group.sh' language='shell' %} - -{% include response_snippet.md file='api/infrastructure-service-group-response.md' %} - - - - -### session - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET DELETE' endpoint='/api/session/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The `session` resource allows you to use your credentials for authenticating with Nuvla. - -**NOTE:** for later usage, we store the authenticated session in a file called _cookies_ - ---- -_Examples_ - - -##### Login with username and password - -{% include request_snippet.md file='api/session.sh' actions='POST' endpoint='/api/session' %} - -{% include code_snippet.md file='api/login.sh' language='shell' %} - -{% include response_snippet.md file='api/login-response.md' %} - - -##### Login with API keys - -{% include request_snippet.md file='api/session.sh' actions='POST' endpoint='/api/session' %} - -{% include code_snippet.md file='api/login_apikey.sh' language='shell' %} - -{% include response_snippet.md file='api/login-response.md' %} - -### user - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/user/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The `user` resource allows you to create a new user account on Nuvla. - ---- -_Examples_ - - -##### Create a user with an email and a password - -{% include request_snippet.md file='api/user_email_password.sh' actions='POST' endpoint='/api/user' %} - -{% include code_snippet.md file='api/user_email_password.sh' language='shell' %} - -{% include response_snippet.md file='api/user-email-password-response.md' %} - -Password must contain at least one uppercase character, one lowercase character, -one digit, one special character, and at least 8 characters in total. - -The creation of a user with `email-password` template does not require a session. - -The user will receive an email with a callback that he have to follow to activate his account. -After following the link, the state attribute of user document will transit from NEW to ACTIVE. - - -### voucher - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/voucher/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The `voucher` resource let's you create and manage digital vouchers, associated with any digital service provider, for better tracking and accounting of voucher consumption. - - ---- -_Examples_ - - -##### Create a new voucher - -{% include request_snippet.md file='api/voucher.sh' actions='POST' endpoint='/api/voucher' %} - -{% include code_snippet.md file='api/voucher.sh' language='shell' %} - -{% include response_snippet.md file='api/voucher-response.md' %} - - -# Python API - -(coming soon...) diff --git a/docs/nuvla/user-guide/api/credential.md b/docs/nuvla/user-guide/api/credential.md new file mode 100644 index 0000000..c9fc7b6 --- /dev/null +++ b/docs/nuvla/user-guide/api/credential.md @@ -0,0 +1,99 @@ +--- +layout: page +title: Credential +nav_order: 3 +parent: API +has_children: false +--- + +# credential + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/credential/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `credential` resource is used to save all the credentials necessary to +manage your Nuvla resources. From API keys, to Container Orchestration Engine +credentials, TLS certificates, etc. Most of the credentials are expected to be +provided by the user, some are generated by Nuvla (e.g. API key). + +--- +_Examples_ + +## Generate an API key credential + +{% include request_snippet.md file='api/credential-apikey.sh' actions='POST' endpoint='/api/credential' %} + +{% include code_snippet.md file='api/credential-apikey.sh' language='shell' %} + +{% include response_snippet.md file='api/credential-apikey-response.md' %} + + + +## Docker Swarm token credential + +{% include request_snippet.md file='api/credential-swarmtoken.sh' actions='POST' endpoint='/api/credential' %} + +{% include code_snippet.md file='api/credential-swarmtoken.sh' language='shell' %} + +{% include response_snippet.md file='api/credential-swarmtoken-response.md' %} + + + +## Infrastructure Service S3 credential + +{% include request_snippet.md file='api/credential-s3.sh' actions='POST' endpoint='/api/credential' %} + +{% include code_snippet.md file='api/credential-s3.sh' language='shell' %} + +{% include response_snippet.md file='api/credential-s3-response.md' %} + + +## Infrastructure Service Docker Swarm HTTP API credential + +{% include request_snippet.md file='api/credential-swarm.sh' actions='POST' endpoint='/api/credential' %} + +{% include code_snippet.md file='api/credential-swarm.sh' language='shell' %} + +{% include response_snippet.md file='api/credential-swarm-response.md' %} + + +## Infrastructure Service Kubernetes HTTP API credential + +{% include request_snippet.md file='api/credential-kubernetes.sh' actions='POST' endpoint='/api/credential' %} + +{% include code_snippet.md file='api/credential-kubernetes.sh' language='shell' %} + +{% include response_snippet.md file='api/credential-kubernetes-response.md' %} diff --git a/docs/nuvla/user-guide/api/deployment.md b/docs/nuvla/user-guide/api/deployment.md new file mode 100644 index 0000000..4fc713b --- /dev/null +++ b/docs/nuvla/user-guide/api/deployment.md @@ -0,0 +1,24 @@ +--- +layout: page +title: Deployment +nav_order: 6 +parent: API +has_children: false +--- + +# deployment + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/deployment/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `deployment` resource allows you to deploy an instance of a `module`. + +--- +_Examples_ + +## Start/Stop an application + +{% include request_snippet.md file='api/deployment.sh' actions='POST PUT GET' endpoint='/api/deployment' %} + +{% include code_snippet.md file='api/deployment.sh' language='shell' %} + +{% include response_snippet.md file='api/deployment-response.md' %} diff --git a/docs/nuvla/user-guide/api/index.md b/docs/nuvla/user-guide/api/index.md new file mode 100644 index 0000000..575989a --- /dev/null +++ b/docs/nuvla/user-guide/api/index.md @@ -0,0 +1,15 @@ +--- +layout: page +title: API +parent: User Guide +nav_order: 1 +has_children: true +permalink: /nuvla/api +--- + +# REST API + +Nuvla provides a uniform and extensible HTTP-based RESTful API, for the management of Nuvla resources. A Nuvla resource can be anything you can perform an action on, through Nuvla, like your own user profile, a Nuvla application, credentials, etc. + +Users have at their disposal all the usual CRUD (Create, Read, Update, Delete) operations, plus Searching, Querying, Bulk delete and Bulk actions. + diff --git a/docs/nuvla/user-guide/api/infrastructure-service-group.md b/docs/nuvla/user-guide/api/infrastructure-service-group.md new file mode 100644 index 0000000..b6b62f6 --- /dev/null +++ b/docs/nuvla/user-guide/api/infrastructure-service-group.md @@ -0,0 +1,28 @@ +--- +layout: page +title: Infrastructure Service Group +nav_order: 5 +parent: API +has_children: false +--- + +# infrastructure-service-group + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET DELETE' endpoint='/api/infrastructure-service-group/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `infrastructure-service-group` resource is a logical container for your infrastructure-service and respective credential and data resources. + + +--- +_Examples_ + + +## Create an infrastructure-service-group + +{% include request_snippet.md file='api/infrastructure-service-group.sh' actions='POST' endpoint='/api/infrastructure-service-group' %} + +{% include code_snippet.md file='api/infrastructure-service-group.sh' language='shell' %} + +{% include response_snippet.md file='api/infrastructure-service-group-response.md' %} + + diff --git a/docs/nuvla/user-guide/api/infrastructure-service.md b/docs/nuvla/user-guide/api/infrastructure-service.md new file mode 100644 index 0000000..a1aeba5 --- /dev/null +++ b/docs/nuvla/user-guide/api/infrastructure-service.md @@ -0,0 +1,74 @@ +--- +layout: page +title: Infrastructure Service +nav_order: 4 +parent: API +has_children: false +--- + +# infrastructure-service + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/infrastructure-service/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `infrastructure-service` resource represents any manageable service with a working endpoint. This resource is templated, which means, like `session` and `credential`, you can also create infrastructure-services of different types. + +--- +_Examples_ + + +## Create Docker Swarm infrastructure service + +{% include request_snippet.md file='api/infrastructure-service.sh' actions='POST' endpoint='/api/infrastructure-service-swarm' %} + +{% include code_snippet.md file='api/infrastructure-service-swarm.sh' language='shell' %} + +{% include response_snippet.md file='api/infrastructure-service-swarm-response.md' %} + + +## Create Kubernetes infrastructure service + +{% include request_snippet.md file='api/infrastructure-service-k8s.sh' actions='POST' endpoint='/api/infrastructure-service' %} + +{% include code_snippet.md file='api/infrastructure-service-k8s.sh' language='shell' %} + +{% include response_snippet.md file='api/infrastructure-service-k8s-response.md' %} + + +## Create S3 infrastructure service + +{% include request_snippet.md file='api/infrastructure-service-s3.sh' actions='POST' endpoint='/api/infrastructure-service' %} + +{% include code_snippet.md file='api/infrastructure-service-s3.sh' language='shell' %} + +{% include response_snippet.md file='api/infrastructure-service-s3-response.md' %} + + +## Create generic infrastructure service + +{% include request_snippet.md file='api/infrastructure-service.sh' actions='POST' endpoint='/api/infrastructure-service' %} + +{% include code_snippet.md file='api/infrastructure-service.sh' language='shell' %} + +{% include response_snippet.md file='api/infrastructure-service-response.md' %} + + +# infrastructure-service-group + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET DELETE' endpoint='/api/infrastructure-service-group/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `infrastructure-service-group` resource is a logical container for your infrastructure-service and respective credential and data resources. + + +--- +_Examples_ + + +## Create an infrastructure-service-group + +{% include request_snippet.md file='api/infrastructure-service-group.sh' actions='POST' endpoint='/api/infrastructure-service-group' %} + +{% include code_snippet.md file='api/infrastructure-service-group.sh' language='shell' %} + +{% include response_snippet.md file='api/infrastructure-service-group-response.md' %} + + diff --git a/docs/nuvla/user-guide/api/principle.md b/docs/nuvla/user-guide/api/principle.md new file mode 100644 index 0000000..ce5b994 --- /dev/null +++ b/docs/nuvla/user-guide/api/principle.md @@ -0,0 +1,216 @@ +--- +layout: page +title: Principle +nav_order: 1 +parent: API +has_children: false +--- + +# API Syntax + + +| Action | HTTP Method | Target | +| --- | --- | --- | +| Search | GET or PUT | resource collection | +| Add (create) | POST | resource collection | +| Bulk_delete | DELETE | resource collection | +| Bulk_action | PATCH | resource collection | +| Read | GET | resource | +| Edit (update) | PUT | resource | +| Delete | DELETE | resource | + +The Nuvla REST API endpoints are constructed with the following pattern: + +`/api////` + +where + + - `` is the Kebab Case name of the resource collection you're accessing, + - `` is the unique identifier for the specific resource you're managing, + - `` is a custom additional operation that might be allowed for that resource. + +On top of that, Nuvla's REST API also offers searching and querying through a parameter-based set of keywords: + +`/api/?param=value¶m=value...` + +where + +| Parameter | Description | Examples | +| --- | --- | --- | +| `filter` | Used to return only the set of resources that have an `attribute` matching a certain `value` | `?filter=name="my-resource"`

    `?filter=people/gender!="male" and people/age>=21`

    `?filter=application-name^="my-app-"` | +| `orderby` | To order the returned resources by the specified attribute | `?orderby=created:desc`

    `?orderby=people/surname:asc` | +| `aggregation` | On top of the requested resources, it will also return on-the-fly aggregations based on the specified function. Available functions: `avg`, `max`, `min`, `sum`, `cardinality`, `terms`, `stats`, `extendedstats`, `percentiles`, `value_count`, `missing` | `?aggregation=avg:people/age` | +| `last` and `first` | Returns a range of resources by setting the first and last (1-based) query parameters | `?first=10&last=20` | +| `select` | Selects only certain attributes to be returned by the server. Avoiding sending information that will not be useful reduces the load on the network and the server | `?select=people/id` | + +Nuvla's API also provide custom operations for certain resources. These will be covered individually in the subsections below. + +Here are a few examples on how to construct the different HTTP requests: + + - **GET** all the resources of a specific type: + + `GET /api/` + + - **GET** a specific resource: + + `GET /api//` + + - **CREATE** a new resource: + + ``` + POST /api/ + HEADERS content-type:application/json + DATA + ``` + + - **EDIT** an existing resource: + + ``` + PUT /api// + HEADERS content-type:application/json + DATA + ``` + + - **DELETE** a resource: + + `DELETE /api//` + + - **SEARCH** on resources: + + `GET /api/?param=value¶m=value` + + *or* + + ``` + PUT /api/ + HEADERS content-type:application/x-www-form-urlencoded + DATA
    + ``` + + - **BULK_DELETE** of resources: + + `DELETE /api/?param=value¶m=value` + + *or* + + ``` + DELETE /api/ + HEADERS content-type:application/x-www-form-urlencoded, bulk:true + DATA + ``` + + + - **BULK_ACTION** of resources: + + `PATCH /api//?param=value¶m=value` + + *or* + + ``` + PATCH /api/ + HEADERS content-type:application/x-www-form-urlencoded, bulk:true + DATA + ``` + + +## Resources + +All the Nuvla API calls to retrieve resources will return a JSON output, and you'll notice that all of these outputs contain a set of common attributes: + + - _**id**_: unique resource identifier, defined by the API server + - _**acl**_: fine-grained access-control list, used for managing authorization process for each resource and its collections of resources. If not defined by the user, the API server will default it based on the requesting user credentials. + - _**created**_: timestamp of creation, defined by the API server + - _**created-by**_: user id who created the resource (useful to trace user action when he has switched to a group) + - _**updated**_: timestamp of the last update, defined by the API server + - _**updated-by**_: user id who updated the resource (useful to trace user action when he has switched to a group) + - _**resource-type**_: type of resource, defined by the API server + - _**parent**_: reference to parent resource + - _**operations**_: set of available operations for that resource, defined by the API server + - _**name**_: optional user-friendly name for a specific resource, defined by the user or defaulted to `None` if undefined + - _**description**_: optional verbose description for a specific resource, defined by the user or defaulted to `None` if undefined + +Resources are managed individually, which means that the data schemas and available operations might defer from one to the other. These options are all explained and exemplified in the following sections. + + + +## Filter syntax + +Filter parameter is used to search, to run bulk delete and to run bulk operations on existing resources. + +It could be a simple query e.g. + +- `name='hello'` + +- `acl/delete = 'group/demo'` + +- `created<'2021-11-24T19:59:18Z'` + +- `version < 2` + +- `location intersects 'POINT(13.86 60.84)'` + +- `online!=true` + +- `description=null` + +- `tags='eo'` + +- `fulltext == 'Demo*'` + +or a complex one with parenthesis and combination of logical [`or`, `and`] expression. + +- `(created<'2021-11-24T19:59:18Z' or name^='hello') and location intersects 'POINT(13.86 60.84)'` + +### Supported Values in filter + +| Name | Description | Example | +|---|---| +| Text | Single or double quoted text | `"foobar"` `'foobar'` | +| Date | Single or double quoted UTC timestamp or `now` expression | `'2021-11-24T19:59:18Z'` `'now<30m'` `'now>30d'` | +| Numeric | Integer or Float numbers | `3.14159` `3`| +| Boolean | | `true` `false` | +| Geo-point | Single or double quoted [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) string | `'POLYGON((-49.2 19.6,65.7 19.6,65.7 67.4,-49.2 67.4,-49.2 19.6))'` | +| Geo-shape | Single or double quoted [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) string | `'POLYGON((-49.2 19.6,65.7 19.6,65.7 67.4,-49.2 67.4,-49.2 19.6))'` | +| Null | | `null` | + +Arrays are a special case and searches are executed on their content as if they was a simple value. +E.g. tags field is defined as an array of string. In case we would like to search if tags contains "eo", the filter would be `tags='eo'`. + +### Operations + +| Name | Symbol | Supported values | Details | +|---|---|---|---| +| Equal | = | Numeric, Date, Text, Boolean, null | | +| Not Equal | != | Numeric, Date, Text, Boolean, null | | +| Less than | < | Numeric, Date, Text | | +| Less than or Equal | <= | Numeric, Date, Text | | +| Greater than | > | Numeric, Date, Text | | +| Greater than or Equal | >= | Numeric, Date, Text | | +| Start with | ^= | Text | | +| Full-text search | == | Text | Works only on field `name` , `description` or `fulltext` which is a virtual field that regroup more or less the full resource words. | +| Intersects | intersects | Geo-Point, Geo-shape | Return all documents whose geo_shape or geo_point field intersects the query geometry. | +| Disjoint | disjoint | Geo-shape | Return all documents whose geo_shape or geo_point field has nothing in common with the query geometry. | +| Within | within | Geo-shape | Return all documents whose geo_shape or geo_point field is within the query geometry. Line geometries are not supported. | +| Contains | contains | Geo-shape | Return all documents whose geo_shape or geo_point field contains the query geometry. | + + +## Cloud entry point + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='GET' endpoint='/api/cloud-entry-point' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The primary directory of resources is the Cloud Entry Point (CEP), which contains a list of named resource collections and their URLs (in the href field) relative to the baseURI value. The CEP also contains some other metadata. + +The endpoint is accessible for all registered and anonymous Nuvla users. + +--- + +_Examples_ + +## Get the cloud entry point + +{% include request_snippet.md file='api/cep.sh' actions='GET' endpoint='/api/cloud-entry-point' %} + +{% include code_snippet.md file='api/cep.sh' language='shell' %} + +{% include response_snippet.md file='api/cep-response.md' %} + diff --git a/docs/nuvla/user-guide/api/session.md b/docs/nuvla/user-guide/api/session.md new file mode 100644 index 0000000..21ada23 --- /dev/null +++ b/docs/nuvla/user-guide/api/session.md @@ -0,0 +1,37 @@ +--- +layout: page +title: Session +nav_order: 1 +parent: API +has_children: false +--- + + +# session + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET DELETE' endpoint='/api/session/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `session` resource allows you to use your credentials for authenticating with Nuvla. + +**NOTE:** for later usage, we store the authenticated session in a file called _cookies_ + +--- +_Examples_ + + +## Login with username and password + +{% include request_snippet.md file='api/session.sh' actions='POST' endpoint='/api/session' %} + +{% include code_snippet.md file='api/login.sh' language='shell' %} + +{% include response_snippet.md file='api/login-response.md' %} + + +## Login with API keys + +{% include request_snippet.md file='api/session.sh' actions='POST' endpoint='/api/session' %} + +{% include code_snippet.md file='api/login_apikey.sh' language='shell' %} + +{% include response_snippet.md file='api/login-response.md' %} diff --git a/docs/nuvla/user-guide/api/to-be-deleted.md b/docs/nuvla/user-guide/api/to-be-deleted.md new file mode 100644 index 0000000..8765c41 --- /dev/null +++ b/docs/nuvla/user-guide/api/to-be-deleted.md @@ -0,0 +1,46 @@ +--- +layout: page +title: To Be deleted +nav_order: 100 +parent: API +has_children: false +--- + + +## evidence-record + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/evidence-record/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `evidence-record` resource allows you to create and manage audit evidence records that can afterwards help you keep track of your infrastructures' compliance to certain standards and certification schemas. + +--- +_Examples_ + +### Create an evidence record + +{% include request_snippet.md file='api/evidence-record.sh' actions='POST' endpoint='/api/evidencerecord' %} + +{% include code_snippet.md file='api/evidencerecord.sh' language='shell' %} + +{% include response_snippet.md file='api/evidencerecord-response.md' %} + + + +## voucher + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/voucher/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `voucher` resource let's you create and manage digital vouchers, associated with any digital service provider, for better tracking and accounting of voucher consumption. + + +--- +_Examples_ + + +### Create a new voucher + +{% include request_snippet.md file='api/voucher.sh' actions='POST' endpoint='/api/voucher' %} + +{% include code_snippet.md file='api/voucher.sh' language='shell' %} + +{% include response_snippet.md file='api/voucher-response.md' %} diff --git a/docs/nuvla/user-guide/api/user.md b/docs/nuvla/user-guide/api/user.md new file mode 100644 index 0000000..3998132 --- /dev/null +++ b/docs/nuvla/user-guide/api/user.md @@ -0,0 +1,34 @@ +--- +layout: page +title: User +nav_order: 2 +parent: API +has_children: false +--- + + +# user + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET PUT DELETE' endpoint='/api/user/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `user` resource allows you to create a new user account on Nuvla. + +--- +_Examples_ + + +## Create a user with an email and a password + +{% include request_snippet.md file='api/user_email_password.sh' actions='POST' endpoint='/api/user' %} + +{% include code_snippet.md file='api/user_email_password.sh' language='shell' %} + +{% include response_snippet.md file='api/user-email-password-response.md' %} + +Password must contain at least one uppercase character, one lowercase character, +one digit, one special character, and at least 8 characters in total. + +The creation of a user with `email-password` template does not require a session. + +The user will receive an email with a callback that he have to follow to activate his account. +After following the link, the state attribute of user document will transit from NEW to ACTIVE. diff --git a/docs/nuvla/user-guide.md b/docs/nuvla/user-guide/index.md similarity index 86% rename from docs/nuvla/user-guide.md rename to docs/nuvla/user-guide/index.md index fc0be24..c7c1474 100644 --- a/docs/nuvla/user-guide.md +++ b/docs/nuvla/user-guide/index.md @@ -8,7 +8,7 @@ has_children: true # Nuvla - What is it? -Nuvla is a secured edge-to-cloud (and back) management platform that enables near-data AI for a connected world. +Nuvlaa is a secured edge-to-cloud (and back) management platform that enables near-data AI for a connected world. The container native platform supports all forms of infrastructure: public cloud, private cloud and bare metal infrastructures, as well as edge (with our NuvlaBox). From 80e01438b927b7a4b42f126bb2f9a4ad306a4098 Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Wed, 22 Dec 2021 14:33:43 +0100 Subject: [PATCH 5/6] Add Nuvladocs logo, session api with attributes and operations, minor fixes and refactor --- docs/_config.yml | 2 +- .../api/{login_apikey.sh => login-apikey.sh} | 2 +- .../api/session-get-peers-response.md | 7 ++ .../api/session-switch-group-response.md | 32 +++++++ docs/_includes/api/sessions-response.md | 53 +++++++++++ docs/_includes/api/switch-group.sh | 3 + docs/assets/img/nuvladocs-logo.png | Bin 0 -> 19445 bytes .../advanced-usage/api/cloud-entry-point.md | 29 ++++++ .../api/common-design.md} | 28 +----- .../api/credential.md | 2 +- .../api/deployment.md | 0 .../api/index.md | 3 +- .../api/infrastructure-service-group.md | 0 .../api/infrastructure-service.md | 0 docs/nuvla/advanced-usage/api/session.md | 84 ++++++++++++++++++ .../api/to-be-deleted.md | 0 .../api/user.md | 3 +- .../index.md} | 0 .../installation/advanced-installation.md | 1 - .../installation/example-apps.md | 1 - .../installation/index.md} | 4 +- .../installation/operation-maintenance.md | 1 - .../installation/quickstart.md | 1 - docs/nuvla/advanced-usage/manage-data.md | 2 +- docs/nuvla/{nuvla.md => index.md} | 0 docs/nuvla/user-guide/api/session.md | 37 -------- 26 files changed, 220 insertions(+), 75 deletions(-) rename docs/_includes/api/{login_apikey.sh => login-apikey.sh} (88%) create mode 100644 docs/_includes/api/session-get-peers-response.md create mode 100644 docs/_includes/api/session-switch-group-response.md create mode 100644 docs/_includes/api/sessions-response.md create mode 100644 docs/_includes/api/switch-group.sh create mode 100644 docs/assets/img/nuvladocs-logo.png create mode 100644 docs/nuvla/advanced-usage/api/cloud-entry-point.md rename docs/nuvla/{user-guide/api/principle.md => advanced-usage/api/common-design.md} (90%) rename docs/nuvla/{user-guide => advanced-usage}/api/credential.md (99%) rename docs/nuvla/{user-guide => advanced-usage}/api/deployment.md (100%) rename docs/nuvla/{user-guide => advanced-usage}/api/index.md (92%) rename docs/nuvla/{user-guide => advanced-usage}/api/infrastructure-service-group.md (100%) rename docs/nuvla/{user-guide => advanced-usage}/api/infrastructure-service.md (100%) create mode 100644 docs/nuvla/advanced-usage/api/session.md rename docs/nuvla/{user-guide => advanced-usage}/api/to-be-deleted.md (100%) rename docs/nuvla/{user-guide => advanced-usage}/api/user.md (98%) rename docs/nuvla/{advanced-usage.md => advanced-usage/index.md} (100%) rename docs/nuvla/{ => advanced-usage}/installation/advanced-installation.md (99%) rename docs/nuvla/{ => advanced-usage}/installation/example-apps.md (89%) rename docs/nuvla/{installation.md => advanced-usage/installation/index.md} (95%) rename docs/nuvla/{ => advanced-usage}/installation/operation-maintenance.md (99%) rename docs/nuvla/{ => advanced-usage}/installation/quickstart.md (99%) rename docs/nuvla/{nuvla.md => index.md} (100%) delete mode 100644 docs/nuvla/user-guide/api/session.md diff --git a/docs/_config.yml b/docs/_config.yml index e5f0f7d..c1034ad 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -22,7 +22,7 @@ permalink: pretty exclude: ["vendor/bundle", "node_modules/", "*.gemspec", "*.gem", "Gemfile", "Gemfile.lock", "package.json", "package-lock.json", "script/", "LICENSE.txt", "lib/", "bin/", "README.md", "Rakefile"] # Set a path/url to a logo that will be displayed instead of the title -#logo: "/assets/images/just-the-docs.png" +logo: "/assets/img/nuvladocs-logo.png" # Enable or disable the site search # Supports true (default) or false diff --git a/docs/_includes/api/login_apikey.sh b/docs/_includes/api/login-apikey.sh similarity index 88% rename from docs/_includes/api/login_apikey.sh rename to docs/_includes/api/login-apikey.sh index 4e44317..2fa8981 100644 --- a/docs/_includes/api/login_apikey.sh +++ b/docs/_includes/api/login-apikey.sh @@ -1,4 +1,4 @@ -curl -XPOST https://nuvla.io/api/session -H 'content-type:application/json' -b cookies -d ''' +curl -XPOST https://nuvla.io/api/session -H 'content-type:application/json' -c cookies -d ''' { "template": { "href": "session-template/api-key", diff --git a/docs/_includes/api/session-get-peers-response.md b/docs/_includes/api/session-get-peers-response.md new file mode 100644 index 0000000..275ce21 --- /dev/null +++ b/docs/_includes/api/session-get-peers-response.md @@ -0,0 +1,7 @@ +```json +{ + "user/41d08575-77c2-45fb-9174-9b34bca81dc5" : "titi@other.example.com", + "user/55366c0f-d1d4-4c15-bf04-4dfb35c23ea2" : "tata@exmaple.com", + "user/d5c54236-94a3-49be-8013-128ead0b5836" : "toto@example.com +} +``` \ No newline at end of file diff --git a/docs/_includes/api/session-switch-group-response.md b/docs/_includes/api/session-switch-group-response.md new file mode 100644 index 0000000..d2ddc9e --- /dev/null +++ b/docs/_includes/api/session-switch-group-response.md @@ -0,0 +1,32 @@ +```json +{ + "active-claim" : "user/d5c54236-94a3-49be-8013-128ead0b5836", + "client-ip" : "172.17.0.1", + "expiry" : "2021-12-29T12:44:55.000Z", + "method" : "password", + "updated" : "2021-12-22T12:44:55.150Z", + "roles" : "group/nuvla-anon group/nuvla-user session/51179a6b-f9e2-4ae9-af16-a0955baf78c8 user/d5c54236-94a3-49be-8013-128ead0b5836", + "created" : "2021-12-20T13:52:08.789Z", + "template" : { + "href" : "session-template/password" + }, + "updated-by" : "user/d5c54236-94a3-49be-8013-128ead0b5836", + "created-by" : "group/nuvla-anon", + "id" : "session/51179a6b-f9e2-4ae9-af16-a0955baf78c8", + "resource-type" : "session", + "identifier" : "toto@example.com", + "acl" : { + "edit-data" : [ "group/nuvla-admin" ], + "owners" : [ "session/51179a6b-f9e2-4ae9-af16-a0955baf78c8" ], + "view-acl" : [ "group/nuvla-admin" ], + "delete" : [ "group/nuvla-admin" ], + "view-meta" : [ "group/nuvla-admin" ], + "edit-acl" : [ "group/nuvla-admin" ], + "view-data" : [ "group/nuvla-admin" ], + "manage" : [ "group/nuvla-admin" ], + "edit-meta" : [ "group/nuvla-admin" ] + }, + "groups" : "group/eo", + "user" : "user/d5c54236-94a3-49be-8013-128ead0b5836" +} +``` \ No newline at end of file diff --git a/docs/_includes/api/sessions-response.md b/docs/_includes/api/sessions-response.md new file mode 100644 index 0000000..6a8dc60 --- /dev/null +++ b/docs/_includes/api/sessions-response.md @@ -0,0 +1,53 @@ +```json +{ + "count" : 1, + "acl" : { + "query" : [ "group/nuvla-anon" ], + "add" : [ "group/nuvla-anon" ] + }, + "resource-type" : "session-collection", + "id" : "session", + "resources" : [ { + "client-ip" : "172.17.0.1", + "expiry" : "2021-12-29T12:57:54.000Z", + "method" : "password", + "updated" : "2021-12-22T12:57:55.002Z", + "roles" : "group/nuvla-anon group/nuvla-user user/d5c54236-94a3-49be-8013-128ead0b5836 session/8ed0f0cc-ea54-4e07-9e11-4ba68bb7113b", + "created" : "2021-12-22T12:57:55.002Z", + "template" : { + "href" : "session-template/password" + }, + "created-by" : "group/nuvla-anon", + "id" : "session/8ed0f0cc-ea54-4e07-9e11-4ba68bb7113b", + "resource-type" : "session", + "identifier" : "toto@example.com", + "acl" : { + "edit-data" : [ "group/nuvla-admin" ], + "owners" : [ "session/8ed0f0cc-ea54-4e07-9e11-4ba68bb7113b" ], + "view-acl" : [ "group/nuvla-admin" ], + "delete" : [ "group/nuvla-admin" ], + "view-meta" : [ "group/nuvla-admin" ], + "edit-acl" : [ "group/nuvla-admin" ], + "view-data" : [ "group/nuvla-admin" ], + "manage" : [ "group/nuvla-admin" ], + "edit-meta" : [ "group/nuvla-admin" ] + }, + "operations" : [ { + "rel" : "delete", + "href" : "session/8ed0f0cc-ea54-4e07-9e11-4ba68bb7113b" + }, { + "rel" : "get-peers", + "href" : "session/8ed0f0cc-ea54-4e07-9e11-4ba68bb7113b/get-peers" + }, { + "rel" : "switch-group", + "href" : "session/8ed0f0cc-ea54-4e07-9e11-4ba68bb7113b/switch-group" + } ], + "groups" : "group/eo", + "user" : "user/d5c54236-94a3-49be-8013-128ead0b5836" + } ], + "operations" : [ { + "rel" : "add", + "href" : "session" + } ] +} +``` \ No newline at end of file diff --git a/docs/_includes/api/switch-group.sh b/docs/_includes/api/switch-group.sh new file mode 100644 index 0000000..1fdb24f --- /dev/null +++ b/docs/_includes/api/switch-group.sh @@ -0,0 +1,3 @@ +curl -XPOST https://nuvla.io/api/session/51179a6b-f9e2-4ae9-af16-a0955baf78c8/switch-group -H 'content-type:application/json' -b cookies -c cookies -d ''' + {claim: "group/x"} +''' diff --git a/docs/assets/img/nuvladocs-logo.png b/docs/assets/img/nuvladocs-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..633a58b2f36c896e7688daaeca8d8aeed474285f GIT binary patch literal 19445 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 literal 0 HcmV?d00001 diff --git a/docs/nuvla/advanced-usage/api/cloud-entry-point.md b/docs/nuvla/advanced-usage/api/cloud-entry-point.md new file mode 100644 index 0000000..2aee167 --- /dev/null +++ b/docs/nuvla/advanced-usage/api/cloud-entry-point.md @@ -0,0 +1,29 @@ +--- +layout: page +title: Cloud Entry Point +nav_order: 2 +parent: API +has_children: false +--- + + +# Cloud Entry Point + +{% include request_snippet.md file='api/credential-amazonec2.sh' actions='GET' endpoint='/api/cloud-entry-point' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The primary directory of resources is the Cloud Entry Point (CEP), which contains a list of named resource collections and their URLs (in the href field) relative to the baseURI value. The CEP also contains some other metadata. + +The endpoint is accessible for all registered and anonymous Nuvla users. + +--- + +_Examples_ + +## Get the cloud entry point + +{% include request_snippet.md file='api/cep.sh' actions='GET' endpoint='/api/cloud-entry-point' %} + +{% include code_snippet.md file='api/cep.sh' language='shell' %} + +{% include response_snippet.md file='api/cep-response.md' %} + diff --git a/docs/nuvla/user-guide/api/principle.md b/docs/nuvla/advanced-usage/api/common-design.md similarity index 90% rename from docs/nuvla/user-guide/api/principle.md rename to docs/nuvla/advanced-usage/api/common-design.md index ce5b994..5eb397f 100644 --- a/docs/nuvla/user-guide/api/principle.md +++ b/docs/nuvla/advanced-usage/api/common-design.md @@ -1,12 +1,12 @@ --- layout: page -title: Principle +title: Common Design nav_order: 1 parent: API -has_children: false +has_children: true --- -# API Syntax +# Common Design | Action | HTTP Method | Target | @@ -192,25 +192,3 @@ E.g. tags field is defined as an array of string. In case we would like to searc | Disjoint | disjoint | Geo-shape | Return all documents whose geo_shape or geo_point field has nothing in common with the query geometry. | | Within | within | Geo-shape | Return all documents whose geo_shape or geo_point field is within the query geometry. Line geometries are not supported. | | Contains | contains | Geo-shape | Return all documents whose geo_shape or geo_point field contains the query geometry. | - - -## Cloud entry point - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='GET' endpoint='/api/cloud-entry-point' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The primary directory of resources is the Cloud Entry Point (CEP), which contains a list of named resource collections and their URLs (in the href field) relative to the baseURI value. The CEP also contains some other metadata. - -The endpoint is accessible for all registered and anonymous Nuvla users. - ---- - -_Examples_ - -## Get the cloud entry point - -{% include request_snippet.md file='api/cep.sh' actions='GET' endpoint='/api/cloud-entry-point' %} - -{% include code_snippet.md file='api/cep.sh' language='shell' %} - -{% include response_snippet.md file='api/cep-response.md' %} - diff --git a/docs/nuvla/user-guide/api/credential.md b/docs/nuvla/advanced-usage/api/credential.md similarity index 99% rename from docs/nuvla/user-guide/api/credential.md rename to docs/nuvla/advanced-usage/api/credential.md index c9fc7b6..c693b77 100644 --- a/docs/nuvla/user-guide/api/credential.md +++ b/docs/nuvla/advanced-usage/api/credential.md @@ -1,7 +1,7 @@ --- layout: page title: Credential -nav_order: 3 +nav_order: 4 parent: API has_children: false --- diff --git a/docs/nuvla/user-guide/api/deployment.md b/docs/nuvla/advanced-usage/api/deployment.md similarity index 100% rename from docs/nuvla/user-guide/api/deployment.md rename to docs/nuvla/advanced-usage/api/deployment.md diff --git a/docs/nuvla/user-guide/api/index.md b/docs/nuvla/advanced-usage/api/index.md similarity index 92% rename from docs/nuvla/user-guide/api/index.md rename to docs/nuvla/advanced-usage/api/index.md index 575989a..883b263 100644 --- a/docs/nuvla/user-guide/api/index.md +++ b/docs/nuvla/advanced-usage/api/index.md @@ -1,10 +1,9 @@ --- layout: page title: API -parent: User Guide +parent: Advanced Usage nav_order: 1 has_children: true -permalink: /nuvla/api --- # REST API diff --git a/docs/nuvla/user-guide/api/infrastructure-service-group.md b/docs/nuvla/advanced-usage/api/infrastructure-service-group.md similarity index 100% rename from docs/nuvla/user-guide/api/infrastructure-service-group.md rename to docs/nuvla/advanced-usage/api/infrastructure-service-group.md diff --git a/docs/nuvla/user-guide/api/infrastructure-service.md b/docs/nuvla/advanced-usage/api/infrastructure-service.md similarity index 100% rename from docs/nuvla/user-guide/api/infrastructure-service.md rename to docs/nuvla/advanced-usage/api/infrastructure-service.md diff --git a/docs/nuvla/advanced-usage/api/session.md b/docs/nuvla/advanced-usage/api/session.md new file mode 100644 index 0000000..ca7d792 --- /dev/null +++ b/docs/nuvla/advanced-usage/api/session.md @@ -0,0 +1,84 @@ +--- +layout: page +title: Session +nav_order: 3 +parent: API +has_children: false +--- + + +# Session + +{% include request_snippet.md actions='POST GET DELETE' endpoint='/api/session/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `session` resource allows you to use your credentials for authenticating with Nuvla. +Extra operations allows you to get the claims of a group and to get a list of your peers (users that share some groups with you). + + +## Attributes + + - _**active-claim**_: group or user id that you are claiming + - _**client-ip**_: your client ip as seen from nuvla server + - _**expiry**_: expiry date of your session + - _**method**_: method used to sign-in + - _**roles**_: string space separated of current roles applied to retrieve resources based on ACL + - _**identifier**_: username used to sign-in + - _**groups**_: string space separated groups + +--- + +## Examples + +**NOTE:** for later usage, we store the authenticated session in a file called _cookies_ + + +## Login with username and password + +{% include request_snippet.md file='api/session.sh' actions='POST' endpoint='/api/session' %} + +{% include code_snippet.md file='api/login.sh' language='shell' %} + +{% include response_snippet.md file='api/login-response.md' %} + + +## Login with API keys + +{% include request_snippet.md file='api/session.sh' actions='POST' endpoint='/api/session' %} + +{% include code_snippet.md file='api/login-apikey.sh' language='shell' %} + +{% include response_snippet.md file='api/login-response.md' %} + + +## Search session + +Retrieve of session collection will return always zero or one resource back. A user can only have +one active session at a time. + + +{% include request_snippet.md actions='GET' endpoint='/api/session' %} + +{% include response_snippet.md file='api/sessions-response.md' %} + + +## Switch group operation + +When a user is in a group, he can ask to change his session to claim the group access. + + +{% include request_snippet.md actions='POST' endpoint='/api/session/689df57a-b217-43eb-bf94-85a0ab638e2c/switch-group' %} + +{% include code_snippet.md file='api/switch-group.sh' language='shell' %} + +{% include response_snippet.md file='api/session-switch-group-response.md' %} + + +## Get peers operation + +Get users that share some groups with you. + + +{% include request_snippet.md actions='POST' endpoint='/api/session/689df57a-b217-43eb-bf94-85a0ab638e2c/get-peers' %} + +{% include response_snippet.md file='api/session-get-peers-response.md' %} + diff --git a/docs/nuvla/user-guide/api/to-be-deleted.md b/docs/nuvla/advanced-usage/api/to-be-deleted.md similarity index 100% rename from docs/nuvla/user-guide/api/to-be-deleted.md rename to docs/nuvla/advanced-usage/api/to-be-deleted.md diff --git a/docs/nuvla/user-guide/api/user.md b/docs/nuvla/advanced-usage/api/user.md similarity index 98% rename from docs/nuvla/user-guide/api/user.md rename to docs/nuvla/advanced-usage/api/user.md index 3998132..ce762bb 100644 --- a/docs/nuvla/user-guide/api/user.md +++ b/docs/nuvla/advanced-usage/api/user.md @@ -1,7 +1,7 @@ --- layout: page title: User -nav_order: 2 +nav_order: 4 parent: API has_children: false --- @@ -32,3 +32,4 @@ The creation of a user with `email-password` template does not require a session The user will receive an email with a callback that he have to follow to activate his account. After following the link, the state attribute of user document will transit from NEW to ACTIVE. + diff --git a/docs/nuvla/advanced-usage.md b/docs/nuvla/advanced-usage/index.md similarity index 100% rename from docs/nuvla/advanced-usage.md rename to docs/nuvla/advanced-usage/index.md diff --git a/docs/nuvla/installation/advanced-installation.md b/docs/nuvla/advanced-usage/installation/advanced-installation.md similarity index 99% rename from docs/nuvla/installation/advanced-installation.md rename to docs/nuvla/advanced-usage/installation/advanced-installation.md index 941acce..e43fd46 100644 --- a/docs/nuvla/installation/advanced-installation.md +++ b/docs/nuvla/advanced-usage/installation/advanced-installation.md @@ -4,7 +4,6 @@ title: Production Installation nav_order: 2 parent: Installation permalink: /nuvla/installation/production -grand_parent: Nuvla --- diff --git a/docs/nuvla/installation/example-apps.md b/docs/nuvla/advanced-usage/installation/example-apps.md similarity index 89% rename from docs/nuvla/installation/example-apps.md rename to docs/nuvla/advanced-usage/installation/example-apps.md index 6f7f44f..276cb19 100644 --- a/docs/nuvla/installation/example-apps.md +++ b/docs/nuvla/advanced-usage/installation/example-apps.md @@ -3,7 +3,6 @@ layout: page title: Example Apps nav_order: 3 parent: Installation -grand_parent: Nuvla permalink: /nuvla/installation/example-apps --- diff --git a/docs/nuvla/installation.md b/docs/nuvla/advanced-usage/installation/index.md similarity index 95% rename from docs/nuvla/installation.md rename to docs/nuvla/advanced-usage/installation/index.md index aa941fd..2534fd4 100644 --- a/docs/nuvla/installation.md +++ b/docs/nuvla/advanced-usage/installation/index.md @@ -2,11 +2,11 @@ layout: page title: Installation nav_order: 12 -parent: Nuvla +parent: Advanced Usage has_children: true -permalink: /nuvla/installation --- + The following diagram shows the main blocks of the Nuvla Architecture. ![Nuvla Architecture](/assets/img/architecture.png) diff --git a/docs/nuvla/installation/operation-maintenance.md b/docs/nuvla/advanced-usage/installation/operation-maintenance.md similarity index 99% rename from docs/nuvla/installation/operation-maintenance.md rename to docs/nuvla/advanced-usage/installation/operation-maintenance.md index 07cc089..1e882e9 100644 --- a/docs/nuvla/installation/operation-maintenance.md +++ b/docs/nuvla/advanced-usage/installation/operation-maintenance.md @@ -3,7 +3,6 @@ layout: page title: Operate & Maintain nav_order: 4 parent: Installation -grand_parent: Nuvla permalink: /nuvla/installation/operation-maintenance --- diff --git a/docs/nuvla/installation/quickstart.md b/docs/nuvla/advanced-usage/installation/quickstart.md similarity index 99% rename from docs/nuvla/installation/quickstart.md rename to docs/nuvla/advanced-usage/installation/quickstart.md index 249d9d5..ad935c9 100644 --- a/docs/nuvla/installation/quickstart.md +++ b/docs/nuvla/advanced-usage/installation/quickstart.md @@ -3,7 +3,6 @@ layout: page title: Quickstart nav_order: 1 parent: Installation -grand_parent: Nuvla --- Here's a simple guide to quickly install Nuvla for evaluation purposes. So if you're looking for quickly trying out Nuvla, you're at the right place. However, if you're looking for a robust production level installation, you probably want to look at [the production deployment page](/nuvla/installation/production). diff --git a/docs/nuvla/advanced-usage/manage-data.md b/docs/nuvla/advanced-usage/manage-data.md index 492a3d5..1983757 100644 --- a/docs/nuvla/advanced-usage/manage-data.md +++ b/docs/nuvla/advanced-usage/manage-data.md @@ -3,7 +3,7 @@ layout: page title: Manage Data parent: Advanced Usage grand_parent: Nuvla -nav_order: 1 +nav_order: 4 permalink: /nuvla/advanced-usage/manage-data --- diff --git a/docs/nuvla/nuvla.md b/docs/nuvla/index.md similarity index 100% rename from docs/nuvla/nuvla.md rename to docs/nuvla/index.md diff --git a/docs/nuvla/user-guide/api/session.md b/docs/nuvla/user-guide/api/session.md deleted file mode 100644 index 21ada23..0000000 --- a/docs/nuvla/user-guide/api/session.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -layout: page -title: Session -nav_order: 1 -parent: API -has_children: false ---- - - -# session - -{% include request_snippet.md file='api/credential-amazonec2.sh' actions='POST GET DELETE' endpoint='/api/session/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} - -The `session` resource allows you to use your credentials for authenticating with Nuvla. - -**NOTE:** for later usage, we store the authenticated session in a file called _cookies_ - ---- -_Examples_ - - -## Login with username and password - -{% include request_snippet.md file='api/session.sh' actions='POST' endpoint='/api/session' %} - -{% include code_snippet.md file='api/login.sh' language='shell' %} - -{% include response_snippet.md file='api/login-response.md' %} - - -## Login with API keys - -{% include request_snippet.md file='api/session.sh' actions='POST' endpoint='/api/session' %} - -{% include code_snippet.md file='api/login_apikey.sh' language='shell' %} - -{% include response_snippet.md file='api/login-response.md' %} From 2241b01b6d9a9f902f066088636257ec2ae183be Mon Sep 17 00:00:00 2001 From: khaled basbous Date: Wed, 22 Dec 2021 16:52:31 +0100 Subject: [PATCH 6/6] group api doc --- docs/_includes/api/group-response.md | 7 +++ docs/_includes/api/group.sh | 10 ++++ docs/_includes/api/invite-response.md | 7 +++ docs/_includes/api/invite.sh | 3 ++ docs/_includes/api/logout-response.md | 7 +++ docs/_includes/api/switch-group.sh | 2 +- .../nuvla/advanced-usage/api/common-design.md | 5 +- docs/nuvla/advanced-usage/api/credential.md | 2 +- docs/nuvla/advanced-usage/api/group.md | 52 ++++++++++++++++++ docs/nuvla/advanced-usage/api/session.md | 53 +++++++++++++++++-- 10 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 docs/_includes/api/group-response.md create mode 100644 docs/_includes/api/group.sh create mode 100644 docs/_includes/api/invite-response.md create mode 100644 docs/_includes/api/invite.sh create mode 100644 docs/_includes/api/logout-response.md create mode 100644 docs/nuvla/advanced-usage/api/group.md diff --git a/docs/_includes/api/group-response.md b/docs/_includes/api/group-response.md new file mode 100644 index 0000000..006790d --- /dev/null +++ b/docs/_includes/api/group-response.md @@ -0,0 +1,7 @@ +```json +{ + "status" : 201, + "message" : "group/dev created", + "resource-id" : "group/dev" +} +``` \ No newline at end of file diff --git a/docs/_includes/api/group.sh b/docs/_includes/api/group.sh new file mode 100644 index 0000000..d4839fc --- /dev/null +++ b/docs/_includes/api/group.sh @@ -0,0 +1,10 @@ +curl -XPOST https://nuvla.io/api/group -H 'content-type:application/json' -b cookies -d ''' + { + "template": { + "href": "group-template/generic", + "group-identifier": "dev", + "name": "Dev", + "description": "Development group" + } + } +''' diff --git a/docs/_includes/api/invite-response.md b/docs/_includes/api/invite-response.md new file mode 100644 index 0000000..c7d149c --- /dev/null +++ b/docs/_includes/api/invite-response.md @@ -0,0 +1,7 @@ +```json +{ + "status" : 200, + "message" : "successfully invited to group/dev", + "resource-id" : "group/dev" +} +``` \ No newline at end of file diff --git a/docs/_includes/api/invite.sh b/docs/_includes/api/invite.sh new file mode 100644 index 0000000..4044921 --- /dev/null +++ b/docs/_includes/api/invite.sh @@ -0,0 +1,3 @@ +curl -XPOST https://nuvla.io/api/group/dev/invite -H 'content-type:application/json' -b cookies -d ''' + {"username": "foobar@example.com"} +''' diff --git a/docs/_includes/api/logout-response.md b/docs/_includes/api/logout-response.md new file mode 100644 index 0000000..f38acf5 --- /dev/null +++ b/docs/_includes/api/logout-response.md @@ -0,0 +1,7 @@ +```json +{ + "status" : 200, + "message" : "session/689df57a-b217-43eb-bf94-85a0ab638e2c deleted", + "resource-id" : "session/689df57a-b217-43eb-bf94-85a0ab638e2c" +} +``` \ No newline at end of file diff --git a/docs/_includes/api/switch-group.sh b/docs/_includes/api/switch-group.sh index 1fdb24f..4656ee0 100644 --- a/docs/_includes/api/switch-group.sh +++ b/docs/_includes/api/switch-group.sh @@ -1,3 +1,3 @@ curl -XPOST https://nuvla.io/api/session/51179a6b-f9e2-4ae9-af16-a0955baf78c8/switch-group -H 'content-type:application/json' -b cookies -c cookies -d ''' - {claim: "group/x"} + {"claim": "group/x"} ''' diff --git a/docs/nuvla/advanced-usage/api/common-design.md b/docs/nuvla/advanced-usage/api/common-design.md index 5eb397f..dc69baf 100644 --- a/docs/nuvla/advanced-usage/api/common-design.md +++ b/docs/nuvla/advanced-usage/api/common-design.md @@ -71,11 +71,14 @@ Here are a few examples on how to construct the different HTTP requests: DATA ``` + In case you want to delete existing attributes , add the attributes names in `select` parameter + and do not send these attributes in `DATA` request body. + - **DELETE** a resource: `DELETE /api//` - - **SEARCH** on resources: + - **QUERY** on resources: `GET /api/?param=value¶m=value` diff --git a/docs/nuvla/advanced-usage/api/credential.md b/docs/nuvla/advanced-usage/api/credential.md index c693b77..57fc248 100644 --- a/docs/nuvla/advanced-usage/api/credential.md +++ b/docs/nuvla/advanced-usage/api/credential.md @@ -1,7 +1,7 @@ --- layout: page title: Credential -nav_order: 4 +nav_order: 5 parent: API has_children: false --- diff --git a/docs/nuvla/advanced-usage/api/group.md b/docs/nuvla/advanced-usage/api/group.md new file mode 100644 index 0000000..3067605 --- /dev/null +++ b/docs/nuvla/advanced-usage/api/group.md @@ -0,0 +1,52 @@ +--- +layout: page +title: Group +nav_order: 4 +parent: API +has_children: false +--- + + +# Group + +{% include request_snippet.md actions='POST GET DELETE' endpoint='/api/group/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} + +The `group` resource allows you to: + + - create new groups + - invite users to join a group + +Group is a resource that allow users to have a common account/view on Nuvla on created resources (see `session` switch-group operation) or shared ones (via ACL). + +## Attributes + +**NOTE:** only common attributes for this resource + +--- + +## Examples + +**NOTE:** for later usage, we store the authenticated session in a file called _cookies_ + +Group is a templated resource. To create/add a new group, you have to refer to a +group-template resource. + +{% include request_snippet.md actions='GET' endpoint='/api/group-template' %} + +## Create a group + +{% include request_snippet.md actions='POST' endpoint='/api/group' %} + +{% include code_snippet.md file='api/group.sh' language='shell' %} + +{% include response_snippet.md file='api/group-response.md' %} + +## Invite operation + +You can invite a user to join a group by email doing as follow. + +{% include request_snippet.md actions='POST' endpoint='/api/group/dev/invite' %} + +{% include code_snippet.md file='api/invite.sh' language='shell' %} + +{% include response_snippet.md file='api/invite-response.md' %} diff --git a/docs/nuvla/advanced-usage/api/session.md b/docs/nuvla/advanced-usage/api/session.md index ca7d792..1a378d0 100644 --- a/docs/nuvla/advanced-usage/api/session.md +++ b/docs/nuvla/advanced-usage/api/session.md @@ -11,9 +11,41 @@ has_children: false {% include request_snippet.md actions='POST GET DELETE' endpoint='/api/session/uuid' maincolor='none' prefix='allowed:' lettercolor='black' %} -The `session` resource allows you to use your credentials for authenticating with Nuvla. -Extra operations allows you to get the claims of a group and to get a list of your peers (users that share some groups with you). +The `session` resource allows you to: + - use your credentials for authenticating with Nuvla + - Delete session (logout) + - switch group (act for a group) + - get your peers (users that share some groups with you) + +Users (clients) authenticate with the Nuvla server by referencing a `session-template` resource (to +identify the authentication method), providing values for the associated parameters, and then +creating a `session` resource via the templated 'add' pattern. + +A successful authentication attempt will return a token (as an HTTP cookie) that must be used in +subsequent interactions with the Nuvla server. + +The detailed process consists of the following steps: + +1. Browse the `session-template` resources to find the authentication method + that you want to use. Unless you have a browser-based client, you will + probably want to use either 'password' (username and password) or 'api-key' + (API key and secret). **Use of API keys and secrets is preferred over the + username and password for programmatic access.** + +2. Prepare a 'create' JSON document that references the `session-template` you + have chosen and provides the corresponding parameters (e.g. username and + password for 'password'). + +3. Post the 'create' document to the `session` collection URL. + +4. On a successful authentication request, a token will be returned allowing + access to the Nuvla resources as the authenticated user. **For convenience, + this token is returned as an HTTP cookie.** + +The authentication token (cookie) must be used in all subsequent requests to +the Nuvla server. The token (cookie) has a **limited lifetime** and you +must re-authenticate with the server when the token expires. ## Attributes @@ -31,6 +63,10 @@ Extra operations allows you to get the claims of a group and to get a list of yo **NOTE:** for later usage, we store the authenticated session in a file called _cookies_ +Session is a templated resource. To create/add a new session, you have to refer to a +session-template resource. + +{% include request_snippet.md actions='GET' endpoint='/api/session-template' %} ## Login with username and password @@ -52,8 +88,10 @@ Extra operations allows you to get the claims of a group and to get a list of yo ## Search session -Retrieve of session collection will return always zero or one resource back. A user can only have -one active session at a time. +The search feature of `session` resources will only return the +`session` resource associated with your current session (or none at all if your +are not authenticated). This can be used to determine if you have an active +session and your associated identity and rights (e.g. groups). {% include request_snippet.md actions='GET' endpoint='/api/session' %} @@ -82,3 +120,10 @@ Get users that share some groups with you. {% include response_snippet.md file='api/session-get-peers-response.md' %} + + +## Logout + +{% include request_snippet.md actions='DELETE' endpoint='/api/session/689df57a-b217-43eb-bf94-85a0ab638e2c' %} + +{% include response_snippet.md file='api/logout-response.md' %}