summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/best_practices_guide.adoc153
-rw-r--r--docs/core_concepts_guide.adoc43
-rw-r--r--docs/style_guide.adoc138
3 files changed, 334 insertions, 0 deletions
diff --git a/docs/best_practices_guide.adoc b/docs/best_practices_guide.adoc
new file mode 100644
index 000000000..301c6ccda
--- /dev/null
+++ b/docs/best_practices_guide.adoc
@@ -0,0 +1,153 @@
+// vim: ft=asciidoc
+
+= Openshift-Ansible Best Practices Guide
+
+The purpose of this guide is to describe the preferred patterns and best practices used in this repository (both in ansible and python).
+
+It is important to note that this repository may not currently comply with all best practices, but the intention is that it will.
+
+All new pull requests created against this repository MUST comply with this guide.
+
+This guide complies with https://www.ietf.org/rfc/rfc2119.txt[RFC2119].
+
+
+== Pull Requests
+
+[cols="2v,v"]
+|===
+| **Rule**
+| All pull requests MUST pass the build bot *before* they are merged.
+|===
+
+
+The purpose of this rule is to avoid cases where the build bot will fail pull requests for code modified in a previous pull request.
+
+The tooling is flexible enough that exceptions can be made so that the tool the build bot is running will ignore certain areas or certain checks, but the build bot itself must pass for the pull request to be merged.
+
+
+
+== Python
+
+=== PyLint
+http://www.pylint.org/[PyLint] is used in an attempt to keep the python code as clean and as managable as possible. The build bot runs each pull request through PyLint and any warnings or errors cause the build bot to fail the pull request.
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| PyLint rules MUST NOT be disabled on a whole file.
+|===
+
+Instead, http://docs.pylint.org/faq.html#is-it-possible-to-locally-disable-a-particular-message[disable the PyLint check on the line where PyLint is complaining].
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| PyLint rules MUST NOT be disabled unless they meet one of the following exceptions
+|===
+
+.Exceptions:
+1. When PyLint fails because of a dependency that can't be installed on the build bot
+1. When PyLint fails because of including a module that is outside of control (like Ansible)
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| All PyLint rule disables MUST be documented in the code.
+|===
+
+The purpose of this rule is to inform future developers about the disable.
+
+.Specifically, the following MUST accompany every PyLint disable:
+1. Why is the check being disabled?
+1. Is disabling this check meant to be permanent or temporary?
+
+.Example:
+[source,python]
+----
+# Reason: disable pylint maybe-no-member because overloaded use of
+# the module name causes pylint to not detect that 'results'
+# is an array or hash
+# Status: permanently disabled unless a way is found to fix this.
+# pylint: disable=maybe-no-member
+metadata[line] = results.pop()
+----
+
+
+== Ansible
+
+=== Roles
+.Context
+* http://docs.ansible.com/playbooks_best_practices.html#directory-layout[Ansible Suggested Directory Layout]
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| The Ansible roles directory MUST maintain a flat structure.
+|===
+
+.The purpose of this rule is to:
+* Comply with the upstream best practices
+* Make it familiar for new contributors
+* Make it compatible with Ansible Galaxy
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| Ansible Roles SHOULD be named like technology_component[_subcomponent].
+|===
+
+For clarity, it is suggested to follow a pattern when naming roles. It is important to note that this is a recommendation for role naming, and follows the pattern used by upstream.
+
+Many times the `technology` portion of the pattern will line up with a package name. It is advised that whenever possible, the package name should be used.
+
+.Examples:
+* The role to configure an OpenShift Master is called `openshift_master`
+* The role to configure OpenShift specific yum repositories is called `openshift_repos`
+
+=== Filters
+.Context:
+* https://docs.ansible.com/playbooks_filters.html[Ansible Playbook Filters]
+* http://jinja.pocoo.org/docs/dev/templates/#builtin-filters[Jinja2 Builtin Filters]
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| The `default` filter SHOULD replace empty strings, lists, etc.
+|===
+
+When using the jinja2 `default` filter, unless the variable is a boolean, specify `true` as the second parameter. This will cause the default filter to replace empty strings, lists, etc with the provided default.
+
+This is because it is preferable to either have a sane default set than to have an empty string, list, etc. For example, it is preferable to have a config value set to a sane default than to have it simply set as an empty string.
+
+.From the http://jinja.pocoo.org/docs/dev/templates/[Jinja2 Docs]:
+[quote]
+If you want to use default with variables that evaluate to false you have to set the second parameter to true
+
+.Example:
+[source,yaml]
+----
+---
+- hosts: localhost
+ gather_facts: no
+ vars:
+ somevar: ''
+ tasks:
+ - debug: var=somevar
+
+ - name: "Will output 'somevar: []'"
+ debug: "msg='somevar: [{{ somevar | default('the string was empty') }}]'"
+
+ - name: "Will output 'somevar: [the string was empty]'"
+ debug: "msg='somevar: [{{ somevar | default('the string was empty', true) }}]'"
+----
+
+
+In other words, normally the `default` filter will only replace the value if it's undefined. By setting the second parameter to `true`, it will also replace the value if it defaults to a false value in python, so None, empty list, empty string, etc.
+
+This is almost always more desirable than an empty list, string, etc.
diff --git a/docs/core_concepts_guide.adoc b/docs/core_concepts_guide.adoc
new file mode 100644
index 000000000..38187c55e
--- /dev/null
+++ b/docs/core_concepts_guide.adoc
@@ -0,0 +1,43 @@
+// vim: ft=asciidoc
+
+= Openshift-Ansible Core Concepts Guide
+
+The purpose of this guide is to describe core concepts used in this repository.
+
+It is important to note that this repository may not currently implement all of the concepts, but the intention is that it will.
+
+== Logical Grouping Concepts
+The following are the concepts used to logically group OpenShift cluster instances.
+
+These groupings are used to perform operations specifically against instances in the specified group.
+
+For example, run an Ansible playbook against all instances in the `production` environment, or run an adhoc command against all instances in the `acme-corp` cluster group.
+
+=== Cluster
+A Cluster is a complete install of OpenShift (master, nodes, registry, router, etc).
+
+Example: Acme Corp has sales and marketing departments that both want to use OpenShift for their internal applications, but they do not want to share resources because they have different cost centers. Each department could have their own completely separate install of OpenShift. Each install is a separate OpenShift cluster.
+
+Defined Clusters:
+`acme-sales`
+`acme-marketing`
+
+=== Cluster Group
+A cluster group is a logical grouping of one or more clusters. Which clusters are in which cluster groups is determined by the OpenShift administrators.
+
+Example: Extending the example above, both marketing and sales clusters are part of Acme Corp. Let's say that Acme Corp contracts with Hosting Corp to host their OpenShift clusters. Hosting Corp could create an Acme Corp cluster group.
+
+This would logically group Acme Corp resources from other Hosting Corp customers, which would enable the Hosting Corp's OpenShift administrators to run operations specifically targeting Acme Corp instances.
+
+Defined Cluster Group:
+`acme-corp`
+
+=== Environment
+An environment is a logical grouping of one or more cluster groups. How the environment is defined is determined by the OpenShift administrators.
+
+Example: Extending the two examples above, Hosting Corp is upgrading to the latest version of OpenShift. Before deploying it to their clusters in the Production environment, they want to test it out. So, Hosting Corp runs an Ansible playbook specifically against all of the cluster groups in the Staging environment in order to do the OpenShift upgrade.
+
+
+Defined Environments:
+`production`
+`staging`
diff --git a/docs/style_guide.adoc b/docs/style_guide.adoc
new file mode 100644
index 000000000..3b888db12
--- /dev/null
+++ b/docs/style_guide.adoc
@@ -0,0 +1,138 @@
+// vim: ft=asciidoc
+
+= Openshift-Ansible Style Guide
+
+The purpose of this guide is to describe the preferred coding conventions used in this repository (both in ansible and python).
+
+It is important to note that this repository may not currently comply with all style guide rules, but the intention is that it will.
+
+All new pull requests created against this repository MUST comply with this guide.
+
+This style guide complies with https://www.ietf.org/rfc/rfc2119.txt[RFC2119].
+
+== Python
+
+
+=== Python Maximum Line Length
+
+.Context:
+* https://www.python.org/dev/peps/pep-0008/#maximum-line-length[Python Pep8 Line Length]
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| All lines SHOULD be no longer than 80 characters.
+|===
+
+Every attempt SHOULD be made to comply with this soft line length limit, and only when it makes the code more readable should this be violated.
+
+Code readability is subjective, therefore pull-requests SHOULD still be merged, even if they violate this soft limit as it is up to the individual contributor to determine if they should violate the 80 character soft limit.
+
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| All lines MUST be no longer than 120 characters.
+|===
+
+This is a hard limit and is enforced by the build bot. This check MUST NOT be disabled.
+
+
+
+== Ansible
+
+=== Ansible Global Variables
+Ansible global variables are defined as any variables outside of ansible roles. Examples include playbook variables, variables passed in on the cli, etc.
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| Global variables MUST have a prefix of g_
+|===
+
+
+Example:
+[source]
+----
+g_environment: someval
+----
+
+=== Ansible Role Variables
+Ansible role variables are defined as variables contained in (or passed into) a role.
+
+'''
+[cols="2v,v"]
+|===
+| **Rule**
+| Role variables MUST have a prefix of atleast 3 characters. See below for specific naming rules.
+|===
+
+==== Role with 3 (or more) words in the name
+
+Take the first letter of each of the words.
+
+.3 word example:
+* Role name: made_up_role
+* Prefix: mur
+[source]
+----
+mur_var1: value_one
+----
+
+.4 word example:
+* Role name: totally_made_up_role
+* Prefix: tmur
+[source]
+----
+tmur_var1: value_one
+----
+
+
+
+==== Role with 2 (or less) words in the name
+
+Make up a prefix that makes sense.
+
+.1 word example:
+* Role name: ansible
+* Prefix: ans
+[source]
+----
+ans_var1: value_one
+----
+
+.2 word example:
+* Role name: ansible_tower
+* Prefix: tow
+[source]
+----
+tow_var1: value_one
+----
+
+
+==== Role name prefix conflicts
+If two role names contain words that start with the same letters, it will seem like their prefixes would conflict.
+
+Role variables are confined to the roles themselves, so this is actually only a problem if one of the roles depends on the other role (or uses includes into the other role).
+
+.Same prefix example:
+* First Role Name: made_up_role
+* First Role Prefix: mur
+* Second Role Name: my_uber_role
+* Second Role Prefix: mur
+[source]
+----
+- hosts: localhost
+ roles:
+ - { role: made_up_role, mur_var1: val1 }
+ - { role: my_uber_role, mur_var1: val2 }
+----
+
+Even though both roles have the same prefix (mur), and even though both roles have a variable named mur_var1, these two variables never exist outside of their respective roles. This means that this is not a problem.
+
+This would only be a problem if my_uber_role depended on made_up_role, or vice versa. Or if either of these two roles included things from the other.
+
+This is enough of a corner case that it is unlikely to happen. If it does, it will be addressed on a case by case basis.