reorganize the platform pages
authorelijah <elijah@riseup.net>
Mon, 1 Dec 2014 07:26:39 +0000 (23:26 -0800)
committerelijah <elijah@riseup.net>
Mon, 1 Dec 2014 07:26:39 +0000 (23:26 -0800)
21 files changed:
docs/platform/details/couchdb.md [moved from docs/platform/couchdb.md with 93% similarity]
docs/platform/details/development.md [moved from docs/platform/development.md with 97% similarity]
docs/platform/details/en.haml [new file with mode: 0644]
docs/platform/details/faq.md [moved from docs/platform/faq.md with 94% similarity]
docs/platform/details/under-the-hood.md [moved from docs/platform/under-the-hood.md with 95% similarity]
docs/platform/details/webapp.md [new file with mode: 0644]
docs/platform/en.md
docs/platform/guide/commands.md [moved from docs/platform/commands.md with 99% similarity]
docs/platform/guide/config.md [moved from docs/platform/config.md with 99% similarity]
docs/platform/guide/en.haml [new file with mode: 0644]
docs/platform/guide/keys-and-certificates.md [moved from docs/platform/guide.md with 58% similarity]
docs/platform/guide/miscellaneous.md [new file with mode: 0644]
docs/platform/guide/nodes.md [new file with mode: 0644]
docs/platform/troubleshooting/en.haml [new file with mode: 0644]
docs/platform/troubleshooting/known-issues.md [moved from docs/platform/known-issues.md with 100% similarity]
docs/platform/troubleshooting/tests.md [moved from docs/platform/tests.md with 82% similarity]
docs/platform/troubleshooting/where-to-look.md [moved from docs/platform/troubleshooting.md with 99% similarity]
docs/platform/tutorials/en.haml [new file with mode: 0644]
docs/platform/tutorials/quick-start.md [moved from docs/platform/quick-start.md with 89% similarity]
docs/platform/tutorials/single-node.md [moved from docs/platform/quick-start-singlenode.md with 98% similarity]
menu.txt

similarity index 93%
rename from docs/platform/couchdb.md
rename to docs/platform/details/couchdb.md
index 8128d57..afecf16 100644 (file)
@@ -1,9 +1,11 @@
+@title = "CouchDB"
+
 Rebalance Cluster
 =================
 
 Bigcouch currently does not have automatic rebalancing.
 It will probably be added after merging into couchdb.
-If you add a node, or remove one node from the cluster, 
+If you add a node, or remove one node from the cluster,
 
 . make sure you have a backup of all DBs !
 
@@ -13,7 +15,7 @@ If you add a node, or remove one node from the cluster,
 . delete all dbs
 . shut down old node
 . check the couchdb members
-    
+
     curl -s —netrc-file /etc/couchdb/couchdb.netrc -X GET http://127.0.0.1:5986/nodes/_all_docs
     curl -s —netrc-file /etc/couchdb/couchdb.netrc http://127.0.0.1:5984/_membership
 
@@ -49,7 +51,7 @@ When a user account gets destroyed from the webapp, there's still a leftover doc
 
 . lookup "id" and "rev" to delete the doc:
 
-    curl -s --netrc-file /etc/couchdb/couchdb.netrc -X DELETE 'http://127.0.0.1:5984/identities/b25cf10f935b58088f0d547fca823265?rev=2-715a9beba597a2ab01851676f12c3e4a' 
+    curl -s --netrc-file /etc/couchdb/couchdb.netrc -X DELETE 'http://127.0.0.1:5984/identities/b25cf10f935b58088f0d547fca823265?rev=2-715a9beba597a2ab01851676f12c3e4a'
 
 
 
similarity index 97%
rename from docs/platform/development.md
rename to docs/platform/details/development.md
index 0f17b19..97f207c 100644 (file)
@@ -1,9 +1,10 @@
 @title = "Development Environment"
+@summary = "Setting up an environment for modifying the leap_platform."
 @toc = true
 
-If you are wanting to make local changes to your provider, or want to contribute some fixes back to LEAP, we recommend that you follow this guide to build up a development environment to test your changes first. Using this method, you can quickly test your changes without deploying them to your production environment, while benefitting from the convenience of reverting to known good states in order to retry things from scratch. 
+If you are wanting to make local changes to your provider, or want to contribute some fixes back to LEAP, we recommend that you follow this guide to build up a development environment to test your changes first. Using this method, you can quickly test your changes without deploying them to your production environment, while benefitting from the convenience of reverting to known good states in order to retry things from scratch.
 
