aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorThomas Duval <thomas.duval@orange.com>2016-08-12 15:28:34 +0200
committerThomas Duval <thomas.duval@orange.com>2016-08-12 15:28:34 +0200
commit51a65a7286ee1e8c1ab69b2ef809dacde88cd508 (patch)
treec377ab6e1d4ce40419812283a533c03e640454a8 /docs
parent5634a52f01ddff5438516e5d60b98dc04c685a32 (diff)
Add documentation for OPNFV
Change-Id: I38c136308610bd414d73ca98faa71e9202d6361a
Diffstat (limited to 'docs')
-rw-r--r--docs/configurationguide/index.rst198
-rw-r--r--docs/img/moon_infra.png669
-rw-r--r--docs/img/policy_engine.png669
-rw-r--r--docs/installationprocedure/index.rst330
-rw-r--r--docs/platformoverview/index.rst152
-rw-r--r--docs/userguide/index.rst850
6 files changed, 2868 insertions, 0 deletions
diff --git a/docs/configurationguide/index.rst b/docs/configurationguide/index.rst
new file mode 100644
index 00000000..4001a63e
--- /dev/null
+++ b/docs/configurationguide/index.rst
@@ -0,0 +1,198 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) ruan.he@orange.com & thomas.duval@orange.com
+
+******************************
+OPNFV MOON configuration guide
+******************************
+
+.. toctree::
+ :numbered:
+ :maxdepth: 2
+
+
+============
+Introduction
+============
+
+Moon must be configured through the standard Keystone configuration files and the standard KeystoneMiddleware configuration files:
+* /etc/keystone/keystone-paste.ini
+* /etc/keystone/keystone.conf
+* /etc/nova/api-paste.ini
+* /etc/swift/proxy-server.conf
+
+There is no other custom configuration file.
+
+=============
+Configuration
+=============
+
+Keystone
+========
+
+For Keystone, the following files must be configured, some modifications may be needed, specially passwords:
+
+/etc/keystone/keystone-paste.ini
+
+.. code-block:: bash
+
+ sudo cp /etc/keystone/keystone-paste.ini /etc/keystone/keystone-paste.ini.bak
+ sudo sed "3i[pipeline:moon_pipeline]\npipeline = sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension moon_service\n\n[app:moon_service]\nuse = egg:keystone#moon_service\n" /etc/keystone/keystone-paste.ini > /tmp/keystone-paste.ini
+ sudo cp /tmp/keystone-paste.ini /etc/keystone/keystone-paste.ini
+ sudo sed "s/use = egg:Paste#urlmap/use = egg:Paste#urlmap\n\/moon = moon_pipeline/" /etc/keystone/keystone-paste.ini > /tmp/keystone-paste.ini
+ sudo cp /tmp/keystone-paste.ini /etc/keystone/keystone-paste.ini
+
+/etc/keystone/keystone.conf
+
+.. code-block:: bash
+
+ cat << EOF | sudo tee -a /etc/keystone/keystone.conf
+ [moon]
+
+ # Configuration backend driver
+ configuration_driver = keystone.contrib.moon.backends.memory.ConfigurationConnector
+
+ # Tenant backend driver
+ tenant_driver = keystone.contrib.moon.backends.sql.TenantConnector
+
+ # Authorisation backend driver
+ authz_driver = keystone.contrib.moon.backends.flat.SuperExtensionConnector
+
+ # IntraExtension backend driver
+ intraextension_driver = keystone.contrib.moon.backends.sql.IntraExtensionConnector
+
+ # InterExtension backend driver
+ interextension_driver = keystone.contrib.moon.backends.sql.InterExtensionConnector
+
+ # Logs backend driver
+ log_driver = keystone.contrib.moon.backends.flat.LogConnector
+
+ # Local directory where all policies are stored
+ policy_directory = /etc/keystone/policies
+
+ # Local directory where Root IntraExtension configuration is stored
+ root_policy_directory = policy_root
+
+ # URL of the Moon master
+ master = 'http://localhost:35357/'
+
+ # Login of the Moon master
+ master_login = 'admin'
+
+ # Password of the Moon master
+ master_password = 'nomoresecrete'
+ EOF
+
+
+The logging system must be configured :
+
+.. code-block:: bash
+
+ sudo mkdir /var/log/moon/
+ sudo chown keystone /var/log/moon/
+
+ sudo addgroup moonlog
+
+ sudo chgrp moonlog /var/log/moon/
+
+ sudo touch /var/log/moon/keystonemiddleware.log
+ sudo touch /var/log/moon/system.log
+
+ sudo chgrp moonlog /var/log/moon/keystonemiddleware.log
+ sudo chgrp moonlog /var/log/moon/system.log
+ sudo chmod g+rw /var/log/moon
+ sudo chmod g+rw /var/log/moon/keystonemiddleware.log
+ sudo chmod g+rw /var/log/moon/system.log
+
+ sudo adduser keystone moonlog
+ sudo adduser swift moonlog
+ sudo adduser nova moonlog
+
+The Keystone database must be updated:
+
+.. code-block:: bash
+
+ sudo /usr/bin/keystone-manage db_sync
+ sudo /usr/bin/keystone-manage db_sync --extension moon
+
+And, Apache must be restarted:
+
+.. code-block:: bash
+
+ sudo systemctl restart apache.service
+
+Nova
+====
+
+In order to Nova to be able to communicate with Keystone-Moon, you must update the Nova KeystoneMiddleware configuration file.
+To achieve this, a new filter must be added in `/etc/nova/api-paste.ini` and this filter must be added to the composite data.
+The filter is:
+
+.. code-block:: bash
+
+ [filter:moon]
+ paste.filter_factory = keystonemiddleware.moon_agent:filter_factory
+ authz_login=admin
+ authz_password=password
+ logfile=/var/log/moon/keystonemiddleware.log
+
+Here is some bash lines to insert this into the Nova configuration file:
+
+.. code-block:: bash
+
+ sudo cp /etc/nova/api-paste.ini /etc/nova/api-paste.ini.bak2
+ sudo sed "/^keystone = / s/keystonecontext/keystonecontext moon/" /etc/nova/api-paste.ini > /tmp/api-paste.ini
+ sudo cp /tmp/api-paste.ini /etc/nova/api-paste.ini
+
+ echo -e "\n[filter:moon]\npaste.filter_factory = keystonemiddleware.moon_agent:filter_factory\nauthz_login=admin\nauthz_password=password\nlogfile=/var/log/moon/keystonemiddleware.log\n" | sudo tee -a /etc/nova/api-paste.ini
+
+Nova can then be restarted:
+
+.. code-block:: bash
+
+ for service in nova-compute nova-api nova-cert nova-conductor nova-consoleauth nova-scheduler ; do
+ sudo service ${service} restart
+ done
+
+Swift
+=====
+
+In order to Swift to be able to communicate with Keystone-Moon, you must update the Swift KeystoneMiddleware configuration file.
+To achieve this, a new filter must be added in `/etc/swift/proxy-server.conf` and this filter must be added to the composite data.
+The filter is (exactly the same as Nova):
+
+.. code-block:: bash
+
+ [filter:moon]
+ paste.filter_factory = keystonemiddleware.moon_agent:filter_factory
+ authz_login=admin
+ authz_password=password
+ logfile=/var/log/moon/keystonemiddleware.log
+
+Here is some bash lines to insert this into the Nova configuration file:
+
+.. code-block:: bash
+
+ sudo cp /etc/swift/proxy-server.conf /etc/swift/proxy-server.conf.bak2
+ sudo sed "/^pipeline = / s/proxy-server/moon proxy-server/" /etc/swift/proxy-server.conf > /tmp/proxy-server.conf
+ sudo cp /tmp/proxy-server.conf /etc/swift/proxy-server.conf
+
+ echo -e "\n[filter:moon]\npaste.filter_factory = keystonemiddleware.moon_agent:filter_factory\nauthz_login=admin\nauthz_password=password\nlogfile=/var/log/moon/keystonemiddleware.log\n" | sudo tee -a /etc/swift/proxy-server.conf
+
+Swift can then be restarted:
+
+.. code-block:: bash
+
+ for service in swift-account swift-account-replicator \
+ swift-container-replicator swift-object swift-object-updater \
+ swift-account-auditor swift-container swift-container-sync \
+ swift-object-auditor swift-proxy swift-account-reaper swift-container-auditor \
+ swift-container-updater swift-object-replicator ; do
+ sudo service ${service} status
+ done
+
+
+
+Revision: _sha1_
+
+Build date: |today| \ No newline at end of file
diff --git a/docs/img/moon_infra.png b/docs/img/moon_infra.png
new file mode 100644
index 00000000..1c2e8c02
--- /dev/null
+++ b/docs/img/moon_infra.png
@@ -0,0 +1,669 @@
+
+
+
+
+<!DOCTYPE html>
+<html lang="en" class=" is-copy-enabled">
+ <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#">
+ <meta charset='utf-8'>
+
+
+ <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-be4c6e0e479a2d4d0eb3159c8772b5bfc4aa39831cb28f5f92cc2e448d93eaa1.css" integrity="sha256-vkxuDkeaLU0OsxWch3K1v8SqOYMcso9fkswuRI2T6qE=" media="all" rel="stylesheet" />
+ <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-2172647018381485dc3021817136b6cbb4c7f1a47f195b528c5c72f9260f4271.css" integrity="sha256-IXJkcBg4FIXcMCGBcTa2y7TH8aR/GVtSjFxy+SYPQnE=" media="all" rel="stylesheet" />
+
+
+
+
+
+ <link as="script" href="https://assets-cdn.github.com/assets/frameworks-efdb851061bb7933d0e409f8be67f6ae483a2fa8612b913ae2678aa4abf4569a.js" rel="preload" />
+
+ <link as="script" href="https://assets-cdn.github.com/assets/github-d09d041c0bb26578f4971b50803dbdba4f19a632670c92dc2fb2f9905e435636.js" rel="preload" />
+
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta http-equiv="Content-Language" content="en">
+ <meta name="viewport" content="width=device-width">
+
+ <title>rebirthmonkey.github.io/moon_infra.png at master · rebirthmonkey/rebirthmonkey.github.io</title>
+ <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
+ <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png">
+ <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
+ <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
+ <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
+ <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
+ <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
+ <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
+ <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
+ <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
+ <meta property="fb:app_id" content="1401488693436528">
+
+ <meta content="https://avatars3.githubusercontent.com/u/5707752?v=3&amp;s=400" name="twitter:image:src" /><meta content="@github" name="twitter:site" /><meta content="summary" name="twitter:card" /><meta content="rebirthmonkey/rebirthmonkey.github.io" name="twitter:title" /><meta content="rebirthmonkey.github.io - Wukong&#39;s Bloc" name="twitter:description" />
+ <meta content="https://avatars3.githubusercontent.com/u/5707752?v=3&amp;s=400" property="og:image" /><meta content="GitHub" property="og:site_name" /><meta content="object" property="og:type" /><meta content="rebirthmonkey/rebirthmonkey.github.io" property="og:title" /><meta content="https://github.com/rebirthmonkey/rebirthmonkey.github.io" property="og:url" /><meta content="rebirthmonkey.github.io - Wukong&#39;s Bloc" property="og:description" />
+ <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
+ <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
+ <link rel="assets" href="https://assets-cdn.github.com/">
+ <link rel="web-socket" href="wss://live.github.com/_sockets/NzA3OTU5ODo2OWM0Y2RhNGM0NTcwNGQ4MmZiYTg4OTgzMDJhMjZhZjo1N2YwZjdlZWU2ZTQxNjg4YWJhN2NmMDJjN2JiYjA3NTQxMGVlZjk3YTBiODE5NmVjMGQ5NThlOTUwNjE0NGJj--c823af5d802f8f59e45ad501a8092923685f54c6">
+ <meta name="pjax-timeout" content="1000">
+ <link rel="sudo-modal" href="/sessions/sudo_modal">
+ <meta name="request-id" content="C202CA51:1FFC:D9E62C:57AC865F" data-pjax-transient>
+
+ <meta name="msapplication-TileImage" content="/windows-tile.png">
+ <meta name="msapplication-TileColor" content="#ffffff">
+ <meta name="selected-link" value="repo_source" data-pjax-transient>
+
+ <meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
+<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
+ <meta name="google-analytics" content="UA-3769691-2">
+
+<meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" /><meta content="C202CA51:1FFC:D9E62C:57AC865F" name="octolytics-dimension-request_id" /><meta content="7079598" name="octolytics-actor-id" /><meta content="dthom" name="octolytics-actor-login" /><meta content="9c4e325d50d942c182d7c2694b1e2606da1e566788bcf5a9b6b9680a957dfb6a" name="octolytics-actor-hash" />
+<meta content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-pjax-transient="true" name="analytics-location" />
+
+
+
+ <meta class="js-ga-set" name="dimension1" content="Logged In">
+
+
+
+ <meta name="hostname" content="github.com">
+ <meta name="user-login" content="dthom">
+
+ <meta name="expected-hostname" content="github.com">
+ <meta name="js-proxy-site-detection-payload" content="NzU4Njk2NTQxN2YwYzdjYjczODkxYzhhZDdkYzYxYTdjNDgxYmZlNWJkZjJjYTJhZWFlOTBjZmI5YjE1MWQ3Y3x7InJlbW90ZV9hZGRyZXNzIjoiMTk0LjIuMjAyLjgxIiwicmVxdWVzdF9pZCI6IkMyMDJDQTUxOjFGRkM6RDlFNjJDOjU3QUM4NjVGIiwidGltZXN0YW1wIjoxNDcwOTI0MzgzfQ==">
+
+
+ <link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#4078c0">
+ <link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">
+
+ <meta name="html-safe-nonce" content="f8d22d1ea86c94ab8c05e89327ece5451ac180d1">
+ <meta content="4575b3e17adfc8057914e1edc819062b7be0bf8f" name="form-nonce" />
+
+ <meta http-equiv="x-pjax-version" content="15d2202b74ada67a977cd0b44d4b4c5f">
+
+
+
+ <meta name="description" content="rebirthmonkey.github.io - Wukong&#39;s Bloc">
+ <meta name="go-import" content="github.com/rebirthmonkey/rebirthmonkey.github.io git https://github.com/rebirthmonkey/rebirthmonkey.github.io.git">
+
+ <meta content="5707752" name="octolytics-dimension-user_id" /><meta content="rebirthmonkey" name="octolytics-dimension-user_login" /><meta content="27342779" name="octolytics-dimension-repository_id" /><meta content="rebirthmonkey/rebirthmonkey.github.io" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="true" name="octolytics-dimension-repository_is_fork" /><meta content="15397768" name="octolytics-dimension-repository_parent_id" /><meta content="LingxianKong/lingxiankong.github.io" name="octolytics-dimension-repository_parent_nwo" /><meta content="2843336" name="octolytics-dimension-repository_network_root_id" /><meta content="beiyuu/Github-Pages-Example" name="octolytics-dimension-repository_network_root_nwo" />
+ <link href="https://github.com/rebirthmonkey/rebirthmonkey.github.io/commits/master.atom" rel="alternate" title="Recent Commits to rebirthmonkey.github.io:master" type="application/atom+xml">
+
+
+ <link rel="canonical" href="https://github.com/rebirthmonkey/rebirthmonkey.github.io/blob/master/images/moon/moon_infra.png" data-pjax-transient>
+ </head>
+
+
+ <body class="logged-in env-production linux vis-public fork page-blob">
+ <div id="js-pjax-loader-bar" class="pjax-loader-bar"><div class="progress"></div></div>
+ <a href="#start-of-content" tabindex="1" class="accessibility-aid js-skip-to-content">Skip to content</a>
+
+
+
+
+
+
+
+ <div class="header header-logged-in true" role="banner">
+ <div class="container clearfix">
+
+ <a class="header-logo-invertocat" href="https://github.com/" data-hotkey="g d" aria-label="Homepage" data-ga-click="Header, go to dashboard, icon:logo">
+ <svg aria-hidden="true" class="octicon octicon-mark-github" height="28" version="1.1" viewBox="0 0 16 16" width="28"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
+</a>
+
+
+ <div class="header-search scoped-search site-scoped-search js-site-search" role="search">
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/search" class="js-site-search-form" data-scoped-search-url="/rebirthmonkey/rebirthmonkey.github.io/search" data-unscoped-search-url="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
+ <label class="form-control header-search-wrapper js-chromeless-input-container">
+ <div class="header-search-scope">This repository</div>
+ <input type="text"
+ class="form-control header-search-input js-site-search-focus js-site-search-field is-clearable"
+ data-hotkey="s"
+ name="q"
+ placeholder="Search"
+ aria-label="Search this repository"
+ data-unscoped-placeholder="Search GitHub"
+ data-scoped-placeholder="Search"
+ autocapitalize="off">
+ </label>
+</form></div>
+
+
+ <ul class="header-nav left" role="navigation">
+ <li class="header-nav-item">
+ <a href="/pulls" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:pulls context:user" data-hotkey="g p" data-selected-links="/pulls /pulls/assigned /pulls/mentioned /pulls">
+ Pull requests
+</a> </li>
+ <li class="header-nav-item">
+ <a href="/issues" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:issues context:user" data-hotkey="g i" data-selected-links="/issues /issues/assigned /issues/mentioned /issues">
+ Issues
+</a> </li>
+ <li class="header-nav-item">
+ <a class="header-nav-link" href="https://gist.github.com/" data-ga-click="Header, go to gist, text:gist">Gist</a>
+ </li>
+ </ul>
+
+
+<ul class="header-nav user-nav right" id="user-links">
+ <li class="header-nav-item">
+
+ <a href="/notifications" aria-label="You have unread notifications" class="header-nav-link notification-indicator tooltipped tooltipped-s js-socket-channel js-notification-indicator" data-channel="tenant:1:notification-changed:7079598" data-ga-click="Header, go to notifications, icon:unread" data-hotkey="g n">
+ <span class="mail-status unread"></span>
+ <svg aria-hidden="true" class="octicon octicon-bell" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M14 12v1H0v-1l.73-.58c.77-.77.81-2.55 1.19-4.42C2.69 3.23 6 2 6 2c0-.55.45-1 1-1s1 .45 1 1c0 0 3.39 1.23 4.16 5 .38 1.88.42 3.66 1.19 4.42l.66.58H14zm-7 4c1.11 0 2-.89 2-2H5c0 1.11.89 2 2 2z"></path></svg>
+</a>
+ </li>
+
+ <li class="header-nav-item dropdown js-menu-container">
+ <a class="header-nav-link tooltipped tooltipped-s js-menu-target" href="/new"
+ aria-label="Create new…"
+ data-ga-click="Header, create new, icon:add">
+ <svg aria-hidden="true" class="octicon octicon-plus left" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 9H7v5H5V9H0V7h5V2h2v5h5z"></path></svg>
+ <span class="dropdown-caret"></span>
+ </a>
+
+ <div class="dropdown-menu-content js-menu-content">
+ <ul class="dropdown-menu dropdown-menu-sw">
+
+<a class="dropdown-item" href="/new" data-ga-click="Header, create new repository">
+ New repository
+</a>
+
+ <a class="dropdown-item" href="/new/import" data-ga-click="Header, import a repository">
+ Import repository
+ </a>
+
+
+ <a class="dropdown-item" href="/organizations/new" data-ga-click="Header, create new organization">
+ New organization
+ </a>
+
+
+
+
+ </ul>
+ </div>
+ </li>
+
+ <li class="header-nav-item dropdown js-menu-container">
+ <a class="header-nav-link name tooltipped tooltipped-sw js-menu-target" href="/dthom"
+ aria-label="View profile and more"
+ data-ga-click="Header, show menu, icon:avatar">
+ <img alt="@dthom" class="avatar" height="20" src="https://avatars3.githubusercontent.com/u/7079598?v=3&amp;s=40" width="20" />
+ <span class="dropdown-caret"></span>
+ </a>
+
+ <div class="dropdown-menu-content js-menu-content">
+ <div class="dropdown-menu dropdown-menu-sw">
+ <div class="dropdown-header header-nav-current-user css-truncate">
+ Signed in as <strong class="css-truncate-target">dthom</strong>
+ </div>
+
+ <div class="dropdown-divider"></div>
+
+ <a class="dropdown-item" href="/dthom" data-ga-click="Header, go to profile, text:your profile">
+ Your profile
+ </a>
+ <a class="dropdown-item" href="/stars" data-ga-click="Header, go to starred repos, text:your stars">
+ Your stars
+ </a>
+ <a class="dropdown-item" href="/explore" data-ga-click="Header, go to explore, text:explore">
+ Explore
+ </a>
+ <a class="dropdown-item" href="/integrations" data-ga-click="Header, go to integrations, text:integrations">
+ Integrations
+ </a>
+ <a class="dropdown-item" href="https://help.github.com" data-ga-click="Header, go to help, text:help">
+ Help
+ </a>
+
+
+ <div class="dropdown-divider"></div>
+
+ <a class="dropdown-item" href="/settings/profile" data-ga-click="Header, go to settings, icon:settings">
+ Settings
+ </a>
+
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/logout" class="logout-form" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="QasvPUUX7xXJxbueRTPGHaFRv5l+JWuisVLqkabICiFyDAfAL4lReiVkAf3Q4beTs4f/7+qunRtQTu+QCn0REQ==" /></div>
+ <button class="dropdown-item dropdown-signout" data-ga-click="Header, sign out, icon:logout">
+ Sign out
+ </button>
+</form> </div>
+ </div>
+ </li>
+</ul>
+
+
+
+ </div>
+</div>
+
+
+
+
+
+ <div id="start-of-content" class="accessibility-aid"></div>
+
+ <div id="js-flash-container">
+</div>
+
+
+ <div role="main">
+ <div itemscope itemtype="http://schema.org/SoftwareSourceCode">
+ <div id="js-repo-pjax-container" data-pjax-container>
+
+<div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav">
+ <div class="container repohead-details-container">
+
+
+
+<ul class="pagehead-actions">
+
+ <li>
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/notifications/subscribe" class="js-social-container" data-autosubmit="true" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="0PjKXfYY2nrJFBmqZApQPwnPGJLis6uz/l3W/ByqSzLOJ1SPIaveU2xkv+0pdnwP6vrz8X0aVZmzrmnYO9gE8w==" /></div> <input class="form-control" id="repository_id" name="repository_id" type="hidden" value="27342779" />
+
+ <div class="select-menu js-menu-container js-select-menu">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/subscription"
+ class="btn btn-sm btn-with-count select-menu-button js-menu-target" role="button" tabindex="0" aria-haspopup="true"
+ data-ga-click="Repository, click Watch settings, action:blob#show">
+ <span class="js-select-button">
+ <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"></path></svg>
+ Unwatch
+ </span>
+ </a>
+ <a class="social-count js-social-count" href="/rebirthmonkey/rebirthmonkey.github.io/watchers">
+ 2
+ </a>
+
+ <div class="select-menu-modal-holder">
+ <div class="select-menu-modal subscription-menu-modal js-menu-content" aria-hidden="true">
+ <div class="select-menu-header js-navigation-enable" tabindex="-1">
+ <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
+ <span class="select-menu-title">Notifications</span>
+ </div>
+
+ <div class="select-menu-list js-navigation-container" role="menu">
+
+ <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <div class="select-menu-item-text">
+ <input id="do_included" name="do" type="radio" value="included" />
+ <span class="select-menu-item-heading">Not watching</span>
+ <span class="description">Be notified when participating or @mentioned.</span>
+ <span class="js-select-button-text hidden-select-button-text">
+ <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"></path></svg>
+ Watch
+ </span>
+ </div>
+ </div>
+
+ <div class="select-menu-item js-navigation-item selected" role="menuitem" tabindex="0">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <div class="select-menu-item-text">
+ <input checked="checked" id="do_subscribed" name="do" type="radio" value="subscribed" />
+ <span class="select-menu-item-heading">Watching</span>
+ <span class="description">Be notified of all conversations.</span>
+ <span class="js-select-button-text hidden-select-button-text">
+ <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"></path></svg>
+ Unwatch
+ </span>
+ </div>
+ </div>
+
+ <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <div class="select-menu-item-text">
+ <input id="do_ignore" name="do" type="radio" value="ignore" />
+ <span class="select-menu-item-heading">Ignoring</span>
+ <span class="description">Never be notified.</span>
+ <span class="js-select-button-text hidden-select-button-text">
+ <svg aria-hidden="true" class="octicon octicon-mute" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8 2.81v10.38c0 .67-.81 1-1.28.53L3 10H1c-.55 0-1-.45-1-1V7c0-.55.45-1 1-1h2l3.72-3.72C7.19 1.81 8 2.14 8 2.81zm7.53 3.22l-1.06-1.06-1.97 1.97-1.97-1.97-1.06 1.06L11.44 8 9.47 9.97l1.06 1.06 1.97-1.97 1.97 1.97 1.06-1.06L13.56 8l1.97-1.97z"></path></svg>
+ Stop ignoring
+ </span>
+ </div>
+ </div>
+
+ </div>
+
+ </div>
+ </div>
+ </div>
+</form>
+ </li>
+
+ <li>
+
+ <div class="js-toggler-container js-social-container starring-container ">
+
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/unstar" class="starred" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="7tBaOOr1/fJ8XlAK7Ey3PKZVnUNWoOV9DzHTB6yOVS7C4wfanZu2L3xPEX0uSi5CBQik9GUj/sQplU/85HALrw==" /></div>
+ <button
+ class="btn btn-sm btn-with-count js-toggler-target"
+ aria-label="Unstar this repository" title="Unstar rebirthmonkey/rebirthmonkey.github.io"
+ data-ga-click="Repository, click unstar button, action:blob#show; text:Unstar">
+ <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"></path></svg>
+ Unstar
+ </button>
+ <a class="social-count js-social-count" href="/rebirthmonkey/rebirthmonkey.github.io/stargazers">
+ 0
+ </a>
+</form>
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/star" class="unstarred" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="IV/EDpba4zl8V0EPWZPgRC2f0N5Hq1ImlHW4xvKgrqB5GHQhlDdcPdDEjAdxNEWPOK9dCZ5YakUSxj4pHDPe9g==" /></div>
+ <button
+ class="btn btn-sm btn-with-count js-toggler-target"
+ aria-label="Star this repository" title="Star rebirthmonkey/rebirthmonkey.github.io"
+ data-ga-click="Repository, click star button, action:blob#show; text:Star">
+ <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"></path></svg>
+ Star
+ </button>
+ <a class="social-count js-social-count" href="/rebirthmonkey/rebirthmonkey.github.io/stargazers">
+ 0
+ </a>
+</form> </div>
+
+ </li>
+
+ <li>
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/fork" class="btn-with-count" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="SKhb9VOHnVUe32mocOlsHy4sE/HWWlJDZ8QX4I+BYPBb+/g476Kp0aD5pSFYW3adG+rwO9qmJmXKt5iXKbqi1g==" /></div>
+ <button
+ type="submit"
+ class="btn btn-sm btn-with-count"
+ data-ga-click="Repository, show fork modal, action:blob#show; text:Fork"
+ title="Fork your own copy of rebirthmonkey/rebirthmonkey.github.io to your account"
+ aria-label="Fork your own copy of rebirthmonkey/rebirthmonkey.github.io to your account">
+ <svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
+ Fork
+ </button>
+</form>
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/network" class="social-count">
+ 791
+ </a>
+ </li>
+</ul>
+
+ <h1 class="public ">
+ <svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
+ <span class="author" itemprop="author"><a href="/rebirthmonkey" class="url fn" rel="author">rebirthmonkey</a></span><!--
+--><span class="path-divider">/</span><!--
+--><strong itemprop="name"><a href="/rebirthmonkey/rebirthmonkey.github.io" data-pjax="#js-repo-pjax-container">rebirthmonkey.github.io</a></strong>
+
+ <span class="fork-flag">
+ <span class="text">forked from <a href="/LingxianKong/lingxiankong.github.io">LingxianKong/lingxiankong.github.io</a></span>
+ </span>
+</h1>
+
+ </div>
+ <div class="container">
+
+<nav class="reponav js-repo-nav js-sidenav-container-pjax"
+ itemscope
+ itemtype="http://schema.org/BreadcrumbList"
+ role="navigation"
+ data-pjax="#js-repo-pjax-container">
+
+ <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io" aria-selected="true" class="js-selected-navigation-item selected reponav-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /rebirthmonkey/rebirthmonkey.github.io" itemprop="url">
+ <svg aria-hidden="true" class="octicon octicon-code" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"></path></svg>
+ <span itemprop="name">Code</span>
+ <meta itemprop="position" content="1">
+</a> </span>
+
+
+ <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/pulls" class="js-selected-navigation-item reponav-item" data-hotkey="g p" data-selected-links="repo_pulls /rebirthmonkey/rebirthmonkey.github.io/pulls" itemprop="url">
+ <svg aria-hidden="true" class="octicon octicon-git-pull-request" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
+ <span itemprop="name">Pull requests</span>
+ <span class="counter">0</span>
+ <meta itemprop="position" content="3">
+</a> </span>
+
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/wiki" class="js-selected-navigation-item reponav-item" data-hotkey="g w" data-selected-links="repo_wiki /rebirthmonkey/rebirthmonkey.github.io/wiki">
+ <svg aria-hidden="true" class="octicon octicon-book" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M3 5h4v1H3V5zm0 3h4V7H3v1zm0 2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1 1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45 1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z"></path></svg>
+ Wiki
+</a>
+
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/pulse" class="js-selected-navigation-item reponav-item" data-selected-links="pulse /rebirthmonkey/rebirthmonkey.github.io/pulse">
+ <svg aria-hidden="true" class="octicon octicon-pulse" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8z"></path></svg>
+ Pulse
+</a>
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/graphs" class="js-selected-navigation-item reponav-item" data-selected-links="repo_graphs repo_contributors /rebirthmonkey/rebirthmonkey.github.io/graphs">
+ <svg aria-hidden="true" class="octicon octicon-graph" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"></path></svg>
+ Graphs
+</a>
+
+</nav>
+
+ </div>
+</div>
+
+<div class="container new-discussion-timeline experiment-repo-nav">
+ <div class="repository-content">
+
+
+
+<a href="/rebirthmonkey/rebirthmonkey.github.io/blob/b7338020dfb0da5149ad5be75538a1504cb203d5/images/moon/moon_infra.png" class="hidden js-permalink-shortcut" data-hotkey="y">Permalink</a>
+
+<!-- blob contrib key: blob_contributors:v21:d6e7e0f73f6d3fec20fc3b81033b2a06 -->
+
+<div class="file-navigation js-zeroclipboard-container">
+
+<div class="select-menu branch-select-menu js-menu-container js-select-menu left">
+ <button class="btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
+
+ type="button" aria-label="Switch branches or tags" tabindex="0" aria-haspopup="true">
+ <i>Branch:</i>
+ <span class="js-select-button css-truncate-target">master</span>
+ </button>
+
+ <div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax aria-hidden="true">
+
+ <div class="select-menu-modal">
+ <div class="select-menu-header">
+ <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
+ <span class="select-menu-title">Switch branches/tags</span>
+ </div>
+
+ <div class="select-menu-filters">
+ <div class="select-menu-text-filter">
+ <input type="text" aria-label="Find or create a branch…" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Find or create a branch…">
+ </div>
+ <div class="select-menu-tabs">
+ <ul>
+ <li class="select-menu-tab">
+ <a href="#" data-tab-filter="branches" data-filter-placeholder="Find or create a branch…" class="js-select-menu-tab" role="tab">Branches</a>
+ </li>
+ <li class="select-menu-tab">
+ <a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+
+ <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
+
+ <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
+
+
+ <a class="select-menu-item js-navigation-item js-navigation-open selected"
+ href="/rebirthmonkey/rebirthmonkey.github.io/blob/master/images/moon/moon_infra.png"
+ data-name="master"
+ data-skip-pjax="true"
+ rel="nofollow">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
+ master
+ </span>
+ </a>
+ <a class="select-menu-item js-navigation-item js-navigation-open "
+ href="/rebirthmonkey/rebirthmonkey.github.io/blob/thomas/images/moon/moon_infra.png"
+ data-name="thomas"
+ data-skip-pjax="true"
+ rel="nofollow">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
+ thomas
+ </span>
+ </a>
+ </div>
+
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/branches" class="js-create-branch select-menu-item select-menu-new-item-form js-navigation-item js-new-item-form" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="ajzHGnzTPnBsy9DplFhjKroduVRrybgWFrVxlGhK6hffJa8w1FRrRdykwhMAhNItdOTF7eLG7NQnPA3ePZpqFA==" /></div>
+ <svg aria-hidden="true" class="octicon octicon-git-branch select-menu-item-icon" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path d="M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
+ <div class="select-menu-item-text">
+ <span class="select-menu-item-heading">Create branch: <span class="js-new-item-name"></span></span>
+ <span class="description">from ‘master’</span>
+ </div>
+ <input type="hidden" name="name" id="name" class="js-new-item-value">
+ <input type="hidden" name="branch" id="branch" value="master">
+ <input type="hidden" name="path" id="path" value="images/moon/moon_infra.png">
+</form>
+ </div>
+
+ <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
+ <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
+
+
+ </div>
+
+ <div class="select-menu-no-results">Nothing to show</div>
+ </div>
+
+ </div>
+ </div>
+</div>
+
+ <div class="btn-group right">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/find/master"
+ class="js-pjax-capture-input btn btn-sm"
+ data-pjax
+ data-hotkey="t">
+ Find file
+ </a>
+ <button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm zeroclipboard-button tooltipped tooltipped-s" data-copied-hint="Copied!" type="button">Copy path</button>
+ </div>
+ <div class="breadcrumb js-zeroclipboard-target">
+ <span class="repo-root js-repo-root"><span class="js-path-segment"><a href="/rebirthmonkey/rebirthmonkey.github.io"><span>rebirthmonkey.github.io</span></a></span></span><span class="separator">/</span><span class="js-path-segment"><a href="/rebirthmonkey/rebirthmonkey.github.io/tree/master/images"><span>images</span></a></span><span class="separator">/</span><span class="js-path-segment"><a href="/rebirthmonkey/rebirthmonkey.github.io/tree/master/images/moon"><span>moon</span></a></span><span class="separator">/</span><strong class="final-path">moon_infra.png</strong>
+ </div>
+</div>
+
+<include-fragment class="commit-tease" src="/rebirthmonkey/rebirthmonkey.github.io/contributors/master/images/moon/moon_infra.png">
+ <div>
+ Fetching contributors&hellip;
+ </div>
+
+ <div class="commit-tease-contributors">
+ <img alt="" class="loader-loading left" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32-EAF2F5.gif" width="16" />
+ <span class="loader-error">Cannot retrieve contributors at this time</span>
+ </div>
+</include-fragment>
+<div class="file">
+ <div class="file-header">
+ <div class="file-actions">
+
+ <div class="btn-group">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/raw/master/images/moon/moon_infra.png" class="btn btn-sm " id="raw-url">Download</a>
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/commits/master/images/moon/moon_infra.png" class="btn btn-sm " rel="nofollow">History</a>
+ </div>
+
+
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/delete/master/images/moon/moon_infra.png" class="inline-form" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="NwlL7/4Y/BZXN6yKfqKWzFrSTfUky3uuN7+vV99QVYUF9SnTQjs9u9LoiCbsnQr+hbUOkwCdCarzQL2S2Ka1Cw==" /></div>
+ <button class="btn-octicon btn-octicon-danger tooltipped tooltipped-nw" type="submit"
+ aria-label="Delete this file" data-disable-with>
+ <svg aria-hidden="true" class="octicon octicon-trashcan" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"></path></svg>
+ </button>
+</form> </div>
+
+ <div class="file-info">
+ 229 KB
+ </div>
+</div>
+
+
+
+ <div itemprop="text" class="blob-wrapper data type-text">
+ <div class="image">
+ <span class="border-wrap"><img src="/rebirthmonkey/rebirthmonkey.github.io/blob/master/images/moon/moon_infra.png?raw=true" alt="moon_infra.png"></span>
+ </div>
+ </div>
+
+</div>
+
+<button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="hidden">Jump to Line</button>
+<div id="jump-to-line" style="display:none">
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
+ <input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" aria-label="Jump to line" autofocus>
+ <button type="submit" class="btn">Go</button>
+</form></div>
+
+ </div>
+ <div class="modal-backdrop js-touch-events"></div>
+</div>
+
+
+ </div>
+ </div>
+
+ </div>
+
+ <div class="container site-footer-container">
+ <div class="site-footer" role="contentinfo">
+ <ul class="site-footer-links right">
+ <li><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact GitHub</a></li>
+ <li><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
+ <li><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
+ <li><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
+ <li><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
+ <li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li>
+
+ </ul>
+
+ <a href="https://github.com" aria-label="Homepage" class="site-footer-mark" title="GitHub">
+ <svg aria-hidden="true" class="octicon octicon-mark-github" height="24" version="1.1" viewBox="0 0 16 16" width="24"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
+</a>
+ <ul class="site-footer-links">
+ <li>&copy; 2016 <span title="0.07656s from github-fe119-cp1-prd.iad.github.net">GitHub</span>, Inc.</li>
+ <li><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li>
+ <li><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li>
+ <li><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li>
+ <li><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
+ <li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li>
+ </ul>
+ </div>
+</div>
+
+
+
+
+
+ <div id="ajax-error-message" class="ajax-error-message flash flash-error">
+ <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"></path></svg>
+ <button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
+ <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
+ </button>
+ You can't perform that action at this time.
+ </div>
+
+
+
+ <script crossorigin="anonymous" integrity="sha256-79uFEGG7eTPQ5An4vmf2rkg6L6hhK5E64meKpKv0Vpo=" src="https://assets-cdn.github.com/assets/frameworks-efdb851061bb7933d0e409f8be67f6ae483a2fa8612b913ae2678aa4abf4569a.js"></script>
+ <script async="async" crossorigin="anonymous" integrity="sha256-0J0EHAuyZXj0lxtQgD29uk8ZpjJnDJLcL7L5kF5DVjY=" src="https://assets-cdn.github.com/assets/github-d09d041c0bb26578f4971b50803dbdba4f19a632670c92dc2fb2f9905e435636.js"></script>
+
+
+
+
+
+
+ <div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner hidden">
+ <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"></path></svg>
+ <span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
+ <span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
+ </div>
+ <div class="facebox" id="facebox" style="display:none;">
+ <div class="facebox-popup">
+ <div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
+ </div>
+ <button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
+ <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
+ </button>
+ </div>
+</div>
+
+ </body>
+</html>
+
diff --git a/docs/img/policy_engine.png b/docs/img/policy_engine.png
new file mode 100644
index 00000000..bda00d20
--- /dev/null
+++ b/docs/img/policy_engine.png
@@ -0,0 +1,669 @@
+
+
+
+
+<!DOCTYPE html>
+<html lang="en" class=" is-copy-enabled">
+ <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#">
+ <meta charset='utf-8'>
+
+
+ <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-be4c6e0e479a2d4d0eb3159c8772b5bfc4aa39831cb28f5f92cc2e448d93eaa1.css" integrity="sha256-vkxuDkeaLU0OsxWch3K1v8SqOYMcso9fkswuRI2T6qE=" media="all" rel="stylesheet" />
+ <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-2172647018381485dc3021817136b6cbb4c7f1a47f195b528c5c72f9260f4271.css" integrity="sha256-IXJkcBg4FIXcMCGBcTa2y7TH8aR/GVtSjFxy+SYPQnE=" media="all" rel="stylesheet" />
+
+
+
+
+
+ <link as="script" href="https://assets-cdn.github.com/assets/frameworks-efdb851061bb7933d0e409f8be67f6ae483a2fa8612b913ae2678aa4abf4569a.js" rel="preload" />
+
+ <link as="script" href="https://assets-cdn.github.com/assets/github-d09d041c0bb26578f4971b50803dbdba4f19a632670c92dc2fb2f9905e435636.js" rel="preload" />
+
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta http-equiv="Content-Language" content="en">
+ <meta name="viewport" content="width=device-width">
+
+ <title>rebirthmonkey.github.io/policy_engine.png at master · rebirthmonkey/rebirthmonkey.github.io</title>
+ <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
+ <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png">
+ <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
+ <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
+ <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
+ <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
+ <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
+ <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
+ <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
+ <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
+ <meta property="fb:app_id" content="1401488693436528">
+
+ <meta content="https://avatars3.githubusercontent.com/u/5707752?v=3&amp;s=400" name="twitter:image:src" /><meta content="@github" name="twitter:site" /><meta content="summary" name="twitter:card" /><meta content="rebirthmonkey/rebirthmonkey.github.io" name="twitter:title" /><meta content="rebirthmonkey.github.io - Wukong&#39;s Bloc" name="twitter:description" />
+ <meta content="https://avatars3.githubusercontent.com/u/5707752?v=3&amp;s=400" property="og:image" /><meta content="GitHub" property="og:site_name" /><meta content="object" property="og:type" /><meta content="rebirthmonkey/rebirthmonkey.github.io" property="og:title" /><meta content="https://github.com/rebirthmonkey/rebirthmonkey.github.io" property="og:url" /><meta content="rebirthmonkey.github.io - Wukong&#39;s Bloc" property="og:description" />
+ <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
+ <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
+ <link rel="assets" href="https://assets-cdn.github.com/">
+ <link rel="web-socket" href="wss://live.github.com/_sockets/NzA3OTU5ODo2OWM0Y2RhNGM0NTcwNGQ4MmZiYTg4OTgzMDJhMjZhZjpkMmI2OTkyMjJmYzhmNGY3MGQzMzVlYTlhMGFhZmQyNjUxMDMxZGZkZmVkYWRjNzYyZTgyYTQ0N2QyOWM4NDM5--c96ede35cd7cc8ecc1718abf2997a6c5919a664a">
+ <meta name="pjax-timeout" content="1000">
+ <link rel="sudo-modal" href="/sessions/sudo_modal">
+ <meta name="request-id" content="C202CA51:1FEC:D7C4AB:57AC8683" data-pjax-transient>
+
+ <meta name="msapplication-TileImage" content="/windows-tile.png">
+ <meta name="msapplication-TileColor" content="#ffffff">
+ <meta name="selected-link" value="repo_source" data-pjax-transient>
+
+ <meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
+<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
+ <meta name="google-analytics" content="UA-3769691-2">
+
+<meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" /><meta content="C202CA51:1FEC:D7C4AB:57AC8683" name="octolytics-dimension-request_id" /><meta content="7079598" name="octolytics-actor-id" /><meta content="dthom" name="octolytics-actor-login" /><meta content="9c4e325d50d942c182d7c2694b1e2606da1e566788bcf5a9b6b9680a957dfb6a" name="octolytics-actor-hash" />
+<meta content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-pjax-transient="true" name="analytics-location" />
+
+
+
+ <meta class="js-ga-set" name="dimension1" content="Logged In">
+
+
+
+ <meta name="hostname" content="github.com">
+ <meta name="user-login" content="dthom">
+
+ <meta name="expected-hostname" content="github.com">
+ <meta name="js-proxy-site-detection-payload" content="MjkzYWRiMDc3NjBiNTM2MTYzMzMwYjZkMGVmYzg2MzllNTBiYWFkNzQ5NTRiNTZlZWVlZGNkOWNkMzQ2YTExMHx7InJlbW90ZV9hZGRyZXNzIjoiMTk0LjIuMjAyLjgxIiwicmVxdWVzdF9pZCI6IkMyMDJDQTUxOjFGRUM6RDdDNEFCOjU3QUM4NjgzIiwidGltZXN0YW1wIjoxNDcwOTI0NDE5fQ==">
+
+
+ <link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#4078c0">
+ <link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">
+
+ <meta name="html-safe-nonce" content="f8d22d1ea86c94ab8c05e89327ece5451ac180d1">
+ <meta content="4575b3e17adfc8057914e1edc819062b7be0bf8f" name="form-nonce" />
+
+ <meta http-equiv="x-pjax-version" content="15d2202b74ada67a977cd0b44d4b4c5f">
+
+
+
+ <meta name="description" content="rebirthmonkey.github.io - Wukong&#39;s Bloc">
+ <meta name="go-import" content="github.com/rebirthmonkey/rebirthmonkey.github.io git https://github.com/rebirthmonkey/rebirthmonkey.github.io.git">
+
+ <meta content="5707752" name="octolytics-dimension-user_id" /><meta content="rebirthmonkey" name="octolytics-dimension-user_login" /><meta content="27342779" name="octolytics-dimension-repository_id" /><meta content="rebirthmonkey/rebirthmonkey.github.io" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="true" name="octolytics-dimension-repository_is_fork" /><meta content="15397768" name="octolytics-dimension-repository_parent_id" /><meta content="LingxianKong/lingxiankong.github.io" name="octolytics-dimension-repository_parent_nwo" /><meta content="2843336" name="octolytics-dimension-repository_network_root_id" /><meta content="beiyuu/Github-Pages-Example" name="octolytics-dimension-repository_network_root_nwo" />
+ <link href="https://github.com/rebirthmonkey/rebirthmonkey.github.io/commits/master.atom" rel="alternate" title="Recent Commits to rebirthmonkey.github.io:master" type="application/atom+xml">
+
+
+ <link rel="canonical" href="https://github.com/rebirthmonkey/rebirthmonkey.github.io/blob/master/images/moon/policy_engine.png" data-pjax-transient>
+ </head>
+
+
+ <body class="logged-in env-production linux vis-public fork page-blob">
+ <div id="js-pjax-loader-bar" class="pjax-loader-bar"><div class="progress"></div></div>
+ <a href="#start-of-content" tabindex="1" class="accessibility-aid js-skip-to-content">Skip to content</a>
+
+
+
+
+
+
+
+ <div class="header header-logged-in true" role="banner">
+ <div class="container clearfix">
+
+ <a class="header-logo-invertocat" href="https://github.com/" data-hotkey="g d" aria-label="Homepage" data-ga-click="Header, go to dashboard, icon:logo">
+ <svg aria-hidden="true" class="octicon octicon-mark-github" height="28" version="1.1" viewBox="0 0 16 16" width="28"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
+</a>
+
+
+ <div class="header-search scoped-search site-scoped-search js-site-search" role="search">
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/search" class="js-site-search-form" data-scoped-search-url="/rebirthmonkey/rebirthmonkey.github.io/search" data-unscoped-search-url="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
+ <label class="form-control header-search-wrapper js-chromeless-input-container">
+ <div class="header-search-scope">This repository</div>
+ <input type="text"
+ class="form-control header-search-input js-site-search-focus js-site-search-field is-clearable"
+ data-hotkey="s"
+ name="q"
+ placeholder="Search"
+ aria-label="Search this repository"
+ data-unscoped-placeholder="Search GitHub"
+ data-scoped-placeholder="Search"
+ autocapitalize="off">
+ </label>
+</form></div>
+
+
+ <ul class="header-nav left" role="navigation">
+ <li class="header-nav-item">
+ <a href="/pulls" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:pulls context:user" data-hotkey="g p" data-selected-links="/pulls /pulls/assigned /pulls/mentioned /pulls">
+ Pull requests
+</a> </li>
+ <li class="header-nav-item">
+ <a href="/issues" class="js-selected-navigation-item header-nav-link" data-ga-click="Header, click, Nav menu - item:issues context:user" data-hotkey="g i" data-selected-links="/issues /issues/assigned /issues/mentioned /issues">
+ Issues
+</a> </li>
+ <li class="header-nav-item">
+ <a class="header-nav-link" href="https://gist.github.com/" data-ga-click="Header, go to gist, text:gist">Gist</a>
+ </li>
+ </ul>
+
+
+<ul class="header-nav user-nav right" id="user-links">
+ <li class="header-nav-item">
+
+ <a href="/notifications" aria-label="You have unread notifications" class="header-nav-link notification-indicator tooltipped tooltipped-s js-socket-channel js-notification-indicator" data-channel="tenant:1:notification-changed:7079598" data-ga-click="Header, go to notifications, icon:unread" data-hotkey="g n">
+ <span class="mail-status unread"></span>
+ <svg aria-hidden="true" class="octicon octicon-bell" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M14 12v1H0v-1l.73-.58c.77-.77.81-2.55 1.19-4.42C2.69 3.23 6 2 6 2c0-.55.45-1 1-1s1 .45 1 1c0 0 3.39 1.23 4.16 5 .38 1.88.42 3.66 1.19 4.42l.66.58H14zm-7 4c1.11 0 2-.89 2-2H5c0 1.11.89 2 2 2z"></path></svg>
+</a>
+ </li>
+
+ <li class="header-nav-item dropdown js-menu-container">
+ <a class="header-nav-link tooltipped tooltipped-s js-menu-target" href="/new"
+ aria-label="Create new…"
+ data-ga-click="Header, create new, icon:add">
+ <svg aria-hidden="true" class="octicon octicon-plus left" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 9H7v5H5V9H0V7h5V2h2v5h5z"></path></svg>
+ <span class="dropdown-caret"></span>
+ </a>
+
+ <div class="dropdown-menu-content js-menu-content">
+ <ul class="dropdown-menu dropdown-menu-sw">
+
+<a class="dropdown-item" href="/new" data-ga-click="Header, create new repository">
+ New repository
+</a>
+
+ <a class="dropdown-item" href="/new/import" data-ga-click="Header, import a repository">
+ Import repository
+ </a>
+
+
+ <a class="dropdown-item" href="/organizations/new" data-ga-click="Header, create new organization">
+ New organization
+ </a>
+
+
+
+
+ </ul>
+ </div>
+ </li>
+
+ <li class="header-nav-item dropdown js-menu-container">
+ <a class="header-nav-link name tooltipped tooltipped-sw js-menu-target" href="/dthom"
+ aria-label="View profile and more"
+ data-ga-click="Header, show menu, icon:avatar">
+ <img alt="@dthom" class="avatar" height="20" src="https://avatars3.githubusercontent.com/u/7079598?v=3&amp;s=40" width="20" />
+ <span class="dropdown-caret"></span>
+ </a>
+
+ <div class="dropdown-menu-content js-menu-content">
+ <div class="dropdown-menu dropdown-menu-sw">
+ <div class="dropdown-header header-nav-current-user css-truncate">
+ Signed in as <strong class="css-truncate-target">dthom</strong>
+ </div>
+
+ <div class="dropdown-divider"></div>
+
+ <a class="dropdown-item" href="/dthom" data-ga-click="Header, go to profile, text:your profile">
+ Your profile
+ </a>
+ <a class="dropdown-item" href="/stars" data-ga-click="Header, go to starred repos, text:your stars">
+ Your stars
+ </a>
+ <a class="dropdown-item" href="/explore" data-ga-click="Header, go to explore, text:explore">
+ Explore
+ </a>
+ <a class="dropdown-item" href="/integrations" data-ga-click="Header, go to integrations, text:integrations">
+ Integrations
+ </a>
+ <a class="dropdown-item" href="https://help.github.com" data-ga-click="Header, go to help, text:help">
+ Help
+ </a>
+
+
+ <div class="dropdown-divider"></div>
+
+ <a class="dropdown-item" href="/settings/profile" data-ga-click="Header, go to settings, icon:settings">
+ Settings
+ </a>
+
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/logout" class="logout-form" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="UxYHVHp+Mx88b8qF/3kAcHTrY0F4aPiMwnicj8q0SYbeSoTcC9jjDCS7ATa950+N5USqSv2HMgk43bVru+6yBQ==" /></div>
+ <button class="dropdown-item dropdown-signout" data-ga-click="Header, sign out, icon:logout">
+ Sign out
+ </button>
+</form> </div>
+ </div>
+ </li>
+</ul>
+
+
+
+ </div>
+</div>
+
+
+
+
+
+ <div id="start-of-content" class="accessibility-aid"></div>
+
+ <div id="js-flash-container">
+</div>
+
+
+ <div role="main">
+ <div itemscope itemtype="http://schema.org/SoftwareSourceCode">
+ <div id="js-repo-pjax-container" data-pjax-container>
+
+<div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav">
+ <div class="container repohead-details-container">
+
+
+
+<ul class="pagehead-actions">
+
+ <li>
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/notifications/subscribe" class="js-social-container" data-autosubmit="true" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="pXmafHyT7vfBCb06RMS0rHwr7xWKyFeNxQpTvTCOneLefO+RMxlHILGnyNw+XUsywbTrn/uBOXO+U0Nve+Pd+Q==" /></div> <input class="form-control" id="repository_id" name="repository_id" type="hidden" value="27342779" />
+
+ <div class="select-menu js-menu-container js-select-menu">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/subscription"
+ class="btn btn-sm btn-with-count select-menu-button js-menu-target" role="button" tabindex="0" aria-haspopup="true"
+ data-ga-click="Repository, click Watch settings, action:blob#show">
+ <span class="js-select-button">
+ <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"></path></svg>
+ Unwatch
+ </span>
+ </a>
+ <a class="social-count js-social-count" href="/rebirthmonkey/rebirthmonkey.github.io/watchers">
+ 2
+ </a>
+
+ <div class="select-menu-modal-holder">
+ <div class="select-menu-modal subscription-menu-modal js-menu-content" aria-hidden="true">
+ <div class="select-menu-header js-navigation-enable" tabindex="-1">
+ <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
+ <span class="select-menu-title">Notifications</span>
+ </div>
+
+ <div class="select-menu-list js-navigation-container" role="menu">
+
+ <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <div class="select-menu-item-text">
+ <input id="do_included" name="do" type="radio" value="included" />
+ <span class="select-menu-item-heading">Not watching</span>
+ <span class="description">Be notified when participating or @mentioned.</span>
+ <span class="js-select-button-text hidden-select-button-text">
+ <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"></path></svg>
+ Watch
+ </span>
+ </div>
+ </div>
+
+ <div class="select-menu-item js-navigation-item selected" role="menuitem" tabindex="0">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <div class="select-menu-item-text">
+ <input checked="checked" id="do_subscribed" name="do" type="radio" value="subscribed" />
+ <span class="select-menu-item-heading">Watching</span>
+ <span class="description">Be notified of all conversations.</span>
+ <span class="js-select-button-text hidden-select-button-text">
+ <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"></path></svg>
+ Unwatch
+ </span>
+ </div>
+ </div>
+
+ <div class="select-menu-item js-navigation-item " role="menuitem" tabindex="0">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <div class="select-menu-item-text">
+ <input id="do_ignore" name="do" type="radio" value="ignore" />
+ <span class="select-menu-item-heading">Ignoring</span>
+ <span class="description">Never be notified.</span>
+ <span class="js-select-button-text hidden-select-button-text">
+ <svg aria-hidden="true" class="octicon octicon-mute" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8 2.81v10.38c0 .67-.81 1-1.28.53L3 10H1c-.55 0-1-.45-1-1V7c0-.55.45-1 1-1h2l3.72-3.72C7.19 1.81 8 2.14 8 2.81zm7.53 3.22l-1.06-1.06-1.97 1.97-1.97-1.97-1.06 1.06L11.44 8 9.47 9.97l1.06 1.06 1.97-1.97 1.97 1.97 1.06-1.06L13.56 8l1.97-1.97z"></path></svg>
+ Stop ignoring
+ </span>
+ </div>
+ </div>
+
+ </div>
+
+ </div>
+ </div>
+ </div>
+</form>
+ </li>
+
+ <li>
+
+ <div class="js-toggler-container js-social-container starring-container ">
+
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/unstar" class="starred" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="tc3x1rdEcEVMYShzB+HlPb0ZG4mMCDCU3PN1bqzOO4GTeS1nnYHuwSIEIBxcOsW7XlB9kzIxjNq+RpbUQhx8KA==" /></div>
+ <button
+ class="btn btn-sm btn-with-count js-toggler-target"
+ aria-label="Unstar this repository" title="Unstar rebirthmonkey/rebirthmonkey.github.io"
+ data-ga-click="Repository, click unstar button, action:blob#show; text:Unstar">
+ <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"></path></svg>
+ Unstar
+ </button>
+ <a class="social-count js-social-count" href="/rebirthmonkey/rebirthmonkey.github.io/stargazers">
+ 0
+ </a>
+</form>
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/star" class="unstarred" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="hcvuuYY27VdE4BmobEe5rMcTfxMc+9hG6hEbkDrsHB2mHYfhG4w54g6kKrBSNJQGl2lJaRWugVaA3NH/DX/6tg==" /></div>
+ <button
+ class="btn btn-sm btn-with-count js-toggler-target"
+ aria-label="Star this repository" title="Star rebirthmonkey/rebirthmonkey.github.io"
+ data-ga-click="Repository, click star button, action:blob#show; text:Star">
+ <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"></path></svg>
+ Star
+ </button>
+ <a class="social-count js-social-count" href="/rebirthmonkey/rebirthmonkey.github.io/stargazers">
+ 0
+ </a>
+</form> </div>
+
+ </li>
+
+ <li>
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/fork" class="btn-with-count" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="WJN/V8N7WKdfWIbju1uJacJQV6qbkY3AzHNn/MohXy4cWKjJ7EelwLnTq50mEOAZ5NnREv8qRW7enFYJQghhEw==" /></div>
+ <button
+ type="submit"
+ class="btn btn-sm btn-with-count"
+ data-ga-click="Repository, show fork modal, action:blob#show; text:Fork"
+ title="Fork your own copy of rebirthmonkey/rebirthmonkey.github.io to your account"
+ aria-label="Fork your own copy of rebirthmonkey/rebirthmonkey.github.io to your account">
+ <svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
+ Fork
+ </button>
+</form>
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/network" class="social-count">
+ 791
+ </a>
+ </li>
+</ul>
+
+ <h1 class="public ">
+ <svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
+ <span class="author" itemprop="author"><a href="/rebirthmonkey" class="url fn" rel="author">rebirthmonkey</a></span><!--
+--><span class="path-divider">/</span><!--
+--><strong itemprop="name"><a href="/rebirthmonkey/rebirthmonkey.github.io" data-pjax="#js-repo-pjax-container">rebirthmonkey.github.io</a></strong>
+
+ <span class="fork-flag">
+ <span class="text">forked from <a href="/LingxianKong/lingxiankong.github.io">LingxianKong/lingxiankong.github.io</a></span>
+ </span>
+</h1>
+
+ </div>
+ <div class="container">
+
+<nav class="reponav js-repo-nav js-sidenav-container-pjax"
+ itemscope
+ itemtype="http://schema.org/BreadcrumbList"
+ role="navigation"
+ data-pjax="#js-repo-pjax-container">
+
+ <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io" aria-selected="true" class="js-selected-navigation-item selected reponav-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /rebirthmonkey/rebirthmonkey.github.io" itemprop="url">
+ <svg aria-hidden="true" class="octicon octicon-code" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"></path></svg>
+ <span itemprop="name">Code</span>
+ <meta itemprop="position" content="1">
+</a> </span>
+
+
+ <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/pulls" class="js-selected-navigation-item reponav-item" data-hotkey="g p" data-selected-links="repo_pulls /rebirthmonkey/rebirthmonkey.github.io/pulls" itemprop="url">
+ <svg aria-hidden="true" class="octicon octicon-git-pull-request" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
+ <span itemprop="name">Pull requests</span>
+ <span class="counter">0</span>
+ <meta itemprop="position" content="3">
+</a> </span>
+
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/wiki" class="js-selected-navigation-item reponav-item" data-hotkey="g w" data-selected-links="repo_wiki /rebirthmonkey/rebirthmonkey.github.io/wiki">
+ <svg aria-hidden="true" class="octicon octicon-book" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M3 5h4v1H3V5zm0 3h4V7H3v1zm0 2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1 1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45 1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z"></path></svg>
+ Wiki
+</a>
+
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/pulse" class="js-selected-navigation-item reponav-item" data-selected-links="pulse /rebirthmonkey/rebirthmonkey.github.io/pulse">
+ <svg aria-hidden="true" class="octicon octicon-pulse" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8z"></path></svg>
+ Pulse
+</a>
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/graphs" class="js-selected-navigation-item reponav-item" data-selected-links="repo_graphs repo_contributors /rebirthmonkey/rebirthmonkey.github.io/graphs">
+ <svg aria-hidden="true" class="octicon octicon-graph" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"></path></svg>
+ Graphs
+</a>
+
+</nav>
+
+ </div>
+</div>
+
+<div class="container new-discussion-timeline experiment-repo-nav">
+ <div class="repository-content">
+
+
+
+<a href="/rebirthmonkey/rebirthmonkey.github.io/blob/b7338020dfb0da5149ad5be75538a1504cb203d5/images/moon/policy_engine.png" class="hidden js-permalink-shortcut" data-hotkey="y">Permalink</a>
+
+<!-- blob contrib key: blob_contributors:v21:d68dc7f4c44a8aecb802ab172c56dffb -->
+
+<div class="file-navigation js-zeroclipboard-container">
+
+<div class="select-menu branch-select-menu js-menu-container js-select-menu left">
+ <button class="btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
+
+ type="button" aria-label="Switch branches or tags" tabindex="0" aria-haspopup="true">
+ <i>Branch:</i>
+ <span class="js-select-button css-truncate-target">master</span>
+ </button>
+
+ <div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax aria-hidden="true">
+
+ <div class="select-menu-modal">
+ <div class="select-menu-header">
+ <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
+ <span class="select-menu-title">Switch branches/tags</span>
+ </div>
+
+ <div class="select-menu-filters">
+ <div class="select-menu-text-filter">
+ <input type="text" aria-label="Find or create a branch…" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Find or create a branch…">
+ </div>
+ <div class="select-menu-tabs">
+ <ul>
+ <li class="select-menu-tab">
+ <a href="#" data-tab-filter="branches" data-filter-placeholder="Find or create a branch…" class="js-select-menu-tab" role="tab">Branches</a>
+ </li>
+ <li class="select-menu-tab">
+ <a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+
+ <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
+
+ <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
+
+
+ <a class="select-menu-item js-navigation-item js-navigation-open selected"
+ href="/rebirthmonkey/rebirthmonkey.github.io/blob/master/images/moon/policy_engine.png"
+ data-name="master"
+ data-skip-pjax="true"
+ rel="nofollow">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
+ master
+ </span>
+ </a>
+ <a class="select-menu-item js-navigation-item js-navigation-open "
+ href="/rebirthmonkey/rebirthmonkey.github.io/blob/thomas/images/moon/policy_engine.png"
+ data-name="thomas"
+ data-skip-pjax="true"
+ rel="nofollow">
+ <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"></path></svg>
+ <span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
+ thomas
+ </span>
+ </a>
+ </div>
+
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/branches" class="js-create-branch select-menu-item select-menu-new-item-form js-navigation-item js-new-item-form" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="/RXVpCDEEEBorPTpTTp6jjHxrbjTpGo2iX9UzbiP/D7bKFsSIjTnpHDOzHnnxbpseCWL2X0oOPzczeAV8uQoHQ==" /></div>
+ <svg aria-hidden="true" class="octicon octicon-git-branch select-menu-item-icon" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path d="M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
+ <div class="select-menu-item-text">
+ <span class="select-menu-item-heading">Create branch: <span class="js-new-item-name"></span></span>
+ <span class="description">from ‘master’</span>
+ </div>
+ <input type="hidden" name="name" id="name" class="js-new-item-value">
+ <input type="hidden" name="branch" id="branch" value="master">
+ <input type="hidden" name="path" id="path" value="images/moon/policy_engine.png">
+</form>
+ </div>
+
+ <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
+ <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
+
+
+ </div>
+
+ <div class="select-menu-no-results">Nothing to show</div>
+ </div>
+
+ </div>
+ </div>
+</div>
+
+ <div class="btn-group right">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/find/master"
+ class="js-pjax-capture-input btn btn-sm"
+ data-pjax
+ data-hotkey="t">
+ Find file
+ </a>
+ <button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm zeroclipboard-button tooltipped tooltipped-s" data-copied-hint="Copied!" type="button">Copy path</button>
+ </div>
+ <div class="breadcrumb js-zeroclipboard-target">
+ <span class="repo-root js-repo-root"><span class="js-path-segment"><a href="/rebirthmonkey/rebirthmonkey.github.io"><span>rebirthmonkey.github.io</span></a></span></span><span class="separator">/</span><span class="js-path-segment"><a href="/rebirthmonkey/rebirthmonkey.github.io/tree/master/images"><span>images</span></a></span><span class="separator">/</span><span class="js-path-segment"><a href="/rebirthmonkey/rebirthmonkey.github.io/tree/master/images/moon"><span>moon</span></a></span><span class="separator">/</span><strong class="final-path">policy_engine.png</strong>
+ </div>
+</div>
+
+<include-fragment class="commit-tease" src="/rebirthmonkey/rebirthmonkey.github.io/contributors/master/images/moon/policy_engine.png">
+ <div>
+ Fetching contributors&hellip;
+ </div>
+
+ <div class="commit-tease-contributors">
+ <img alt="" class="loader-loading left" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32-EAF2F5.gif" width="16" />
+ <span class="loader-error">Cannot retrieve contributors at this time</span>
+ </div>
+</include-fragment>
+<div class="file">
+ <div class="file-header">
+ <div class="file-actions">
+
+ <div class="btn-group">
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/raw/master/images/moon/policy_engine.png" class="btn btn-sm " id="raw-url">Download</a>
+ <a href="/rebirthmonkey/rebirthmonkey.github.io/commits/master/images/moon/policy_engine.png" class="btn btn-sm " rel="nofollow">History</a>
+ </div>
+
+
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/rebirthmonkey/rebirthmonkey.github.io/delete/master/images/moon/policy_engine.png" class="inline-form" data-form-nonce="4575b3e17adfc8057914e1edc819062b7be0bf8f" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="4qPnL0QRlHJVtU0P3fCqd8fYOjt7rpIZkgyoZH83VWhb2225iA9qkneJazWof8oQ/squs4UA6V/VuLBshFRfng==" /></div>
+ <button class="btn-octicon btn-octicon-danger tooltipped tooltipped-nw" type="submit"
+ aria-label="Delete this file" data-disable-with>
+ <svg aria-hidden="true" class="octicon octicon-trashcan" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"></path></svg>
+ </button>
+</form> </div>
+
+ <div class="file-info">
+ 19.1 KB
+ </div>
+</div>
+
+
+
+ <div itemprop="text" class="blob-wrapper data type-text">
+ <div class="image">
+ <span class="border-wrap"><img src="/rebirthmonkey/rebirthmonkey.github.io/blob/master/images/moon/policy_engine.png?raw=true" alt="policy_engine.png"></span>
+ </div>
+ </div>
+
+</div>
+
+<button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="hidden">Jump to Line</button>
+<div id="jump-to-line" style="display:none">
+ <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
+ <input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" aria-label="Jump to line" autofocus>
+ <button type="submit" class="btn">Go</button>
+</form></div>
+
+ </div>
+ <div class="modal-backdrop js-touch-events"></div>
+</div>
+
+
+ </div>
+ </div>
+
+ </div>
+
+ <div class="container site-footer-container">
+ <div class="site-footer" role="contentinfo">
+ <ul class="site-footer-links right">
+ <li><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact GitHub</a></li>
+ <li><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
+ <li><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
+ <li><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
+ <li><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
+ <li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li>
+
+ </ul>
+
+ <a href="https://github.com" aria-label="Homepage" class="site-footer-mark" title="GitHub">
+ <svg aria-hidden="true" class="octicon octicon-mark-github" height="24" version="1.1" viewBox="0 0 16 16" width="24"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
+</a>
+ <ul class="site-footer-links">
+ <li>&copy; 2016 <span title="0.10125s from github-fe146-cp1-prd.iad.github.net">GitHub</span>, Inc.</li>
+ <li><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li>
+ <li><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li>
+ <li><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li>
+ <li><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
+ <li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li>
+ </ul>
+ </div>
+</div>
+
+
+
+
+
+ <div id="ajax-error-message" class="ajax-error-message flash flash-error">
+ <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"></path></svg>
+ <button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
+ <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
+ </button>
+ You can't perform that action at this time.
+ </div>
+
+
+
+ <script crossorigin="anonymous" integrity="sha256-79uFEGG7eTPQ5An4vmf2rkg6L6hhK5E64meKpKv0Vpo=" src="https://assets-cdn.github.com/assets/frameworks-efdb851061bb7933d0e409f8be67f6ae483a2fa8612b913ae2678aa4abf4569a.js"></script>
+ <script async="async" crossorigin="anonymous" integrity="sha256-0J0EHAuyZXj0lxtQgD29uk8ZpjJnDJLcL7L5kF5DVjY=" src="https://assets-cdn.github.com/assets/github-d09d041c0bb26578f4971b50803dbdba4f19a632670c92dc2fb2f9905e435636.js"></script>
+
+
+
+
+
+
+ <div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner hidden">
+ <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"></path></svg>
+ <span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
+ <span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
+ </div>
+ <div class="facebox" id="facebox" style="display:none;">
+ <div class="facebox-popup">
+ <div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
+ </div>
+ <button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
+ <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
+ </button>
+ </div>
+</div>
+
+ </body>
+</html>
+
diff --git a/docs/installationprocedure/index.rst b/docs/installationprocedure/index.rst
new file mode 100644
index 00000000..e8528f6d
--- /dev/null
+++ b/docs/installationprocedure/index.rst
@@ -0,0 +1,330 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) ruan.he@orange.com & thomas.duval@orange.com
+
+*****************************
+OPNFV MOON installation guide
+*****************************
+
+.. toctree::
+ :numbered:
+ :maxdepth: 2
+
+
+============
+Introduction
+============
+
+The Moon platform is composed of 3 components :
+* keystone-moon
+* keystonemiddleware-moon
+* python-moonclient
+
+keystone-moon
+=============
+This component replaces the Keystone component of the OpenStack platform.
+All basic functions of the original component were maintained but we add some new functions (specially authorization functions)
+
+keystonemiddleware-moon
+=======================
+This component replaces the KeystoneMiddleware component of the OpenStack platform.
+The main function added was to intercept all actions from Nova and Swift in order to retrieve an authorization token
+from the Keystone-moon component.
+
+python-moonclient
+=================
+The MoonClient is an interactive script to drive the Keystone-Moon component through the network.
+
+=================
+Packages creation
+=================
+
+Packages can be found on https://github.com/dthom/moon-bin
+
+keystone-moon package
+=====================
+
+The Keystone-Moon can be package into 2 forms.
+The first form is in traditional Python package :
+
+.. code-block:: bash
+
+ cd moon_repo/keystone-moon
+ python setup.py sdist
+ ls dist
+
+We develop a script to build a Debian package, this script is located in `moon_repo/debian/keystone-moon`
+
+.. code-block:: bash
+
+ cd moon_repo/debian/keystone-moon
+ python create_deb.py
+
+
+keystonemiddleware-moon package
+===============================
+
+The KeystoneMiddleware-Moon can be package into 2 forms.
+The first form is in traditional Python package :
+
+.. code-block:: bash
+
+ cd moon_repo/keystonemiddleware-moon
+ python setup.py sdist
+ ls dist
+
+We develop a script to build a Debian package, this script is located in `moon_repo/debian/keystonemiddleware-moon`
+
+.. code-block:: bash
+
+ cd moon_repo/debian/keystonemiddleware-moon
+ python create_deb.py
+
+
+python-moonclient package
+=========================
+
+There is only one type of package for the Moon client:
+
+.. code-block:: bash
+
+ cd moon_repo/moonclient
+ python setup.py sdist
+ ls dist
+
+
+============
+Installation
+============
+
+This installation procedure only describe the installation of a standalone Moon platform.
+
+
+Pre-requisite
+=============
+
+To install the Moon platform, you will need a working Linux server box.
+The platform is tested on an up-to-date Ubuntu 16.04 box.
+
+You can build your own packages or you can download stable ones on https://github.com/dthom/moon-bin
+
+Installation
+============
+
+First of all, you must install dependencies for the Keystone-moon package, then you can download pre-built packages or
+create them by yourself. Endly, you can install Keystone-Moon and MoonClient packages:
+
+.. code-block:: bash
+
+ cd /tmp
+ wget https://github.com/dthom/moon-bin/archive/master.zip
+ unzip master.zip
+ PKGS = $(python3 /tmp/moon-bin-master/tools/get_deb_depends.py /tmp/moon-bin-master/*.deb)
+ sudo apt-get install $PKGS
+ sudo dpkg -i /tmp/moon-bin-master/keystone_latest-moon_all.deb
+ sudo pip install --upgrade /tmp/moon-bin-master/python-moonclient-latest.tar.gz
+
+At this point, the Nova and Swift components must be installed on the same box or on an other box.
+See http://docs.openstack.org/ for more explanation.
+
+Nova and Swift components automatically installed the python-keystonemiddleware package.
+We have to replace it with the dedicated Moon one:
+
+.. code-block:: bash
+
+ cd /tmp
+ sudo dpkg -i /tmp/moon-bin-master/python3-keystonemiddleware_latest-moon_all.deb
+ sudo dpkg -i /tmp/moon-bin-master/python-keystonemiddleware_latest-moon_all.deb
+
+Note: if you installed Nova and Swift in 2 different nodes, you must install python-keystonemiddleware
+in those 2 nodes.
+
+Configuration
+=============
+
+For Keystone, the following files must be configured, some modifications may be needed, specially passwords:
+
+/etc/keystone/keystone-paste.ini
+
+.. code-block:: bash
+
+ sudo cp /etc/keystone/keystone-paste.ini /etc/keystone/keystone-paste.ini.bak
+ sudo sed "3i[pipeline:moon_pipeline]\npipeline = sizelimit url_normalize request_id build_auth_context token_auth admin_token_auth json_body ec2_extension_v3 s3_extension moon_service\n\n[app:moon_service]\nuse = egg:keystone#moon_service\n" /etc/keystone/keystone-paste.ini > /tmp/keystone-paste.ini
+ sudo cp /tmp/keystone-paste.ini /etc/keystone/keystone-paste.ini
+ sudo sed "s/use = egg:Paste#urlmap/use = egg:Paste#urlmap\n\/moon = moon_pipeline/" /etc/keystone/keystone-paste.ini > /tmp/keystone-paste.ini
+ sudo cp /tmp/keystone-paste.ini /etc/keystone/keystone-paste.ini
+
+/etc/keystone/keystone.conf
+
+.. code-block:: bash
+
+ cat << EOF | sudo tee -a /etc/keystone/keystone.conf
+ [moon]
+
+ # Configuration backend driver
+ configuration_driver = keystone.contrib.moon.backends.memory.ConfigurationConnector
+
+ # Tenant backend driver
+ tenant_driver = keystone.contrib.moon.backends.sql.TenantConnector
+
+ # Authorisation backend driver
+ authz_driver = keystone.contrib.moon.backends.flat.SuperExtensionConnector
+
+ # IntraExtension backend driver
+ intraextension_driver = keystone.contrib.moon.backends.sql.IntraExtensionConnector
+
+ # InterExtension backend driver
+ interextension_driver = keystone.contrib.moon.backends.sql.InterExtensionConnector
+
+ # Logs backend driver
+ log_driver = keystone.contrib.moon.backends.flat.LogConnector
+
+ # Local directory where all policies are stored
+ policy_directory = /etc/keystone/policies
+
+ # Local directory where Root IntraExtension configuration is stored
+ root_policy_directory = policy_root
+
+ # URL of the Moon master
+ master = 'http://localhost:35357/'
+
+ # Login of the Moon master
+ master_login = 'admin'
+
+ # Password of the Moon master
+ master_password = 'nomoresecrete'
+ EOF
+
+
+The logging system must be configured :
+
+.. code-block:: bash
+
+ sudo mkdir /var/log/moon/
+ sudo chown keystone /var/log/moon/
+
+ sudo addgroup moonlog
+
+ sudo chgrp moonlog /var/log/moon/
+
+ sudo touch /var/log/moon/keystonemiddleware.log
+ sudo touch /var/log/moon/system.log
+
+ sudo chgrp moonlog /var/log/moon/keystonemiddleware.log
+ sudo chgrp moonlog /var/log/moon/system.log
+ sudo chmod g+rw /var/log/moon
+ sudo chmod g+rw /var/log/moon/keystonemiddleware.log
+ sudo chmod g+rw /var/log/moon/system.log
+
+ sudo adduser keystone moonlog
+ sudo adduser swift moonlog
+ sudo adduser nova moonlog
+
+The Keystone database must be updated:
+
+.. code-block:: bash
+
+ sudo /usr/bin/keystone-manage db_sync
+ sudo /usr/bin/keystone-manage db_sync --extension moon
+
+And, Apache must be restarted:
+
+.. code-block:: bash
+
+ sudo systemctl restart apache.service
+
+In order to Nova to be able to communicate with Keystone-Moon, you must update the Nova KeystoneMiddleware configuration file.
+To achieve this, a new filter must be added in `/etc/nova/api-paste.ini` and this filter must be added to the composite data.
+The filter is:
+
+.. code-block:: bash
+
+ [filter:moon]
+ paste.filter_factory = keystonemiddleware.moon_agent:filter_factory
+ authz_login=admin
+ authz_password=password
+ logfile=/var/log/moon/keystonemiddleware.log
+
+Here is some bash lines to insert this into the Nova configuration file:
+
+.. code-block:: bash
+
+ sudo cp /etc/nova/api-paste.ini /etc/nova/api-paste.ini.bak2
+ sudo sed "/^keystone = / s/keystonecontext/keystonecontext moon/" /etc/nova/api-paste.ini > /tmp/api-paste.ini
+ sudo cp /tmp/api-paste.ini /etc/nova/api-paste.ini
+
+ echo -e "\n[filter:moon]\npaste.filter_factory = keystonemiddleware.moon_agent:filter_factory\nauthz_login=admin\nauthz_password=password\nlogfile=/var/log/moon/keystonemiddleware.log\n" | sudo tee -a /etc/nova/api-paste.ini
+
+Nova can then be restarted:
+
+.. code-block:: bash
+
+ for service in nova-compute nova-api nova-cert nova-conductor nova-consoleauth nova-scheduler ; do
+ sudo service ${service} restart
+ done
+
+In order to Swift to be able to communicate with Keystone-Moon, you must update the Swift KeystoneMiddleware configuration file.
+To achieve this, a new filter must be added in `/etc/swift/proxy-server.conf` and this filter must be added to the composite data.
+The filter is (exactly the same as Nova):
+
+.. code-block:: bash
+
+ [filter:moon]
+ paste.filter_factory = keystonemiddleware.moon_agent:filter_factory
+ authz_login=admin
+ authz_password=password
+ logfile=/var/log/moon/keystonemiddleware.log
+
+Here is some bash lines to insert this into the Nova configuration file:
+
+.. code-block:: bash
+
+ sudo cp /etc/swift/proxy-server.conf /etc/swift/proxy-server.conf.bak2
+ sudo sed "/^pipeline = / s/proxy-server/moon proxy-server/" /etc/swift/proxy-server.conf > /tmp/proxy-server.conf
+ sudo cp /tmp/proxy-server.conf /etc/swift/proxy-server.conf
+
+ echo -e "\n[filter:moon]\npaste.filter_factory = keystonemiddleware.moon_agent:filter_factory\nauthz_login=admin\nauthz_password=password\nlogfile=/var/log/moon/keystonemiddleware.log\n" | sudo tee -a /etc/swift/proxy-server.conf
+
+Swift can then be restarted:
+
+.. code-block:: bash
+
+ for service in swift-account swift-account-replicator \
+ swift-container-replicator swift-object swift-object-updater \
+ swift-account-auditor swift-container swift-container-sync \
+ swift-object-auditor swift-proxy swift-account-reaper swift-container-auditor \
+ swift-container-updater swift-object-replicator ; do
+ sudo service ${service} status
+ done
+
+
+
+Running tests
+=============
+
+After a successful installation of the Moon platform, you can execute some tests to see if the platform is
+up and running. Be patient, the latest test takes time (5 to 20 minutes).
+
+.. code-block:: bash
+
+ export OS_USERNAME=admin
+ export OS_PASSWORD=password
+ export OS_REGION_NAME=What_ever_you_want
+ export OS_TENANT_NAME=admin
+ export OS_AUTH_URL=http://localhost:5000/v2.0
+
+ # See if Nova is up and running:
+ nova list
+
+ # See if Swift is up and running:
+ swift stat
+
+ # See if Keystone-Moon is up and running
+ moon intraextension list
+ # you must see one extension (named root)
+ moon test --self
+
+
+Revision: _sha1_
+
+Build date: |today| \ No newline at end of file
diff --git a/docs/platformoverview/index.rst b/docs/platformoverview/index.rst
new file mode 100644
index 00000000..4c942e0b
--- /dev/null
+++ b/docs/platformoverview/index.rst
@@ -0,0 +1,152 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) ruan.he@orange.com & thomas.duval@orange.com
+
+****************************
+OPNFV MOON platform overview
+****************************
+
+.. toctree::
+ :numbered:
+ :maxdepth: 2
+
+
+Moon: Toward a Policy-based User-centric Security Management System for Cloud Infrastructure
+
+Introduction
+------------
+
+Cloud infrastructure is able to provision a set of different cloud resources/services for
+cloud service consumers. Trust over the provided cloud resources/services becomes a new challenge.
+In order to avoid losing control over IT assets that consumers put in the cloud, we design and develop
+Moon, a policy-based user-centric security management system for cloud infrastructure.
+Administrator can define policies in Moon, which will be enforced through different mechanisms
+in the cloud infrastructure.
+
+### Why security management system?
+A security management system is a combine system that integrates mechanisms of different security aspects.
+It first has a security policy that specifies users’ security requirements.
+It enforces the security policy through various mechanisms like authorization for access control,
+firewall for networking, isolation for storage, logging for traceability, etc.
+###Why policy-based approach?
+Cloud computing embeds a various set of heterogeneous resources into resource pools.
+Such a mechanism makes a management system hard through one standard interface.
+Alternatively, the policy-based approach bypasses the heterogeneity, the management is achieved
+through a standard policy instead of a standard interface.
+Each module of a cloud infrastructure only needs to accept the policy.
+###Why user-centric?
+The flexibility of resource pool for cloud computing makes users custom cloud resources/services
+for their own purpose. However, the current management system is not able to support this flexibility.
+A user-centric management system enables users to define, configure and manipulate on the management layer,
+in order to adapt to their usage and requirements.
+
+Drawbacks of OpenStack
+----------------------
+
+The first version of Moon is implemented in OpenStack. However, we also plan to make Moon
+protect other cloud infrastructure like VMware vCloud Director, etc in the future.
+Considering the current state of OpenStack (release Juno), several drawbacks related
+to the security management are identified:
+###No centralized control
+The OpenStack platform is divided into different services, like Nova for computing, Swift for storage,
+Neutron for networking, etc. Each service uses a configuration file with the corresponding security policy.
+But it lacks a synchronization mechanism between there configuration file. This may bring conflict.
+###No dynamic control
+Currently, each service of OpenStack is managed by a “Policy.JSON” file, all the modification
+should be done manually and reboot is necessary after the modification. On the other side,
+the authentication and authorization are achieved through the token mechanism, but there isn’t any
+token revocation mechanism. Once a user gets an authorization token, we will not have any control
+over the user. It lacks dynamic control at runtime in OpenStack.
+###No customization and flexibility
+Each user of OpenStack consumes their resource pool in their own manner, but it lacks customization
+for the management system. In OpenStack, user cannot configure their resources and define their own
+policy for each resource pool (called project in OpenStack). Users may also be a software application,
+it also lacks an automated policy enforcement mechanism in OpenStack.
+###No fine-granularity
+Finally, the granularity of authorization in OpenStack is not enough fine. Currently, it’s at the API-level.
+This means that we can authorize or deny a user from using an API like launch any VM. But we need the
+granularity to be pushed to the resource-level, authorize or deny a user from using a specific
+resource through the API, e.g. allowing a user to launch a dedicated VM.
+
+Moon Description
+----------------
+
+For all the listed reason, we decided to build a security management system to monitor,
+control and project the OpenStack infrastructure.
+
+###Functional architecture
+Moon can be considered as a management layer over OpenStack.
+We can dynamically create security modules in Moon and assign these modules to protect different
+tenants in OpenStack.
+![](../img/moon_infra.png)
+
+###Policy engine
+The core part of the security management layer is its policy engine.
+The policy engine should be at same time generic to support a large set of security models
+used by consumers and robust so that all the manipulations on the policy engine need to be proved correct.
+For all these purposes, we designed EMTAC (Extensible Multi-tenancy Access Control) meta-model,
+which defines policy specification, policy administration, inter-policy collaboration and administration
+over this collaboration.
+![](../img/policy_engine.png)
+
+###User-centric
+At the same time, Moon enables administrators or a third-party application to define, configure and manage
+its policies. Such a user-centric aspect helps users to define their own manner in using
+OpenStack’s resources.
+
+###Authorization enforcement in OpenStack
+As the first step, the security policy in Moon is enforced by authorization mechanism in Keystone and Nova
+and Swift.
+All the operations in Keystone and Nova and Swift are controlled and validated by Moon.
+In OpenStack, we implemented 3 hooks respectively for Keystone and Nova and Swift, the hooks will
+redirect all authorization requests to Moon and return decision from Moon.
+
+###Log System
+Traceability and accountability are also handled in Moon, all the operations and interactions
+are logged and can be consulted for any purpose.
+
+###Separation of management layer from OpenStack
+The separation of management layer from OpenStack makes the management system totally
+independent from OpenStack. We can install Moon in client’s local so that Moon can be
+locally administrated by clients and remotely project their data which are hosted in
+Cloud Service Provider’s datacenter.
+
+Roadmap
+-------
+
+Even if Moon can now work with OpenStack as a security management system,
+several blueprints are planned for its improvement.
+
+###Technical improvements
+
+* Update Moon’s policy engine with Prolog/Datalog: in the last version of Moon, we use a hard-coded Python policy engine. We will collaborate with VMware and their “Congress” policy engine.
+* Networking enforcement: other important improvement is to enable network management by Moon. Based on the defined policy, Moon will configure Neutron, FWaaS, etc, in OpenStack.
+* Storage enforcement: storage protect is another important aspect, access to storage blocks or files will be control by Moon.
+* IDS/IPS and self-protection: as Moon’s security module will protect each tenant,
+
+###Contribution to OpenStack
+We have worked in the OpenStack community since 1 year and half, our next step is to integrate
+with the community and contribute Moon to OpenStack/Keystone.
+Once Moon is integrated in OpenStack, the community, together with its developers will
+maintain Moon’s evolution.
+
+###Contribution to European project “SuperCloud”
+The H2020 European project “SuperCloud” will start this year, its objective is to provide
+360 degree protection on cloud infrastructure. Moon and its policy meta-model will be contributed
+as core security management system in this project.
+
+###Contribution to OPNFV
+OPNFV ([OPNFV]) wants to build a reference cloud-based architecture for NFV
+(Network Function Virtualization) based on OpenStack.
+Orange will propose a “security management” project in OPNFV.
+Moon is supposed to be the base module to develop and manage dedicated security mechanisms for vNF
+(virtualized Network Functions).
+
+See: [OPNFV-MOON]
+
+[OPNFV]:http://www.opnfv.org
+[OPNFV-MOON]:https://wiki.opnfv.org/moon
+
+Revision: _sha1_
+
+Build date: |today| \ No newline at end of file
diff --git a/docs/userguide/index.rst b/docs/userguide/index.rst
new file mode 100644
index 00000000..f7e47933
--- /dev/null
+++ b/docs/userguide/index.rst
@@ -0,0 +1,850 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) ruan.he@orange.com & thomas.duval@orange.com
+
+**************************
+OPNFV MOON developer guide
+**************************
+
+.. toctree::
+ :numbered:
+ :maxdepth: 2
+
+
+============
+Introduction
+============
+
+This guide presents the use of the MoonClient script.
+The MoonClient script allows the administrator/user to drive the Moon platform and some parts of the Keystone server itself.
+
+=============
+Pre-requisite
+=============
+
+Before using the MoonClient script, you must export some variables in your shell.
+Those variables are the same as the variables used to execute the OpenStack client or the Nova/Swift/Neutron/... clients.
+You can export directly in the shell like this:
+
+.. code-block:: bash
+
+ export OS_USERNAME=admin
+ export OS_PASSWORD=password
+ export OS_REGION_NAME=What_ever_you_want
+ export OS_TENANT_NAME=admin
+ export OS_AUTH_URL=http://localhost:5000/v2.0
+
+Or you can source a shell script:
+
+.. code-block:: bash
+
+ cat << EOF | tee ~/set_openstack_auth.sh
+ #!/usr/bin/env bash
+ export OS_USERNAME=admin
+ export OS_PASSWORD=password
+ export OS_REGION_NAME=What_ever_you_want
+ export OS_TENANT_NAME=admin
+ export OS_AUTH_URL=http://localhost:5000/v2.0
+ EOF
+ source ~/set_openstack_auth.sh
+
+It is important to notice that those variables are **exactly** the same you use for the OpenStack clients.
+
+=====
+Usage
+=====
+
+The main usage of the MoonClient is:
+
+.. code-block:: bash
+
+ $ moon --help
+ usage: moon [--version] [-v | -q] [--log-file LOG_FILE] [-h] [--debug]
+ [--username <username-str>] [--tenant <tenantname-str>]
+ [--password <password-str>] [--authurl <authurl-str>]
+ command
+ ...
+
+MoonClient ca be used interactively:
+
+.. code-block:: bash
+
+ $ moon
+
+or by using a specific command, like:
+
+.. code-block:: bash
+
+ $ moon tenant list
+
+Output formats
+==============
+
+The default output is a tabular:
+
+.. code-block:: bash
+
+ $ moon tenant list
+ +----------------------------------+-------+---------------+--------------------------+--------------------------+
+ | id | name | description | intra_authz_extension_id | intra_admin_extension_id |
+ +----------------------------------+-------+---------------+--------------------------+--------------------------+
+ | 9fb190ddb19a4a138837e2740daec3ae | admin | Admin Project | | None |
+ +----------------------------------+-------+---------------+--------------------------+--------------------------+
+
+But you can have other output format, use the `-f bad_value` to see them all:
+
+.. code-block:: bash
+
+ $ moon tenant list -f bad_value
+ usage: moon tenant list [-h] [-f {csv,json,table,value,yaml}] [-c COLUMN]
+ [--max-width <integer>] [--noindent]
+ [--quote {all,minimal,none,nonnumeric}]
+ moon tenant list: error: argument -f/--format: invalid choice: 'bad_value' (choose from 'csv', 'json', 'table', 'value', 'yaml')
+
+For example, the same command with a JSON output format:
+
+.. code-block:: bash
+
+ $ moon tenant list -f json
+ [
+ {
+ "intra_authz_extension_id": "",
+ "description": "Admin Project",
+ "intra_admin_extension_id": null,
+ "id": "9fb190ddb19a4a138837e2740daec3ae",
+ "name": "admin"
+ }
+ ]
+
+You can also select one or more columns with the `-c` attribute:
+
+.. code-block:: bash
+
+ $ moon tenant list -f value -c id -c name
+ 9fb190ddb19a4a138837e2740daec3ae admin
+
+Commands
+========
+
+All commands can be categorized like this:
+* `tenant` command to get, put or delete tenants (projects in OpenStack)
+* `intraextension` command to get, put or delete intra_extensions in Moon
+* `subject` `object` and `action` commands to configure subject, object or action in intra_extensions in Moon
+* `rule` command to set rules in an intra_extension
+* some configuration commands (`template`, `submetarule`, `aggregation`) to configure Moon and the relation in and between intra_extensions
+* `log` command to show events in the Moon logging system
+* `test` command to run tests against the Moon platform
+
+All commands can be prefixed with the command `help` to have information about usage of that command.
+
+Basic example:
+==============
+
+Here is a basic example of how you can use MoonClient:
+
+.. code-block:: bash
+
+ $ moon tenant list
+
+ $ openstack project list
+ +----------------------------------+-----------------+
+ | ID | Name |
+ +----------------------------------+-----------------+
+ | 06f2f729f5b041f290295d2d966aff00 | alt_demo |
+ | 7d5fb06879ae4a0c82948d4ed7b87b7c | demo |
+ | 833a954bfd314de09b09aac00f1aa647 | service |
+ | 9fb190ddb19a4a138837e2740daec3ae | admin |
+ | ca680df7ee10480d89414c74d46e2c65 | sdn |
+ | d30cffc153b743e88a8d78052737b556 | test_moonclient |
+ +----------------------------------+-----------------+
+ $ moon tenant add admin
+ $ moon tenant list
+ +----------------------------------+-------+---------------+--------------------------+--------------------------+
+ | id | name | description | intra_authz_extension_id | intra_admin_extension_id |
+ +----------------------------------+-------+---------------+--------------------------+--------------------------+
+ | 9fb190ddb19a4a138837e2740daec3ae | admin | Admin Project | None | None |
+ +----------------------------------+-------+---------------+--------------------------+--------------------------+
+ $ moon intraextension list
+ +----------------------------------+------------------+--------------------+
+ | id | name | model |
+ +----------------------------------+------------------+--------------------+
+ | d508874d08424ee8a78ded9d5e008685 | policy_root | policy_root |
+ +----------------------------------+------------------+--------------------+
+ $ moon template list
+ +--------------------+-------------------+-----------------------------+
+ | id | name | description |
+ +--------------------+-------------------+-----------------------------+
+ | policy_rbac_admin | RBAC Admin Policy | |
+ | policy_root | Root Policy | root extension |
+ | policy_authz | Multiple_Policy | Multiple Security Policies |
+ | policy_empty_admin | Empty_Policy | Empty Policy |
+ | policy_empty_authz | MLS_Policy | Multi Level Security Policy |
+ | policy_mls_authz | MLS_Policy | Multi Level Security Policy |
+ +--------------------+-------------------+-----------------------------+
+ $ moon intraextension add --policy_model policy_authz test
+ IntraExtension created: e75dad8f2f7d40de9921b0d444198973
+ $ moon intraextension list
+ +----------------------------------+------------------+--------------------+
+ | id | name | model |
+ +----------------------------------+------------------+--------------------+
+ | e75dad8f2f7d40de9921b0d444198973 | test | policy_authz |
+ | d508874d08424ee8a78ded9d5e008685 | policy_root | policy_root |
+ +----------------------------------+------------------+--------------------+
+ $ moon intraextension select e75dad8f2f7d40de9921b0d444198973
+ Select e75dad8f2f7d40de9921b0d444198973 IntraExtension.
+ $ moon intraextension show selected
+ +-------------+----------------------------------+
+ | Field | Value |
+ +-------------+----------------------------------+
+ | id | e75dad8f2f7d40de9921b0d444198973 |
+ | name | test |
+ | description | |
+ | model | policy_authz |
+ | genre | authz |
+ +-------------+----------------------------------+
+ $ moon subject list
+ +----------------------------------+-------+----------------------------------+
+ | id | name | Keystone ID |
+ +----------------------------------+-------+----------------------------------+
+ | 04ed28e87f004ed29ddb721c43fdafb0 | demo | 16254c7516734bca99311979f0a486bf |
+ | 8101e73fb82e433fbc576587e6201bfe | admin | 6b135900bf874d63abe59be074584eb9 |
+ +----------------------------------+-------+----------------------------------+
+ $ moon object list
+ +----------------------------------+---------+-------------+
+ | id | name | description |
+ +----------------------------------+---------+-------------+
+ | 0fb3e294f0714a30a3b0af4c889354aa | servers | servers |
+ +----------------------------------+---------+-------------+
+ $ openstack user list
+ +----------------------------------+----------+
+ | ID | Name |
+ +----------------------------------+----------+
+ | 088758e049aa4c51bdb386fd7e954c73 | glance |
+ | 16254c7516734bca99311979f0a486bf | demo |
+ | 263b87f84f274260a9dbef34e7c55602 | neutron |
+ | 40f2cbbe71e845b49e828b9208ba7dfc | alt_demo |
+ | 505a9758bd3e493f9baf44ed880aae92 | swift |
+ | 62c91c632e76435a907a510ae99df378 | keystone |
+ | 6b135900bf874d63abe59be074584eb9 | admin |
+ | b58c153e4d0647e7b61bd76d5a77916c | nova |
+ | c90c58fb2aaf4fd3880a39a8d1c34263 | cinder |
+ +----------------------------------+----------+
+ $ moon subject add test_user
+ Password for user test_user:
+ $ openstack user list
+ +----------------------------------+-----------+
+ | ID | Name |
+ +----------------------------------+-----------+
+ | 088758e049aa4c51bdb386fd7e954c73 | glance |
+ | 16254c7516734bca99311979f0a486bf | demo |
+ | 1d2fcb31ba9b44a4bd21ae6e390ae906 | test_user |
+ | 263b87f84f274260a9dbef34e7c55602 | neutron |
+ | 40f2cbbe71e845b49e828b9208ba7dfc | alt_demo |
+ | 505a9758bd3e493f9baf44ed880aae92 | swift |
+ | 62c91c632e76435a907a510ae99df378 | keystone |
+ | 6b135900bf874d63abe59be074584eb9 | admin |
+ | b58c153e4d0647e7b61bd76d5a77916c | nova |
+ | c90c58fb2aaf4fd3880a39a8d1c34263 | cinder |
+ +----------------------------------+-----------+
+
+
+
+IntraExtension
+==============
+
+An intra_extension is a module connected to a tenant/project.
+This connection allows to configure the authorization configuration for that tenant.
+The `intraextension`commands has the following sub-commands:
+
+* `add` sub-command add a new intraextension
+** this sub-command needs the name of the policy template to use
+** the list of all policy template can be retrieve with `moon template list`
+* `delete` sub-command delete an intra_extension (the deletion is definitive)
+* `init` sub-command must be **only** used if the root intra_extension was deleted
+** the sub-command has no effect otherwise
+* `list` sub-command list all intra_extensions
+* `select` sub-commands select a specific tenant so the `--intraextension` attribute is not mandatory in other commands
+* `show` sub-commands print a description of the tenant given in argument
+** `selected` is a special argument of the `show` sub-commands which prints the current selected tenant
+
+There are 3 types of intra_extension:
+
+* authz intra_extensions which are used to configure rules for standard actions (for example Nova or Swift actions)
+* admin intra_extensions which are used to configure rules for authz and admin intra_extensions
+* root intra_extensions which are used to configure rules for admin intra_extensions
+
+When you start using Moon, we recommend that you only configure authz intra_extensions.
+Admin and root intra_extensions are already configured for your needs.
+
+Here is an example of how to use intra_extension:
+
+.. code-block:: bash
+
+ $ moon template list
+ +--------------------+-------------------+-----------------------------+
+ | id | name | description |
+ +--------------------+-------------------+-----------------------------+
+ | policy_rbac_admin | RBAC Admin Policy | |
+ | policy_root | Root Policy | root extension |
+ | policy_authz | Multiple_Policy | Multiple Security Policies |
+ | policy_empty_admin | Empty_Policy | Empty Policy |
+ | policy_empty_authz | MLS_Policy | Multi Level Security Policy |
+ | policy_mls_authz | MLS_Policy | Multi Level Security Policy |
+ +--------------------+-------------------+-----------------------------+
+ $ moon intraextension add --policy_model policy_authz test
+ IntraExtension created: e75dad8f2f7d40de9921b0d444198973
+ $ moon intraextension list
+ +----------------------------------+------------------+--------------------+
+ | id | name | model |
+ +----------------------------------+------------------+--------------------+
+ | e75dad8f2f7d40de9921b0d444198973 | test | policy_authz |
+ | d508874d08424ee8a78ded9d5e008685 | policy_root | policy_root |
+ +----------------------------------+------------------+--------------------+
+ $ moon intraextension select e75dad8f2f7d40de9921b0d444198973
+ Select e75dad8f2f7d40de9921b0d444198973 IntraExtension.
+ $ moon intraextension show selected
+ +-------------+----------------------------------+
+ | Field | Value |
+ +-------------+----------------------------------+
+ | id | e75dad8f2f7d40de9921b0d444198973 |
+ | name | test |
+ | description | |
+ | model | policy_authz |
+ | genre | authz |
+ +-------------+----------------------------------+
+
+Tenant/project
+==============
+
+The `tenant` command allows to get information and modify projects in Keystone.
+
+The tenant command has several sub-commands:
+
+* `add` sub-commands add new tenant/project in Moon
+** if the project doesn't exist in Keystone, it is automatically created (see example below)
+* `delete` sub-commands delete a tenant in Moon
+** warning: it only deletes in Moon, not in Keystone
+* `list` sub-commands show all tenants configured in Moon
+** warning it doesn't list all projects in Keystone
+* `set` sub-commands update a tenant in Moon
+** this sub-commands is especially use to connect a tenant with an intra_extension
+
+
+Here is an example of use:
+
+.. code-block:: bash
+
+ $ openstack project list
+ +----------------------------------+-----------------+
+ | ID | Name |
+ +----------------------------------+-----------------+
+ | 06f2f729f5b041f290295d2d966aff00 | alt_demo |
+ | 7d5fb06879ae4a0c82948d4ed7b87b7c | demo |
+ | 833a954bfd314de09b09aac00f1aa647 | service |
+ | 9fb190ddb19a4a138837e2740daec3ae | admin |
+ | ca680df7ee10480d89414c74d46e2c65 | sdn |
+ | d30cffc153b743e88a8d78052737b556 | test_moonclient |
+ +----------------------------------+-----------------+
+ $ moon tenant list
+ +----------------------------------+-------+---------------+--------------------------+--------------------------+
+ | id | name | description | intra_authz_extension_id | intra_admin_extension_id |
+ +----------------------------------+-------+---------------+--------------------------+--------------------------+
+ | 9fb190ddb19a4a138837e2740daec3ae | admin | Admin Project | None | None |
+ +----------------------------------+-------+---------------+--------------------------+--------------------------+
+ $ moon tenant add test_tenant
+ $ moon tenant list
+ +----------------------------------+-------------+---------------+--------------------------+--------------------------+
+ | id | name | description | intra_authz_extension_id | intra_admin_extension_id |
+ +----------------------------------+-------------+---------------+--------------------------+--------------------------+
+ | 9fb190ddb19a4a138837e2740daec3ae | admin | Admin Project | None | None |
+ | 4694c91a0afb4b7d904a3bf5e886913c | test_tenant | test_tenant | None | None |
+ +----------------------------------+-------------+---------------+--------------------------+--------------------------+
+ $ openstack project list
+ +----------------------------------+-----------------+
+ | ID | Name |
+ +----------------------------------+-----------------+
+ | 06f2f729f5b041f290295d2d966aff00 | alt_demo |
+ | 4694c91a0afb4b7d904a3bf5e886913c | test_tenant |
+ | 7d5fb06879ae4a0c82948d4ed7b87b7c | demo |
+ | 833a954bfd314de09b09aac00f1aa647 | service |
+ | 9fb190ddb19a4a138837e2740daec3ae | admin |
+ | ca680df7ee10480d89414c74d46e2c65 | sdn |
+ | d30cffc153b743e88a8d78052737b556 | test_moonclient |
+ +----------------------------------+-----------------+
+
+To connect a tenant with an intra_extension, use:
+
+.. code-block:: bash
+
+ $ moon tenant set --authz e75dad8f2f7d40de9921b0d444198973 4694c91a0afb4b7d904a3bf5e886913c
+ $ moon tenant list -c id -c name -c intra_authz_extension_id
+ +----------------------------------+-------------+----------------------------------+
+ | id | name | intra_authz_extension_id |
+ +----------------------------------+-------------+----------------------------------+
+ | 9fb190ddb19a4a138837e2740daec3ae | admin | None |
+ | 4694c91a0afb4b7d904a3bf5e886913c | test_tenant | e75dad8f2f7d40de9921b0d444198973 |
+ +----------------------------------+-------------+----------------------------------+
+
+When a tenant **is not connected to** an intra_extension, this tenant acts as a standard Keystone project.
+Authorization rules are evaluated by each component independently. For example, when a user ask to stop a Virtual Machine (VM),
+Nova
+
+* retrieve the Keystone token and
+* check its policy.json file to see if that user can stop this VM.
+
+When a tenant **is connected to** an intra_extension, the authorisation process is driven by Moon.
+Authorization rules are evaluated by the Moon platform. For example, when a user ask to stop a Virtual Machine (VM),
+Nova
+
+* retrieve the Keystone token
+* check its policy.json file to see if that user can stop this VM and
+* ask Moon if the user is authorized to do such action.
+
+When a tenant is connected to an intra_extension, the authorisation process is driven by the following configuration.
+
+Subject/Object/Action
+=====================
+
+The configuration of an intra_extension is mainly divided into 3 elements.
+
+The subjects represent the users (in the future, they can also represent other elements like VM or networks).
+Subjects are the source of an action on an object.
+The objects represent the elements which is actioned by a subject (like VM, network, Swift file or directory).
+The actions represent what can a subject do on an object (like start a VM, create a file in Swift, ...).
+
+Here is an example of what you can found in a standard Moon platform:
+
+.. code-block:: bash
+
+ $ moon subject list
+ +----------------------------------+-----------+----------------------------------+
+ | id | name | Keystone ID |
+ +----------------------------------+-----------+----------------------------------+
+ | 04ed28e87f004ed29ddb721c43fdafb0 | demo | 16254c7516734bca99311979f0a486bf |
+ | 517e648cc5d64984ab18e8c76422258a | test_user | 1d2fcb31ba9b44a4bd21ae6e390ae906 |
+ | 8101e73fb82e433fbc576587e6201bfe | admin | 6b135900bf874d63abe59be074584eb9 |
+ +----------------------------------+-----------+----------------------------------+
+ $ moon object list
+ +----------------------------------+---------+-------------+
+ | id | name | description |
+ +----------------------------------+---------+-------------+
+ | 0fb3e294f0714a30a3b0af4c889354aa | servers | servers |
+ +----------------------------------+---------+-------------+
+ $ moon action list
+ +----------------------------------+--------------+--------------+
+ | id | name | description |
+ +----------------------------------+--------------+--------------+
+ | e349bdad65ac43aeb1058623f9738b2b | unpause | unpause |
+ | 41b8ce4256a84f19b4322acef05f3367 | post | post |
+ | 7eea8c5b19c04d4e9cfc5a14cdd8ce84 | create | create |
+ | 78a20944dbd04b2ea33007d46bfd5ddd | download | download |
+ | a1da1466938842c2b2aace1868153192 | upload | upload |
+ | ab9f285b9670473fbe2f1501b62a2779 | list | list |
+ | b47452174c0c40a58d7cb2ba949acfe9 | storage_list | storage_list |
+ | 9c448d73e344472bbe189546c2c35c5d | stop | stop |
+ | b957463ac8cf4a02ad2e64c0ae38e425 | pause | pause |
+ | 3b018cd88b964e5ca69c4ef9e8045a3d | start | start |
+ +----------------------------------+--------------+--------------+
+
+Note: the *servers* object is a special hardcoded object which represents all servers of Nova.
+This object is used when we need to list Nova VM.
+
+Each of these elements can belonged to one or more categories, here is an example of categories:
+
+.. code-block:: bash
+
+ $ moon subject category list
+ +----------------------------------+------------------------+------------------------+
+ | id | name | description |
+ +----------------------------------+------------------------+------------------------+
+ | 3d97b1e12f6949cfa71e6ecd6f15a361 | domain | domain |
+ | 366c308036b74c9da9121759a42c2f19 | role | role |
+ | f6f7e1fd031144b2a8c4d7866424b8c6 | subject_security_level | subject_security_level |
+ +----------------------------------+------------------------+------------------------+
+ $ moon object category list
+ +----------------------------------+-----------------------+-----------------------+
+ | id | name | description |
+ +----------------------------------+-----------------------+-----------------------+
+ | 3a4c9f8e5b404d1db7aa641714c8b1c7 | object_id | object_id |
+ | 292d8f613dea49ec9118f76691e580d1 | object_security_level | object_security_level |
+ | 57f18e690cb948d88c26d210289fb379 | type | type |
+ +----------------------------------+-----------------------+-----------------------+
+ $ moon action category list
+ +----------------------------------+-----------------+-----------------+
+ | id | name | description |
+ +----------------------------------+-----------------+-----------------+
+ | cdfbf00d0c1f4d61bf4b6de669721f10 | access | access |
+ | b01d380dda324e39a6a6b0d09065a93d | resource_action | resource_action |
+ +----------------------------------+-----------------+-----------------+
+
+For example, a subject can have a domain and/or have a specific role and/or have a specific security level (subject_security_level).
+To know the scope of a category, you can use the `moon scope list <category_id>` command:
+
+.. code-block:: bash
+
+ $ moon subject scope list 366c308036b74c9da9121759a42c2f19
+ +----------------------------------+-------+-------------+
+ | id | name | description |
+ +----------------------------------+-------+-------------+
+ | 98e0357500274d30bb5ba2f896fbedf9 | dev | dev |
+ | 6e4570266b1f42bab47498714716dca6 | admin | admin |
+ +----------------------------------+-------+-------------+
+
+In this example, for the category *role*, we have 2 possible values: *dev* and *admin*.
+
+.. code-block:: bash
+
+ $ moon object scope list 292d8f613dea49ec9118f76691e580d1
+ +----------------------------------+--------+-------------+
+ | id | name | description |
+ +----------------------------------+--------+-------------+
+ | e90edf39b4cc496cb28094a056089d65 | low | low |
+ | 73feffe318de4390bc8b4fce5f7d4b88 | high | high |
+ | 41a80336362248e39298b6f52c4ae14d | medium | medium |
+ +----------------------------------+--------+-------------+
+
+In this example, for the category *object_security_level*, we have 3 possible values: *low*, *medium* and *high*.
+
+_Note:_ if you try to list a scope with the wrong category ID, MoonClient will raise an error:
+
+.. code-block:: bash
+
+ $ moon subject scope list 292d8f613dea49ec9118f76691e580d1
+ Getting an error while requiring /moon/intra_extensions/e75dad8f2f7d40de9921b0d444198973/subject_scopes/292d8f613dea49ec9118f76691e580d1 (400: Subject Category Unknown, The given subject category is unknown.)
+
+Each of these elements (subject, object, action and their respective categories and scopes) can be modified with the
+sub-commands `add` and `delete`.
+
+
+To link all of these elements, you can use assignment.
+In the following example, the subject *admin* is linked to the category *role* with the scope *admin*:
+
+.. code-block:: bash
+
+ $ moon subject assignment list 8101e73fb82e433fbc576587e6201bfe 366c308036b74c9da9121759a42c2f19
+ +----------------------------------+-------+
+ | id | name |
+ +----------------------------------+-------+
+ | 6e4570266b1f42bab47498714716dca6 | admin |
+ +----------------------------------+-------+
+
+This means that the user *admin* has the role *admin*.
+In the following example, the subject *admin* is also linked to the category *subject_security_level* with the scope *high*:
+
+.. code-block:: bash
+
+ $ moon subject assignment list 8101e73fb82e433fbc576587e6201bfe f6f7e1fd031144b2a8c4d7866424b8c6
+ +----------------------------------+------+
+ | id | name |
+ +----------------------------------+------+
+ | 45d6852c4a08498298331bcd72c2e988 | high |
+ +----------------------------------+------+
+
+As before, if you put a wrong subject ID or a wrong subject category ID, MoonClient will raise an error:
+
+.. code-block:: bash
+
+ $ moon subject assignment list 8101e73fb82e433fbc576587e6201bfe f6f7e1fd031144b2a8c4d7866424b8c3
+ Getting an error while requiring /moon/intra_extensions/e75dad8f2f7d40de9921b0d444198973/subject_assignments/8101e73fb82e433fbc576587e6201bfe/f6f7e1fd031144b2a8c4d7866424b8c3 (400: Subject Category Unknown, The given subject category is unknown.)
+ $ moon subject assignment list 8101e73fb82e433fbc576587e6201bfr f6f7e1fd031144b2a8c4d7866424b8c6
+ Getting an error while requiring /moon/intra_extensions/e75dad8f2f7d40de9921b0d444198973/subject_assignments/8101e73fb82e433fbc576587e6201bfr/f6f7e1fd031144b2a8c4d7866424b8c6 (400: Subject Unknown, The given subject is unknown.)
+
+
+Configuration
+=============
+
+Before dealing with rules, we must configure our intra_extension.
+This configuration can be done with `template`, `submetarule`, `aggregation` commands.
+
+We have already see what the `template` command does:
+
+.. code-block:: bash
+
+ $ moon template list
+ +--------------------+-------------------+-----------------------------+
+ | id | name | description |
+ +--------------------+-------------------+-----------------------------+
+ | policy_rbac_admin | RBAC Admin Policy | |
+ | policy_root | Root Policy | root extension |
+ | policy_authz | Multiple_Policy | Multiple Security Policies |
+ | policy_empty_admin | Empty_Policy | Empty Policy |
+ | policy_empty_authz | MLS_Policy | Multi Level Security Policy |
+ | policy_mls_authz | MLS_Policy | Multi Level Security Policy |
+ +--------------------+-------------------+-----------------------------+
+
+This command only list available policy template. Those templates are hardcoded into Moon, you cannot modify them though
+the MoonClient. If you need to update them (which is not recommended), you must go in the directory `/etc/keystone/policies`
+and update the json file inside.
+Those template describe the behaviour of an intra_extension.
+When you start using Moon, we recommend that you use the *Multiple_Policy* (with ID *policy_authz*) template which is the simplest template.
+It has default values easy to configure.
+
+This policy template is configured with 3 sub-meta-rules shown below:
+
+.. code-block:: bash
+
+ $ moon submetarule show
+ +----------------------------------+-----------+-----------+------------------------+-----------------------+-------------------+
+ | id | name | algorithm | subject categories | object categories | action categories |
+ +----------------------------------+-----------+-----------+------------------------+-----------------------+-------------------+
+ | a0c30ab9f4104098a9636b0aab294deb | rbac_rule | inclusion | role, domain | object_id | access |
+ | 6e4abecb486448309ad5ace17ab134dc | dte_rule | inclusion | domain | type | access |
+ | ba9eac79b38a46cc9ab65feb32696803 | mls_rule | inclusion | subject_security_level | object_security_level | resource_action |
+ +----------------------------------+-----------+-----------+------------------------+-----------------------+-------------------+
+
+Each sub-meta-rules indicates how rules will be built.
+In this example, the first sub-meta-rules (*rbac_rule*) indicates that a single rule will be the concatenation of the following categories:
+
+* role,
+* domain
+* object_id
+* access
+
+**The order between categories is important!**
+
+This sub-meta-rules matches a enhanced Role-Base-Access-Control policy. A standard RBAC policy would be:
+
+* role,
+* object_id
+* access
+
+And we would have in Moon:
+
+.. code-block:: bash
+
+ +----------------------------------+-----------+-----------+------------------------+-----------------------+-------------------+
+ | id | name | algorithm | subject categories | object categories | action categories |
+ +----------------------------------+-----------+-----------+------------------------+-----------------------+-------------------+
+ ...
+ | a0c30ab9f4104098a9636b0aab294deb | rbac_rule | inclusion | role | object_id | access |
+ ...
+ +----------------------------------+-----------+-----------+------------------------+-----------------------+-------------------+
+
+If you want to modify that point, use the following commands:
+
+.. code-block:: bash
+
+ $ moon subject category list
+ +----------------------------------+------------------------+------------------------+
+ | id | name | description |
+ +----------------------------------+------------------------+------------------------+
+ | 3d97b1e12f6949cfa71e6ecd6f15a361 | domain | domain |
+ | 366c308036b74c9da9121759a42c2f19 | role | role |
+ | f6f7e1fd031144b2a8c4d7866424b8c6 | subject_security_level | subject_security_level |
+ +----------------------------------+------------------------+------------------------+
+ $ moon submetarule set --subject_category_id 366c308036b74c9da9121759a42c2f19 a0c30ab9f4104098a9636b0aab294deb
+ $ moon submetarule show
+ +----------------------------------+-----------+-----------+------------------------+-----------------------+-------------------+
+ | id | name | algorithm | subject categories | object categories | action categories |
+ +----------------------------------+-----------+-----------+------------------------+-----------------------+-------------------+
+ | a0c30ab9f4104098a9636b0aab294deb | rbac_rule | inclusion | role | object_id | access |
+ | 6e4abecb486448309ad5ace17ab134dc | dte_rule | inclusion | domain | type | access |
+ | ba9eac79b38a46cc9ab65feb32696803 | mls_rule | inclusion | subject_security_level | object_security_level | resource_action |
+ +----------------------------------+-----------+-----------+------------------------+-----------------------+-------------------+
+
+**Warning:** After modifying the sub-meta-rule, you **must** delete all rules corresponding to that sub-meta-rule and add new rules (see below).
+
+As you can see, the third column is titled *algorithm*. This algorithm indicates how the match between scopes and rules is done.
+There are 2 hardcoded algorithms: *inclusion* and *comparison*.
+At this time the *comparison* algorithm is a future work, don't use it. Use exclusively the *inclusion* algorithm.
+
+Rules
+=====
+
+Rules are analysed by our engine to authorize (or not) an action from Nova or Swift.
+Here is an example of what a list of rules looks like for the our *rbac_rule* sub-meta-rule:
+
+.. code-block:: bash
+
+ $ moon rule list a0c30ab9f4104098a9636b0aab294deb
+ +---+----------------------------------+--------+----------+----------+-------------+---------+
+ | | id | s:role | s:domain | a:access | o:object_id | enabled |
+ +---+----------------------------------+--------+----------+----------+-------------+---------+
+ | 0 | b8579d7e2eba4c44a9524843d1b4b2e6 | admin | xx | read | servers | True |
+ | 1 | 11fa000905654737b2476d06fc9e2be0 | admin | ft | read | servers | True |
+ | 2 | 2acca0c356c946d1adec541ad56839ab | dev | xx | read | servers | True |
+ +---+----------------------------------+--------+----------+----------+-------------+---------+
+
+In the sub-meta-rule *rbac_rule*, we have 4 categories (role, domain, object_id, access). So we have 4 columns for each rules:
+
+* s:role
+* s:domain
+* a:access
+* o:object_id
+
+The prefix indicates if the category is a subject, action or object category. Here, we have two subject categories,
+one action category and one object category. Again, the order is very important.
+
+To add a new rule, the help command can be usefull:
+
+.. code-block:: bash
+
+ $ moon help rule add
+ usage: moon rule add [-h] [--intraextension <intraextension-uuid>]
+ <submetarule-uuid> <argument-list>
+
+ Add a new rule.
+
+ positional arguments:
+ <submetarule-uuid> Sub Meta Rule UUID
+ <argument-list> Rule list (example: admin,start,servers) with that
+ ordering: subject, action, object
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --intraextension <intraextension-uuid>
+ IntraExtension UUID
+
+We can see that we need the submetarule-uuid and an argument list.
+To be more user-friendly, this list uses name of scope and not their ID.
+You must respect the order : subject scopes, action scopes and object scopes.
+And if you have more than one scope (in subject for example), you must follow the order of the configuration in the
+sub-meta-rule. In our example, the order is role then domain.
+
+A new rule will be added like this:
+
+.. code-block:: bash
+
+ $ moon rule add a0c30ab9f4104098a9636b0aab294deb dev,ft,read,servers
+ $ moon rule list a0c30ab9f4104098a9636b0aab294deb
+ +---+----------------------------------+--------+----------+----------+-------------+---------+
+ | | id | s:role | s:domain | a:access | o:object_id | enabled |
+ +---+----------------------------------+--------+----------+----------+-------------+---------+
+ | 0 | b8579d7e2eba4c44a9524843d1b4b2e6 | admin | xx | read | servers | True |
+ | 1 | 24ef8de4526f4268a7de530443edd9fa | dev | ft | read | servers | True |
+ | 2 | 11fa000905654737b2476d06fc9e2be0 | admin | ft | read | servers | True |
+ | 3 | 2acca0c356c946d1adec541ad56839ab | dev | xx | read | servers | True |
+ +---+----------------------------------+--------+----------+----------+-------------+---------+
+
+The latest column allows to enabled or disabled a specific rule.
+
+Log system
+==========
+
+Logs can be obtain with the `log` command:
+
+.. code-block:: bash
+
+ $ moon log --number 10
+ +---------------------+---------------------------------------------------------------------------------------------------------+
+ | Time | Message |
+ +---------------------+---------------------------------------------------------------------------------------------------------+
+ | 2016-08-11-12:28:58 | No Intra_Admin_Extension found, authorization granted by default. |
+ | | |
+ | 2016-08-12-03:30:05 | /MoonError/AdminException/AdminMetaData/SubjectCategoryUnknown (The given subject category is unknown.) |
+ | | |
+ | 2016-08-12-03:38:11 | /MoonError/AdminException/AdminPerimeter/SubjectUnknown (The |
+ | | given subject is unknown.) |
+ | | |
+ | 2016-08-12-03:48:05 | /MoonError/AdminException/AdminMetaData/SubjectCategoryUnknown (The given subject category is unknown.) |
+ | | |
+ | 2016-08-12-03:48:22 | /MoonError/AdminException/AdminPerimeter/SubjectUnknown (The |
+ | | given subject is unknown.) |
+ | | |
+ | 2016-08-12-03:50:59 | No Intra_Admin_Extension found, authorization granted by default. |
+ | | |
+ | 2016-08-12-03:51:38 | No Intra_Admin_Extension found, authorization granted by default. |
+ | | |
+ | 2016-08-12-03:52:01 | No Intra_Admin_Extension found, authorization granted by default. |
+ | | |
+ | 2016-08-12-03:52:08 | No Intra_Admin_Extension found, authorization granted by default. |
+ | | |
+ | 2016-08-12-03:54:52 | No Intra_Admin_Extension found, authorization granted by default. |
+ | | |
+ +---------------------+---------------------------------------------------------------------------------------------------------+
+
+In this example, we limit the number of events to 10.
+You can filter with a particular string or search by date. See the `help` command for more information:
+
+.. code-block:: bash
+
+ $ moon help log
+ usage: moon log [-h] [-f {csv,json,table,value,yaml}] [-c COLUMN]
+ [--max-width <integer>] [--noindent]
+ [--quote {all,minimal,none,nonnumeric}]
+ [--filter <filter-str>] [--fromdate <from-date-str>]
+ [--todate <to-date-str>] [--number <number-int>]
+
+ List all logs.
+
+ optional arguments:
+ -h, --help show this help message and exit
+ --filter <filter-str>
+ Filter strings (example: "OK" or "authz")
+ --fromdate <from-date-str>
+ Filter logs by date (example: "2015-04-15-13:45:20")
+ --todate <to-date-str>
+ Filter logs by date (example: "2015-04-15-13:45:20")
+ --number <number-int>
+ Show only <number-int> logs
+
+ output formatters:
+ output formatter options
+
+ -f {csv,json,table,value,yaml}, --format {csv,json,table,value,yaml}
+ the output format, defaults to table
+ -c COLUMN, --column COLUMN
+ specify the column(s) to include, can be repeated
+
+ table formatter:
+ --max-width <integer>
+ Maximum display width, <1 to disable. You can also use
+ the CLIFF_MAX_TERM_WIDTH environment variable, but the
+ parameter takes precedence.
+
+ json formatter:
+ --noindent whether to disable indenting the JSON
+
+ CSV Formatter:
+ --quote {all,minimal,none,nonnumeric}
+ when to include quotes, defaults to nonnumeric
+
+
+Test
+====
+
+Moonclient can execute some tests written in a custom format (JSON format).
+After installing MoonClient, it is advised to execute all tests to see if the Moon platform is up and running:
+
+.. code-block:: bash
+
+ $ moon test --self
+ Write tests output to /tmp/moonclient_test_20160812-090856.log
+
+ Executing /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_empty_policy_new_user.json (1/22)
+ ...
+ +------------------------------------------------------------------------------------------+---------+------------------------------------------+
+ | filename | results | log file |
+ +------------------------------------------------------------------------------------------+---------+------------------------------------------+
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_actions.json | True | /tmp/moonclient_test_20160812-092537.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_configuration.json | True | /tmp/moonclient_test_20160812-092434.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_empty_policy_nova.json | False | /tmp/moonclient_test_20160812-092051.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_action_categories.json | True | /tmp/moonclient_test_20160812-091823.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_action_scopes.json | True | /tmp/moonclient_test_20160812-092037.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_object_assignments.json | True | /tmp/moonclient_test_20160812-092520.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_subject_scopes.json | True | /tmp/moonclient_test_20160812-092448.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_objects.json | True | /tmp/moonclient_test_20160812-091836.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_subjects.json | True | /tmp/moonclient_test_20160812-092351.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_object_categories.json | True | /tmp/moonclient_test_20160812-092421.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_root_intraextensions.json | True | /tmp/moonclient_test_20160812-091850.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_subject_assignments.json | True | /tmp/moonclient_test_20160812-092502.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_subject_categories.json | True | /tmp/moonclient_test_20160812-092338.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_admin_intraextensions.json | True | /tmp/moonclient_test_20160812-092237.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_submetarules.json | True | /tmp/moonclient_test_20160812-092405.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_object_scopes.json | True | /tmp/moonclient_test_20160812-092322.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_action_assignments.json | True | /tmp/moonclient_test_20160812-092213.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_rules.json | True | /tmp/moonclient_test_20160812-091857.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_empty_policy_swift.json | False | /tmp/moonclient_test_20160812-091922.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_external_commands.json | False | /tmp/moonclient_test_20160812-092246.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_tenants.json | True | /tmp/moonclient_test_20160812-092228.log |
+ | /usr/local/lib/python2.7/dist-packages/moonclient/tests/tests_empty_policy_new_user.json | False | /tmp/moonclient_test_20160812-090856.log |
+ +------------------------------------------------------------------------------------------+---------+------------------------------------------+
+
+
+Executing all tests may take time, so be patient.
+Each test can be executed separately and you have acces to a file log in the `/tmp` directory for each test.
+
+
+Revision: _sha1_
+
+Build date: |today| \ No newline at end of file