-This page will walk you through setting up nodes using [Vagrant](http://www.vagrantup.com/) for convenient deployment testing, snapshotting known good states, and reverting to previous snapshots. 
+This page will walk you through setting up nodes using [Vagrant](http://www.vagrantup.com/) for convenient deployment testing, snapshotting known good states, and reverting to previous snapshots.
 
 Requirements
 ============
@@ -56,15 +57,15 @@ Install the Vagrant and VirtualBox packages for OS X from their respective Downl
 * https://www.virtualbox.org/wiki/Downloads
 
 
-2. Install 
+2. Install
 
 
 Adding development nodes to your provider
 =========================================
 
-Now you will add local-only Vagrant development nodes to your provider. 
+Now you will add local-only Vagrant development nodes to your provider.
 
-You do not need to setup a different provider instance for development, in fact it is more convenient if you do not, but you can if you wish.  If you do not have a provider already, you will need to create one and configure it before continuing (it is recommended you go through the [Quick Start](quick-start) before continuing down this path). 
+You do not need to setup a different provider instance for development, in fact it is more convenient if you do not, but you can if you wish.  If you do not have a provider already, you will need to create one and configure it before continuing (it is recommended you go through the [Quick Start](quick-start) before continuing down this path).
 
 
 Create local development nodes
@@ -80,7 +81,7 @@ While in your provider directory, create a local node, with the service "webapp"
      = created files/nodes/web1/web1.key
      = created files/nodes/web1/web1.crt
 
-This command creates a node configuration file in `nodes/web1.json` with the webapp service. 
+This command creates a node configuration file in `nodes/web1.json` with the webapp service.
 
 Starting local development nodes
 --------------------------------
@@ -141,7 +142,7 @@ You now can follow the normal LEAP process and initialize it and then deploy you
 Useful local development commands
 =================================
 
-There are many useful things you can do with a virtualized development environment. 
+There are many useful things you can do with a virtualized development environment.
 
 Listing what machines are running
 ---------------------------------
@@ -168,7 +169,7 @@ It is not recommended that you leave your virtual machines running when you are
 Connecting to machines
 ----------------------
 
-You can connect to your local nodes just like you do with normal LEAP nodes, by running 'leap ssh node'. 
+You can connect to your local nodes just like you do with normal LEAP nodes, by running 'leap ssh node'.
 
 However, if you cannot connect to your local node, because the networking is not setup properly, or you have deployed a firewall that locks you out, you may need to access the graphical console.
 
@@ -183,7 +184,7 @@ and then start, or restart, your local Vagrant node. You should get a VirtualBox
 Snapshotting machines
 ---------------------
 
-A very useful feature of local Vagrant development nodes is the ability to snapshot the current state and then revert to that when you need. 
+A very useful feature of local Vagrant development nodes is the ability to snapshot the current state and then revert to that when you need.
 
 For example, perhaps the base image is a little bit out of date and you want to get the packages updated to the latest before continuing. You can do that simply by starting the node, connecting to it and updating the packages and then snapshotting the node:
 
@@ -220,7 +221,7 @@ Troubleshooting Vagrant
 To troubleshoot vagrant issues, try going through these steps:
 
 * Try plain vagrant using the [Getting started guide](http://docs.vagrantup.com/v2/getting-started/index.html).
-* If that fails, make sure that you can run virtual machines (VMs) in plain virtualbox (Virtualbox GUI or VBoxHeadless). 
+* If that fails, make sure that you can run virtual machines (VMs) in plain virtualbox (Virtualbox GUI or VBoxHeadless).
   We don't suggest a sepecial howto for that, [this one](http://www.thegeekstuff.com/2012/02/virtualbox-install-create-vm/) seems pretty decent, or you follow the [Oracale Virtualbox User Manual](http://www.virtualbox.org/manual/UserManual.html). There's also specific documentation for [Debian](https://wiki.debian.org/VirtualBox) and for [Ubuntu](https://help.ubuntu.com/community/VirtualBox). If you succeeded, try again if you now can start vagrant nodes using plain vagrant (see first step).
 * If plain vagrant works for you, you're very close to using vagrant with leap ! If you encounter any problems now, please [contact us](https://leap.se/en/about-us/contact) or use our [issue tracker](https://leap.se/code)
 
@@ -295,7 +296,7 @@ Then:
 
 If everything works, you should export libvirt as the VAGRANT_DEFAULT_PROVIDER:
 
-    export VAGRANT_DEFAULT_PROVIDER="libvirt" 
+    export VAGRANT_DEFAULT_PROVIDER="libvirt"
 
 Now you should be able to use the `leap local` commands.
 
diff --git a/docs/platform/details/en.haml b/docs/platform/details/en.haml
new file mode 100644 (file)
index 0000000..2f59f3f
--- /dev/null
@@ -0,0 +1,5 @@
+- @title = "Details"
+
+%h1.first Platform Details
+
+= child_summaries
\ No newline at end of file
similarity index 94%
rename from docs/platform/faq.md
rename to docs/platform/details/faq.md
index f808512..57afb6c 100644 (file)
@@ -1,5 +1,6 @@
 @title = 'Frequently asked questions'
 @nav_title = 'FAQ'
+@summary = "Frequently Asked Questions"
 @toc = true
 
 APT
@@ -31,9 +32,9 @@ Log into your server and issue:
 How can i customize the leap_platform puppet manifests ?
 --------------------------------------------------------
 
-You can create custom puppet modules under `files/puppet`. 
-The custom puppet entry point is in class 'custom' which can be put into 
-`files/puppet/modules/custom/manifests/init.pp`. This class gets automatically included 
+You can create custom puppet modules under `files/puppet`.
+The custom puppet entry point is in class 'custom' which can be put into
+`files/puppet/modules/custom/manifests/init.pp`. This class gets automatically included
 by site_config::default, which is applied to all nodes.
 
 Of cause you can also create a different git branch and change whatever you want, if you are
similarity index 95%
rename from docs/platform/under-the-hood.md
rename to docs/platform/details/under-the-hood.md
index 2c9a9b7..dcbddb3 100644 (file)
@@ -1,4 +1,5 @@
 @title = "Under the hood"
+@summary = "Various implementation details."
 
 This page contains various details on the how the platform is implemented. You can safely ignore this page, although it may be useful if you plan to make modifications to the platform.
 
diff --git a/docs/platform/details/webapp.md b/docs/platform/details/webapp.md
new file mode 100644 (file)
index 0000000..2b078af
--- /dev/null
@@ -0,0 +1,282 @@
+@title = 'LEAP Web'
+@summary = 'The web component of the LEAP Platform, providing user management, support desk, documentation and more.'
+@toc = true
+
+Introduction
+===================
+
+"LEAP Web" is the webapp component of the LEAP Platform, providing the following services:
+
+* REST API for user registration.
+* Admin interface to manage users.
+* Client certificate distribution and renewal.
+* User support help tickets.
+* Billing
+* Customizable and Localized user documentation
+
+This web application is written in Ruby on Rails 3, using CouchDB as the backend data store.
+
+It is licensed under the GNU Affero General Public License (version 3.0 or higher). See http://www.gnu.org/licenses/agpl-3.0.html for more information.
+
+Known problems
+====================
+
+* Client certificates are generated without a CSR. The problem is that this makes the web
+  application extremely vulnerable to denial of service attacks. This was not an issue until we
+  started to allow the possibility of anonymously fetching a client certificate without
+  authenticating first.
+
+* By its very nature, the user database is vulnerable to enumeration attacks. These are
+  very hard to prevent, because our protocol is designed to allow query of a user database via
+  proxy in order to provide network perspective.
+
+Integration
+===========
+
+LEAP web is part of the leap platform. Most of the time it will be customized and deployed in that context. This section describes the integration of LEAP web in the wider framework. The Development section focusses on development of LEAP web itself.
+
+Configuration & Customization
+------------------------------
+
+The customization of the webapp for a leap provider happens via two means:
+ * configuration settings in services/webapp.json
+ * custom files in files/webapp
+
+### Configuration Settings
+
+The webapp ships with a fairly large set of default settings for all environments. They are stored in config/defaults.yml. During deploy the platform creates config/config.yml from the settings in services/webapp.json. These settings will overwrite the defaults.
+
+### Custom Files
+
+Any file placed in files/webapp in the providers repository will overwrite the content of config/customization in the webapp. These files will override files of the same name.
+
+This mechanism allows customizing basically all aspects of the webapp.
+See files/webapp/README.md in the providers repository for more.
+
+### Provider Information ###
+
+The leap client fetches provider information via json files from the server. The platform prepares that information and stores it in the webapp in public/1/config/*.json. (1 being the current API version).
+
+Provider Documentation
+-------------
+
+LEAP web already comes with a bit of user documentation. It mostly resides in app/views/pages and thus can be overwritten by adding files to files/webapp/views/pages in the provider repository. You probably want to add your own Terms of Services and Privacy Policy here.
+The webapp will render haml, erb and markdown templates and pick translated content from localized files such as privacy_policy.es.md. In order to add or remove languages you have to modify the available_locales setting in the config. (See Configuration Settings above)
+
+Development
+===========
+
+Installation
+---------------------------
+
+Typically, this application is installed automatically as part of the LEAP Platform. To install it manually for testing or development, follow these instructions:
+
+### TL;DR ###
+
+Install git, ruby 1.9, rubygems and couchdb on your system. Then run
+
+    gem install bundler
+    git clone https://leap.se/git/leap_web
+    cd leap_web
+    git submodule update --init
+    bundle install --binstubs
+    bin/rails server
+
+### Install system requirements
+
+First of all you need to install ruby, git and couchdb. On debian based systems this would be achieved by something like
+
+    sudo apt-get install git ruby1.9.3 rubygems couchdb
+
+We install most gems we depend upon through [bundler](http://gembundler.com). So first install bundler
+
+    sudo gem install bundler
+
+On Debian Wheezy or later, there is a Debian package for bundler, so you can alternately run ``sudo apt-get install bundler``.
+
+### Download source
+
+Simply clone the git repository:
+
+    git clone git://leap.se/leap_web
+    cd leap_web
+
+### SRP Submodule
+
+We currently use a git submodule to include srp-js. This will soon be replaced by a ruby gem. but for now you need to run
+
+  git submodule update --init
+
+### Install required ruby libraries
+
+    cd leap_web
+    bundle
+
+Typically, you run ``bundle`` as a normal user and it will ask you for a sudo password when it is time to install the required gems. If you don't have sudo, run ``bundle`` as root.
+
+Configuration
+----------------------------
+
+The configuration file `config/defaults.yml` providers good defaults for most
+values. You can override these defaults by creating a file `config/config.yml`.
+
+There are a few values you should make sure to modify:
+
+    production:
+      admins: ["myusername","otherusername"]
+      domain: example.net
+      force_ssl: true
+      secret_token: "4be2f60fafaf615bd4a13b96bfccf2c2c905898dad34..."
+      client_ca_key: "/etc/ssl/ca.key"
+      client_ca_cert: "/etc/ssl/ca.crt"
+      ca_key_password: nil
+
+* `admins` is an array of usernames that are granted special admin privilege.
+* `domain` is your fully qualified domain name.
+* `force_ssl`, if set to true, will require secure cookies and turn on HSTS. Don't do this if you are using a self-signed server certificate.
+* `secret_token`, used for cookie security, you can create one with `rake secret`. Should be at least 30 characters.
+* `client_ca_key`, the private key of the CA used to generate client certificates.
+* `client_ca_cert`, the public certificate the CA used to generate client certificates.
+* `ca_key_password`, used to unlock the client_ca_key, if needed.
+
+### Provider Settings
+
+The leap client fetches provider information via json files from the server. 
+If you want to use that functionality please add your provider files the public/1/config directory. (1 being the current API version).
+
+Running
+-----------------------------
+
+    cd leap_web
+    bin/rails server
+
+You will find Leap Web running on `localhost:3000`
+
+Testing
+--------------------------------
+
+To run all tests
+
+    rake test
+
+To run an individual test:
+
+    rake test TEST=certs/test/unit/client_certificate_test.rb
+    or
+    ruby -Itest certs/test/unit/client_certificate_test.rb
+
+Engines
+---------------------
+
+Leap Web includes some Engines. All things in `app` will overwrite the engine behaviour. You can clone the leap web repository and add your customizations to the `app` directory. Including leap_web as a gem is currently not supported. It should not require too much work though and we would be happy to include the changes required.
+
+If you have no use for one of the engines you can remove it from the Gemfile. Engines should really be plugins - no other engines should depend upon them. If you need functionality in different engines it should probably go into the toplevel.
+
+# Deployment #
+
+We strongly recommend using the LEAP platform for deploy. Most of the things documented here are automated as part of the platform. If you want to research how the platform deploys or work on your own mechanism this section is for you.
+
+These instructions are targeting a Debian GNU/Linux system. You might need to change the commands to match your own needs.
+
+## Server Preperation ##
+
+### Dependencies ##
+
+The following packages need to be installed:
+
+* git
+* ruby1.9
+* rubygems1.9
+* couchdb (if you want to use a local couch)
+
+### Setup Capistrano ###
+
+We use puppet to deploy. But we also ship an untested config/deploy.rb.example. Edit it to match your needs if you want to use capistrano.
+
+run `cap deploy:setup` to create the directory structure.
+
+run `cap deploy` to deploy to the server.
+
+## Customized Files ##
+
+Please make sure your deploy includes the following files:
+
+* public/1/config/*.json (see Provider Settings section)
+* config/couchdb.yml
+
+## Couch Security ##
+
+We recommend against using an admin user for running the webapp. To avoid this couch design documents need to be created ahead of time and the auto update mechanism needs to be disabled.
+Take a look at test/setup_couch.sh for an example of securing the couch.
+
+## Design Documents ##
+
+After securing the couch design documents need to be deployed with admin permissions. There are two ways of doing this:
+ * rake couchrest:migrate_with_proxies
+ * dump the documents as files with `rake couchrest:dump` and deploy them
+   to the couch by hand or with the platform.
+
+### CouchRest::Migrate ###
+
+The before_script block in .travis.yml illustrates how to do this:
+
+    mv test/config/couchdb.yml.admin config/couchdb.yml  # use admin privileges
+    bundle exec rake couchrest:migrate_with_proxies      # run the migrations
+    bundle exec rake couchrest:migrate_with_proxies      # looks like this needs to run twice
+    mv test/config/couchdb.yml.user config/couchdb.yml   # drop admin privileges
+
+### Deploy design docs from CouchRest::Dump ###
+
+First of all we get the design docs as files:
+
+    # put design docs in /tmp/design
+    bundle exec rake couchrest:dump
+
+Then we add them to files/design in the site_couchdb module in leap_platform so they get deployed with the couch. You could also upload them using curl or sth. similar.
+
+# Troubleshooting #
+
+Here are some less common issues you might run into when installing Leap Web.
+
+## Cannot find Bundler ##
+
+### Error Messages ###
+
+`bundle: command not found`
+
+### Solution ###
+
+Make sure bundler is installed. `gem list bundler` should list `bundler`.
+You also need to be able to access the `bundler` executable in your PATH.
+
+## Outdated version of rubygems ##
+
+### Error Messages ###
+
+`bundler requires rubygems >= 1.3.6`
+
+### Solution ###
+
+`gem update --system` will install the latest rubygems
+
+## Missing development tools ##
+
+Some required gems will compile C extensions. They need a bunch of utils for this.
+
+### Error Messages ###
+
+`make: Command not found`
+
+### Solution ###
+
+Install the required tools. For linux the `build-essential` package provides most of them. For Mac OS you probably want the XCode Commandline tools.
+
+## Missing libraries and headers ##
+
+Some gem dependencies might not compile because they lack the needed c libraries.
+
+### Solution ###
+
+Install the libraries in question including their development files.
+
+
index f1a1fc1..d0dcfcc 100644 (file)
@@ -71,7 +71,7 @@ Getting started
 
 We recommend reading the platform documentation in the following order:
 
-1. [Quick start tutorial](platform/quick-start).
+1. [Quick start tutorial](tutorials/quick-start).
 2. [Platform Guide](platform/guide).
 3. [Configuration format](platform/config).
 4. The `leap` [command reference](platform/commands).
similarity index 99%
rename from docs/platform/commands.md
rename to docs/platform/guide/commands.md
index d735fef..0cee709 100644 (file)
@@ -1,4 +1,5 @@
 @title = 'Command Line Reference'
+@summary = "A copy of leap --help"
 
 The command "leap" can be used to manage a bevy of servers running the LEAP platform from the comfort of your own home.
 
similarity index 99%
rename from docs/platform/config.md
rename to docs/platform/guide/config.md
index 3ec2f42..be67e6b 100644 (file)
@@ -1,4 +1,5 @@
 @title = "Configuration Files"
+@summary = "How to edit configuration files."
 
 Files
 -------------------------------------------
diff --git a/docs/platform/guide/en.haml b/docs/platform/guide/en.haml
new file mode 100644 (file)
index 0000000..4c9bd69
--- /dev/null
@@ -0,0 +1,6 @@
+- @nav_title = "Guide"
+- @title = "Platform Guide"
+
+%h1.first Platform Guide
+
+= child_summaries
\ No newline at end of file
similarity index 58%
rename from docs/platform/guide.md
rename to docs/platform/guide/keys-and-certificates.md
index 4b3086e..bd7f349 100644 (file)
@@ -1,153 +1,5 @@
-@title = "LEAP Platform Guide"
-@nav_title = "Guide"
-
-Node types
-================================
-
-Every node has one or more services that determines the node's function within your provider's infrastructure.
-
-When adding a new node to your provider, you should ask yourself four questions:
-
-* **many or few?** Some services benefit from having many nodes, while some services are best run on only one or two nodes.
-* **required or optional?** Some services are required, while others can be left out.
-* **who does the node communicate with?** Some services communicate very heavily with other particular services. Nodes running these services should be close together.
-* **public or private?** Some services communicate with the public internet, while others only need to communicate with other nodes in the infrastructure.
-
-Brief overview of the services:
-
-* **webapp**: The web application. Runs both webapp control panel for users and admins as well as the REST API that the client uses. Needs to communicate heavily with `couchdb` nodes. You need at least one, good to have two for redundancy. The webapp does not get a lot of traffic, so you will not need many.
-* **couchdb**: The database for users and user data. You can get away with just one, but for proper redundancy you should have at least three. Communicates heavily with `webapp`, `mx`, and `soledad` nodes.
-* **soledad**: Handles the data syncing with clients. Typically combined with `couchdb` service, since it communicates heavily with couchdb.
-* **mx**: Incoming and outgoing MX servers. Communicates with the public internet, clients, and `couchdb` nodes.
-* **openvpn**: OpenVPN gateway for clients. You need at least one, but want as many as needed to support the bandwidth your users are doing. The `openvpn` nodes are autonomous and don't need to communicate with any other nodes. Often combined with `tor` service.
-* **monitor**: Internal service to monitor all the other nodes. Currently, you can have zero or one `monitor` nodes.
-* **tor**: Sets up a tor exit node, unconnected to any other service.
-* **dns**: Not yet implemented.
-
-Webapp
------------------------------------
-
-The webapp node is responsible for both the user face web application and the API that the client interacts with.
-
-Some users can be "admins" with special powers to answer tickets and close accounts. To make an account into an administrator, you need to configure the `webapp.admins` property with an array of user names.
-
-For example, to make users `alice` and `bob` into admins, create a file `services/webapp.json` with the following content:
-
-    {
-      "webapp": {
-        "admins": ["bob", "alice"]
-      }
-    }
-
-And then redeploy to all webapp nodes:
-
-    leap deploy webapp
-
-By putting this in `services/webapp.json`, you will ensure that all webapp nodes inherit the value for `webapp.admins`.
-
-Services
-================================
-
-What nodes do you need for a provider that offers particular services?
-
-<table class="table table-striped">
-<tr>
-<th>Node Type</th>
-<th>VPN Service</th>
-<th>Email Service</th>
-</tr>
-<tr>
-<td>webapp</td>
-<td>required</td>
-<td>required</td>
-</tr>
-<tr>
-<td>couchdb</td>
-<td>required</td>
-<td>required</td>
-</tr>
-<tr>
-<td>soledad</td>
-<td>not used</td>
-<td>required</td>
-</tr>
-<tr>
-<td>mx</td>
-<td>not used</td>
-<td>required</td>
-</tr>
-<tr>
-<td>openvpn</td>
-<td>required</td>
-<td>not used</td>
-</tr>
-<tr>
-<td>monitor</td>
-<td>optional</td>
-<td>optional</td>
-</tr>
-<tr>
-<td>tor</td>
-<td>optional</td>
-<td>optional</td>
-</tr>
-<table>
-
-Locations
-================================
-
-All nodes should have a `location.name` specified, and optionally additional information about the location, like the time zone. This location information is used for two things:
-
-* Determine which nodes can, or must, communicate with one another via a local network. The way some virtualization environments work, like OpenStack, requires that nodes communicate via the local network if they are on the same network.
-* Allows the client to prefer connections to nodes that are closer in physical proximity to the user. This is particularly important for OpenVPN nodes.
-
-The location stanza in a node's config file looks like this:
-
-    {
-      "location": {
-        "id": "ankara",
-        "name": "Ankara",
-        "country_code": "TR",
-        "timezone": "+2",
-        "hemisphere": "N"
-      }
-    }
-
-The fields:
-
-* `id`: An internal handle to use for this location. If two nodes have match `location.id`, then they are treated as being on a local network with one another. This value defaults to downcase and underscore of `location.name`.
-* `name`: Can be anything, might be displayed to the user in the client if they choose to manually select a gateway.
-* `country_code`: The [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) two letter country code.
-* `timezone`: The timezone expressed as an offset from UTC (in standard time, not daylight savings). You can look up the timezone using this [handy map](http://www.timeanddate.com/time/map/).
-* `hemisphere`: This should be "S" for all servers in South America, Africa, or Australia. Otherwise, this should be "N".
-
-These location options are very imprecise, but good enough for most usage. The client often does not know its own location precisely either. Instead, the client makes an educated guess at location based on the OS's timezone and locale.
-
-If you have multiple nodes in a single location, it is best to use a tag for the location. For example:
-
-`tags/ankara.json`:
-
-    {
-      "location": {
-        "name": "Ankara",
-        "country_code": "TR",
-        "timezone": "+2",
-        "hemisphere": "N"
-      }
-    }
-
-`nodes/vpngateway.json`:
-
-    {
-      "services": "openvpn",
-      "tags": ["production", "ankara"],
-      "ip_address": "1.1.1.1",
-      "openvpn": {
-        "gateway_address": "1.1.1.2"
-      }
-    }
-
-Unless you are using OpenStack or AWS, setting `location` for nodes is not required. It is, however, highly recommended.
+@title = "Keys and Certificates"
+@summary = "Working with SSH keys, secrets, and X.509 certificates."
 
 Working with SSH
 ================================
@@ -321,34 +173,4 @@ If you want to add additional fields to the CSR, like country, city, or locality
         }
       }
 
-If they are not present, the CSR will be created without them.
-
-Facts
-==============================
-
-There are a few cases when we must gather internal data from a node before we can successfully deploy to other nodes. This is what `facts.json` is for. It stores a snapshot of certain facts about each node, as needed. Entries in `facts.json` are updated automatically when you initialize, rename, or remove a node. To manually force a full update of `facts.json`, run:
-
-    leap facts update FILTER
-
-Run `leap help facts update` for more information.
-
-The file `facts.json` should be committed to source control. You might not have a `facts.json` if one is not required for your provider.
-
-Disabling Nodes
-=====================================
-
-There are two ways to temporarily disable a node:
-
-**Option 1: enabled == false**
-
-If a node has a property `enabled` set to false, then the `leap` command will skip over the node and pretend that it does not exist. For example:
-
-    {
-      "ip_address": "1.1.1.1",
-      "services": ["openvpn"],
-      "enabled": false
-    }
-
-**Options 2: no-deploy**
-
-If the file `/etc/leap/no-deploy` exists on a node, then when you run the commmand `leap deploy` it will halt and prevent a deploy from going through (if the node was going to be included in the deploy).
+If they are not present, the CSR will be created without them.
\ No newline at end of file
diff --git a/docs/platform/guide/miscellaneous.md b/docs/platform/guide/miscellaneous.md
new file mode 100644 (file)
index 0000000..c38c007
--- /dev/null
@@ -0,0 +1,14 @@
+@title = "Miscellaneous"
+@summary = "Miscellaneous commands you may need to know."
+
+Facts
+==============================
+
+There are a few cases when we must gather internal data from a node before we can successfully deploy to other nodes. This is what `facts.json` is for. It stores a snapshot of certain facts about each node, as needed. Entries in `facts.json` are updated automatically when you initialize, rename, or remove a node. To manually force a full update of `facts.json`, run:
+
+    leap facts update FILTER
+
+Run `leap help facts update` for more information.
+
+The file `facts.json` should be committed to source control. You might not have a `facts.json` if one is not required for your provider.
+
diff --git a/docs/platform/guide/nodes.md b/docs/platform/guide/nodes.md
new file mode 100644 (file)
index 0000000..bc48ff3
--- /dev/null
@@ -0,0 +1,169 @@
+@title = "Nodes"
+@summary = "Working with nodes, services, tags, and locations."
+
+Node types
+================================
+
+Every node has one or more services that determines the node's function within your provider's infrastructure.
+
+When adding a new node to your provider, you should ask yourself four questions:
+
+* **many or few?** Some services benefit from having many nodes, while some services are best run on only one or two nodes.
+* **required or optional?** Some services are required, while others can be left out.
+* **who does the node communicate with?** Some services communicate very heavily with other particular services. Nodes running these services should be close together.
+* **public or private?** Some services communicate with the public internet, while others only need to communicate with other nodes in the infrastructure.
+
+Brief overview of the services:
+
+* **webapp**: The web application. Runs both webapp control panel for users and admins as well as the REST API that the client uses. Needs to communicate heavily with `couchdb` nodes. You need at least one, good to have two for redundancy. The webapp does not get a lot of traffic, so you will not need many.
+* **couchdb**: The database for users and user data. You can get away with just one, but for proper redundancy you should have at least three. Communicates heavily with `webapp`, `mx`, and `soledad` nodes.
+* **soledad**: Handles the data syncing with clients. Typically combined with `couchdb` service, since it communicates heavily with couchdb.
+* **mx**: Incoming and outgoing MX servers. Communicates with the public internet, clients, and `couchdb` nodes.
+* **openvpn**: OpenVPN gateway for clients. You need at least one, but want as many as needed to support the bandwidth your users are doing. The `openvpn` nodes are autonomous and don't need to communicate with any other nodes. Often combined with `tor` service.
+* **monitor**: Internal service to monitor all the other nodes. Currently, you can have zero or one `monitor` nodes.
+* **tor**: Sets up a tor exit node, unconnected to any other service.
+* **dns**: Not yet implemented.
+
+Webapp
+-----------------------------------
+
+The webapp node is responsible for both the user face web application and the API that the client interacts with.
+
+Some users can be "admins" with special powers to answer tickets and close accounts. To make an account into an administrator, you need to configure the `webapp.admins` property with an array of user names.
+
+For example, to make users `alice` and `bob` into admins, create a file `services/webapp.json` with the following content:
+
+    {
+      "webapp": {
+        "admins": ["bob", "alice"]
+      }
+    }
+
+And then redeploy to all webapp nodes:
+
+    leap deploy webapp
+
+By putting this in `services/webapp.json`, you will ensure that all webapp nodes inherit the value for `webapp.admins`.
+
+Services
+================================
+
+What nodes do you need for a provider that offers particular services?
+
+<table class="table table-striped">
+<tr>
+<th>Node Type</th>
+<th>VPN Service</th>
+<th>Email Service</th>
+</tr>
+<tr>
+<td>webapp</td>
+<td>required</td>
+<td>required</td>
+</tr>
+<tr>
+<td>couchdb</td>
+<td>required</td>
+<td>required</td>
+</tr>
+<tr>
+<td>soledad</td>
+<td>not used</td>
+<td>required</td>
+</tr>
+<tr>
+<td>mx</td>
+<td>not used</td>
+<td>required</td>
+</tr>
+<tr>
+<td>openvpn</td>
+<td>required</td>
+<td>not used</td>
+</tr>
+<tr>
+<td>monitor</td>
+<td>optional</td>
+<td>optional</td>
+</tr>
+<tr>
+<td>tor</td>
+<td>optional</td>
+<td>optional</td>
+</tr>
+<table>
+
+Locations
+================================
+
+All nodes should have a `location.name` specified, and optionally additional information about the location, like the time zone. This location information is used for two things:
+
+* Determine which nodes can, or must, communicate with one another via a local network. The way some virtualization environments work, like OpenStack, requires that nodes communicate via the local network if they are on the same network.
+* Allows the client to prefer connections to nodes that are closer in physical proximity to the user. This is particularly important for OpenVPN nodes.
+
+The location stanza in a node's config file looks like this:
+
+    {
+      "location": {
+        "id": "ankara",
+        "name": "Ankara",
+        "country_code": "TR",
+        "timezone": "+2",
+        "hemisphere": "N"
+      }
+    }
+
+The fields:
+
+* `id`: An internal handle to use for this location. If two nodes have match `location.id`, then they are treated as being on a local network with one another. This value defaults to downcase and underscore of `location.name`.
+* `name`: Can be anything, might be displayed to the user in the client if they choose to manually select a gateway.
+* `country_code`: The [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) two letter country code.
+* `timezone`: The timezone expressed as an offset from UTC (in standard time, not daylight savings). You can look up the timezone using this [handy map](http://www.timeanddate.com/time/map/).
+* `hemisphere`: This should be "S" for all servers in South America, Africa, or Australia. Otherwise, this should be "N".
+
+These location options are very imprecise, but good enough for most usage. The client often does not know its own location precisely either. Instead, the client makes an educated guess at location based on the OS's timezone and locale.
+
+If you have multiple nodes in a single location, it is best to use a tag for the location. For example:
+
+`tags/ankara.json`:
+
+    {
+      "location": {
+        "name": "Ankara",
+        "country_code": "TR",
+        "timezone": "+2",
+        "hemisphere": "N"
+      }
+    }
+
+`nodes/vpngateway.json`:
+
+    {
+      "services": "openvpn",
+      "tags": ["production", "ankara"],
+      "ip_address": "1.1.1.1",
+      "openvpn": {
+        "gateway_address": "1.1.1.2"
+      }
+    }
+
+Unless you are using OpenStack or AWS, setting `location` for nodes is not required. It is, however, highly recommended.
+
+Disabling Nodes
+=====================================
+
+There are two ways to temporarily disable a node:
+
+**Option 1: enabled == false**
+
+If a node has a property `enabled` set to false, then the `leap` command will skip over the node and pretend that it does not exist. For example:
+
+    {
+      "ip_address": "1.1.1.1",
+      "services": ["openvpn"],
+      "enabled": false
+    }
+
+**Options 2: no-deploy**
+
+If the file `/etc/leap/no-deploy` exists on a node, then when you run the commmand `leap deploy` it will halt and prevent a deploy from going through (if the node was going to be included in the deploy).
diff --git a/docs/platform/troubleshooting/en.haml b/docs/platform/troubleshooting/en.haml
new file mode 100644 (file)
index 0000000..a4b4493
--- /dev/null
@@ -0,0 +1,5 @@
+- @title = "Troubleshooting"
+
+%h1.first Troubleshooting
+
+= child_summaries
\ No newline at end of file
similarity index 82%
rename from docs/platform/tests.md
rename to docs/platform/troubleshooting/tests.md
index 71b47c1..8406404 100644 (file)
@@ -2,7 +2,7 @@
 @summary = 'Testing and monitoring your infrastructure.'
 @toc = true
 
-## Tests
+## Troubleshooting Tests
 
 At any time, you can run troubleshooting tests on the nodes of your provider infrastructure to check to see if things seem to be working correctly. If there is a problem, these tests should help you narrow down precisely where the problem is.
 
@@ -17,16 +17,17 @@ Alternately, you can run test on all nodes (probably only useful if you have pin
 ## Monitoring
 
 In order to set up a monitoring node, you simply add a `monitor` service tag to the node configuration file. It could be combined with any other service, but we propose that you add it to the webapp node, as this already is public accessible via HTTPS.
-After deploying, this node will regularly poll every node to ask for the status of various health checks. These health checks include the checks run with `leap test`, plus many others. 
+
+After deploying, this node will regularly poll every node to ask for the status of various health checks. These health checks include the checks run with `leap test`, plus many others.
+
 We use [Nagios](http://www.nagios.org/) together with [Check MK agent](https://en.wikipedia.org/wiki/Check_MK) for running checks on remote hosts.
 
 You can log into the monitoring web interface via [https://MONITORNODE/nagios3/](https://MONITORNODE/nagios3/). The username is `nagiosadmin` and the password is found in the secrets.json file in your provider directory.
 
-Log Monitoring
---------------
+### Log Monitoring
 
 At the moment, we use [check-mk-agent-logwatch](https://mathias-kettner.de/checkmk_check_logwatch.html) for searching logs for irregularities.
 Logs are parsed for patterns using a blacklist, and are stored in `/var/lib/check_mk/logwatch/<Nodename>`.
 
-In order to "acknoledge" a log warning, you need to log in to the monitoring server, and delete the corresponding file in `/var/lib/check_mk/logwatch/<Nodename>`. This should be done via the nagios webinterface in the future.
+In order to "acknowledge" a log warning, you need to log in to the monitoring server, and delete the corresponding file in `/var/lib/check_mk/logwatch/<Nodename>`. This should be done via the nagios webinterface in the future.
 
similarity index 99%
rename from docs/platform/troubleshooting.md
rename to docs/platform/troubleshooting/where-to-look.md
index 528248d..fbd9593 100644 (file)
@@ -1,5 +1,5 @@
-@title = 'Troubleshooting Guide'
-@nav_title = 'Troubleshooting'
+@title = 'Where to look for errors'
+@nav_title = 'Where to look'
 @toc = true
 
 
diff --git a/docs/platform/tutorials/en.haml b/docs/platform/tutorials/en.haml
new file mode 100644 (file)
index 0000000..72a8a1f
--- /dev/null
@@ -0,0 +1,5 @@
+- @title = "Tutorials"
+
+%h1.first Platform Tutorials
+
+= child_summaries
\ No newline at end of file
similarity index 89%
rename from docs/platform/quick-start.md
rename to docs/platform/tutorials/quick-start.md
index e1fe05a..f45574d 100644 (file)
@@ -1,5 +1,6 @@
 @title = 'LEAP Platform Quick Start'
 @nav_title = 'Quick Start'
+@summary = 'Three node OpenVPN provider.'
 
 Quick Start
 ===========
@@ -14,10 +15,10 @@ We are going to create a minimal LEAP provider offering OpenVPN service. This ba
 Our goal is something like this:
 
     $ leap list
-           NODES   SERVICES           TAGS
-           couch1  couchdb
-           web1    webapp
-           vpn1    openvpn
+         NODES   SERVICES    TAGS
+       cheetah   couchdb     production
+    wildebeest   webapp      production
+       ostrich   openvpn     production
 
 NOTE: You won't be able to run that `leap list` command yet, not until we actually create the node configurations.
 
@@ -28,11 +29,11 @@ In order to complete this Quick Start, you will need a few things:
 
 * You will need three real or paravirtualized virtual machines (KVM, Xen, Openstack, Amazon, but not Vagrant - sorry) that have a basic Debian Stable installed. If you allocate 20G of disk space to each node for the system, after this process is completed, you will have used less than 10% of that disk space. If you allocate 2 CPUs and 8G of memory to each node, that should be more than enough to begin with.
 * You should be able to SSH into them remotely, and know their root password, IP addresses and their SSH host keys
-* You will need four different IPs, one for each node, and a second one for the VPN gateway
+* You will need four different IPs. Each node gets a primary IP, and the OpenVPN gateway additionally needs a gateway IP.
 * The ability to create/modify DNS entries for your domain is preferable, but not needed. If you don't have access to DNS, you can workaround this by modifying your local resolver, i.e. editing `/etc/hosts`.
 * You need to be aware that this process will make changes to your systems, so please be sure that these machines are a basic install with nothing configured or running for other purposes
 * Your machines will need to be connected to the internet, and not behind a restrictive firewall.
-* You should work locally on your laptop/workstation (one that you trust and that is ideally full-disk encrypted) while going through this guide. This is important because the provider configurations you are creating contain sensitive data that should not reside on a remote machine. The leap cli utility will login to your servers and configure the services.
+* You should work locally on your laptop/workstation (one that you trust and that is ideally full-disk encrypted) while going through this guide. This is important because the provider configurations you are creating contain sensitive data that should not reside on a remote machine. The `leap` command will login to your servers and configure the services.
 * You should do everything described below as an unprivileged user, and only run those commands as root that are noted with *sudo* in front of them. Other than those commands, there is no need for privileged access to your machine, and in fact things may not work correctly.
 
 All the commands in this tutorial are run on your sysadmin machine. In order to complete the tutorial, the sysadmin will do the following:
@@ -70,7 +71,7 @@ Install core prerequisites:
 1. Install rubygems from https://rubygems.org/pages/download (unless the `gem` command is already installed).
 -->
 
-NOTE: leap_cli should work with ruby1.8, but has only been tested using ruby1.9.
+NOTE: leap_cli requires ruby 1.9 or later.
 
 
 Install the LEAP command-line utility
@@ -208,21 +209,21 @@ A "node" is a server that is part of your infrastructure. Every node can have on
 
 Create a node, with the service "webapp":
 
-    $ leap node add web1 ip_address:x.x.x.w services:webapp tags:production
+    $ leap node add wildebeest ip_address:x.x.x.w services:webapp tags:production
 
 NOTE: replace x.x.x.w with the actual IP address of this node
 
-This created a node configuration file in `nodes/web1.json`, but it did not do anything else. It also added the 'tag' called 'production' to this node. Tags allow us to conveniently group nodes together. When creating nodes, you should give them the tag 'production' if the node is to be used in your production infrastructure.
+This created a node configuration file in `nodes/wildebeest.json`, but it did not do anything else. It also added the 'tag' called 'production' to this node. Tags allow us to conveniently group nodes together. When creating nodes, you should give them the tag 'production' if the node is to be used in your production infrastructure.
 
 The web application and the VPN nodes require a database, so lets create the database server node:
 
-    $ leap node add couch1 ip_address:x.x.x.x services:couchdb tags:production
+    $ leap node add cheetah ip_address:x.x.x.x services:couchdb tags:production
 
 NOTE: replace x.x.x.x with the actual IP address of this node
 
-Now we need the VPN gateway, so lets create that node:
+Now we need the OpenVPN gateway, so lets create that node:
 
-    $ leap node add vpn1 ip_address:x.x.x.y openvpn.gateway_address:x.x.x.z services:openvpn tags:production
+    $ leap node add ostrich ip_address:x.x.x.y openvpn.gateway_address:x.x.x.z services:openvpn tags:production
 
 NOTE: replace x.x.x.y with the IP address of the machine, and x.x.x.z with the second IP. openvpn gateways must be assigned two IP addresses, one for the host itself and one for the openvpn gateway. We do this to prevent incoming and outgoing VPN traffic on the same IP. Without this, the client might send some traffic to other VPN users in the clear, bypassing the VPN.
 
@@ -235,9 +236,9 @@ Now that you have the nodes configured, you should create the DNS entries for th
 Set up your DNS with these hostnames:
 
     $ leap list --print ip_address,domain.full,dns.aliases
-        couch1  x.x.x.w, couch1.example.org, null
-          web1  x.x.x.x, web1.example.org, api.example.org, nicknym.example.org
-          vpn1  x.x.x.y, vpn1.example.org, null
+       cheetah  x.x.x.w, cheetah.example.org, null
+    wildebeest  x.x.x.x, wildebeest.example.org, api.example.org
+       ostrich  x.x.x.y, ostrich.example.org, null
 
 Alternately, you can adapt this zone file snippet:
 
@@ -245,9 +246,9 @@ Alternately, you can adapt this zone file snippet:
 
 If you cannot edit your DNS zone file, you can still test your provider by adding entries to your local resolver hosts file (`/etc/hosts` for linux):
 
-    x.x.x.w couch1.example.org
-    x.x.x.x web1.example.org api.example.org example.org
-    x.x.x.y vpn1.example.org
+    x.x.x.w cheetah.example.org
+    x.x.x.x wildebeest.example.org api.example.org example.org
+    x.x.x.y ostrich.example.org
 
 Please don't forget about these entries, they will override DNS queries if you setup your DNS later.
 
@@ -263,26 +264,26 @@ This will initialize all nodes with the tag "production". When `leap node init`
 
 If you prefer, you can initalize each node, one at a time:
 
-    $ leap node init web1
-    $ leap node init couch1
-    $ leap node init vpn1
+    $ leap node init wildebeest
+    $ leap node init cheetah
+    $ leap node init ostrich
 
 Deploy the LEAP platform to the nodes
 --------------------
 
-Now you should deploy the platform recipes to the nodes. [Deployment can take a while to run](http://xkcd.com/303/), especially on the first run, as it needs to update the packages on the new machine. 
+Now you should deploy the platform recipes to the nodes. [Deployment can take a while to run](http://xkcd.com/303/), especially on the first run, as it needs to update the packages on the new machine.
+
 *Important notes:* currently nodes must be deployed in a certain order. The underlying couch database node(s) must be deployed first, and then all other nodes. Also you need to configure and deploy all of the couchdb nodes that you plan to use at this time, as currently you cannot add more of them later later ([See](https://leap.se/es/docs/platform/known-issues#CouchDB.Sync)).
 
-    $ leap deploy couch1
+    $ leap deploy cheetah
 
 Watch the output for any errors (in red), if everything worked fine, you should now have your first running node. If you do have errors, try doing the deploy again.
 
 However, to deploy our three-node openvpn setup, we need the database and LEAP web application requires a database to run, so let's deploy to the couchdb and openvpn nodes:
 
-    $ leap deploy web1
-    $ leap deploy vpn1
+    $ leap deploy wildebeest
+    $ leap deploy ostrich
 
-NOTE: the output from deploying can be quite busy, so we often do them each node one by one.
 
 What is going on here?
 --------------------------------------------
@@ -300,19 +301,21 @@ When you run `leap deploy`, a bunch of things happen, in this order:
 
 You can run `leap -v2 deploy` to see exactly what commands are being executed.
 
-<!-- See [under the hood](under-the-hood) for more details. -->
-
 
 Test that things worked correctly
 =================================
 
 You should now have three machines with the LEAP platform deployed to them, one for the web application, one for the database and one for the OpenVPN gateway.
 
+To run troubleshooting tests:
 
-Access the web application
---------------------------------------------
+    leap test
+
+If you want to confirm for yourself that things are working, you can perform the following manual tests.
+
+### Access the web application
 
-In order to connect to the web application in your browser, you need to point your domain at the IP address of the web application node (named web1 in this example).
+In order to connect to the web application in your browser, you need to point your domain at the IP address of the web application node (named wildebeest in this example).
 
 There are a lot of different ways to do this, but one easy way is to modify your `/etc/hosts` file. First, find the IP address of the webapp node:
 
@@ -326,8 +329,7 @@ Replacing 'leap.example.org' with whatever you specified as the `domain` in the
 
 Next, you can connect to the web application either using a web browser or via the API using the LEAP client. To use a browser, connect to https://leap.example.org (replacing that with your domain). Your browser will complain about an untrusted cert, but for now just bypass this. From there, you should be able to register a new user and login.
 
-Use the VPN
------------
+### Use the VPN
 
 You should be able to simply test that the OpenVPN gateway works properly by doing the following:
 
@@ -347,7 +349,7 @@ Useful commands
 
 Here are a few useful commands you can run on your new local nodes:
 
-* `leap ssh web1` -- SSH into node web1 (requires `leap node init web1` first).
+* `leap ssh wildebeest` -- SSH into node wildebeest (requires `leap node init wildebeest` first).
 * `leap list` -- list all nodes.
 * `leap list production` -- list only those nodes with the tag 'production'
 * `leap list --print ip_address` -- list a particular attribute of all nodes.
@@ -371,7 +373,7 @@ Examples:
 * `leap list openvpn` -- list all nodes with service openvpn.
 * `leap list openvpn +production` -- only nodes of service type openvpn AND tag production.
 * `leap deploy webapp openvpn` -- deploy to all webapp OR openvpn nodes.
-* `leap node init vpn1` -- just init the node named vpn1.
+* `leap node init ostrich` -- just init the node named ostrich.
 
 Keep track of your provider configurations
 ------------------------------------------
similarity index 98%
rename from docs/platform/quick-start-singlenode.md
rename to docs/platform/tutorials/single-node.md
index 87c6f52..02d35c7 100644 (file)
@@ -1,5 +1,6 @@
-@title = 'LEAP Platform Quick Start - Single node setup'
-@nav_title = 'Quick Start - Single node'
+@title = 'Single node tutorial'
+@nav_title = 'Single node'
+@summary = 'A single node email provider.'
 
 Quick Start - Single node setup
 ===============================
@@ -15,8 +16,8 @@ We are going to create a minimal LEAP provider offering Email service. This basi
 Our goal is something like this:
 
     $ leap list
-        NODES   SERVICES                       TAGS  
-        node1   couchdb, mx, soledad, webapp   local 
+        NODES   SERVICES                       TAGS
+        node1   couchdb, mx, soledad, webapp   local
 
 NOTE: You won't be able to run that `leap list` command yet, not until we actually create the node configurations.
 
@@ -25,7 +26,7 @@ Requirements
 
 In order to complete this Quick Start, you will need a few things:
 
-* You will need one real or paravirtualized virtual machine (Vagrant, KVM, Xen, Openstack, Amazon, …) that have a basic Debian Stable installed. 
+* You will need one real or paravirtualized virtual machine (Vagrant, KVM, Xen, Openstack, Amazon, …) that have a basic Debian Stable installed.
 * You should be able to SSH into them remotely, and know their root password, IP addresses and their SSH host keys
 * The ability to create/modify DNS entries for your domain is preferable, but not needed. If you don't have access to DNS, you can workaround this by modifying your local resolver, i.e. editing `/etc/hosts`.
 * You need to be aware that this process will make changes to your systems, so please be sure that these machines are a basic install with nothing configured or running for other purposes
@@ -226,7 +227,7 @@ Alternately, you can adapt this zone file snippet:
 
 If you cannot edit your DNS zone file, you can still test your provider by adding this entry to your local resolver hosts file (`/etc/hosts` for linux):
 
-    x.x.x.w node1.example.org example.org api.example.org nicknym.example.org 
+    x.x.x.w node1.example.org example.org api.example.org nicknym.example.org
 
 Please don't forget about these entries, they will override DNS queries if you setup your DNS later.
 
@@ -244,7 +245,7 @@ This will initialize the node with the tag "production". When `leap node init` i
 Deploy the LEAP platform to the nodes
 --------------------
 
-Now you should deploy the platform recipes to the nodes. [Deployment can take a while to run](http://xkcd.com/303/), especially on the first run, as it needs to update the packages on the new machine. 
+Now you should deploy the platform recipes to the nodes. [Deployment can take a while to run](http://xkcd.com/303/), especially on the first run, as it needs to update the packages on the new machine.
 
     $ leap deploy
 
index ec021fb..2246d0b 100644 (file)
--- a/menu.txt
+++ b/menu.txt
@@ -17,16 +17,23 @@ docs
     tapicero
     webapp
   platform
-    quick-start
     guide
-    config
-    commands
-    under-the-hood
-    tests
-    known-issues
-    faq
+      nodes
+      keys-and-certificates
+      miscellaneous
+      config
+      commands
+    tutorials
+      quick-start
+      single-node
     troubleshooting
-    development
+      tests
+      where-to-look
+      known-issues
+    details
+      faq
+      development
+      under-the-hood
   client
     user-install
     user-running