summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules69
-rw-r--r--LICENSE674
-rw-r--r--README.md81
-rwxr-xr-xdeploy.sh3
-rw-r--r--provider_base/README9
-rw-r--r--provider_base/common.json34
-rw-r--r--provider_base/files/branding/head.scss1
-rw-r--r--provider_base/files/branding/tail.scss1
-rw-r--r--provider_base/files/service-definitions/eip-service.json.erb37
-rw-r--r--provider_base/files/service-definitions/provider.json.erb20
-rw-r--r--provider_base/provider.json30
-rw-r--r--provider_base/services/ca.json11
-rw-r--r--provider_base/services/couchdb.json22
-rw-r--r--provider_base/services/dns.json7
-rw-r--r--provider_base/services/monitor.json6
-rw-r--r--provider_base/services/openvpn.json16
-rw-r--r--provider_base/services/tor.json6
-rw-r--r--provider_base/services/webapp.json34
-rw-r--r--provider_base/tags/local.json3
-rw-r--r--provider_base/tags/production.json3
-rw-r--r--provider_base/test/openvpn/client.ovpn.erb26
-rw-r--r--puppet/hiera.yaml15
-rw-r--r--puppet/lib/puppet/parser/functions/create_resources_hash_from.rb116
-rw-r--r--puppet/manifests/site.pp40
m---------puppet/modules/apache0
m---------puppet/modules/apt0
m---------puppet/modules/augeas0
m---------puppet/modules/bundler0
m---------puppet/modules/common0
m---------puppet/modules/concat0
m---------puppet/modules/couchdb0
m---------puppet/modules/git0
m---------puppet/modules/lsb0
m---------puppet/modules/nagios0
m---------puppet/modules/ntp9
m---------puppet/modules/openvpn8
m---------puppet/modules/passenger0
m---------puppet/modules/resolvconf0
m---------puppet/modules/ruby0
m---------puppet/modules/rubygems0
m---------puppet/modules/shorewall0
l---------puppet/modules/site-apache1
-rw-r--r--puppet/modules/site_apache/files/vhosts.d/couchdb_proxy.conf10
-rw-r--r--puppet/modules/site_apache/templates/vhosts.d/api.conf.erb39
-rw-r--r--puppet/modules/site_apache/templates/vhosts.d/leap_webapp.conf.erb47
-rw-r--r--puppet/modules/site_apt/manifests/dist_upgrade.pp15
-rw-r--r--puppet/modules/site_apt/manifests/init.pp15
-rw-r--r--puppet/modules/site_apt/templates/fallback.list3
-rw-r--r--puppet/modules/site_ca_daemon/manifests/apache.pp62
-rw-r--r--puppet/modules/site_ca_daemon/manifests/couchdb.pp16
-rw-r--r--puppet/modules/site_ca_daemon/manifests/init.pp103
-rw-r--r--puppet/modules/site_ca_daemon/templates/leap_ca.yaml.erb31
-rw-r--r--puppet/modules/site_config/lib/facter/ip_interface.rb13
-rw-r--r--puppet/modules/site_config/manifests/caching_resolver.pp41
-rw-r--r--puppet/modules/site_config/manifests/default.pp36
-rw-r--r--puppet/modules/site_config/manifests/hosts.pp22
-rw-r--r--puppet/modules/site_config/manifests/resolvconf.pp24
-rw-r--r--puppet/modules/site_config/manifests/slow.pp6
-rw-r--r--puppet/modules/site_config/manifests/sshd.pp9
-rw-r--r--puppet/modules/site_config/templates/hosts15
-rwxr-xr-xpuppet/modules/site_couchdb/files/couchdb160
-rwxr-xr-xpuppet/modules/site_couchdb/files/leap_ca_daemon157
-rw-r--r--puppet/modules/site_couchdb/files/local.ini89
-rw-r--r--puppet/modules/site_couchdb/manifests/apache_ssl_proxy.pp25
-rw-r--r--puppet/modules/site_couchdb/manifests/configure.pp27
-rw-r--r--puppet/modules/site_couchdb/manifests/init.pp64
-rw-r--r--puppet/modules/site_nagios/files/configs/Debian/nagios.cfg1273
-rw-r--r--puppet/modules/site_nagios/manifests/add_host.pp31
-rw-r--r--puppet/modules/site_nagios/manifests/add_service.pp21
-rw-r--r--puppet/modules/site_nagios/manifests/init.pp4
-rw-r--r--puppet/modules/site_nagios/manifests/server.pp38
-rw-r--r--puppet/modules/site_nagios/manifests/server/purge.pp7
-rw-r--r--puppet/modules/site_openvpn/manifests/init.pp108
-rw-r--r--puppet/modules/site_openvpn/manifests/keys.pp51
-rw-r--r--puppet/modules/site_openvpn/manifests/resolver.pp36
-rw-r--r--puppet/modules/site_openvpn/manifests/server_config.pp166
-rw-r--r--puppet/modules/site_shorewall/manifests/couchdb.pp23
-rw-r--r--puppet/modules/site_shorewall/manifests/defaults.pp54
-rw-r--r--puppet/modules/site_shorewall/manifests/dnat_rule.pp25
-rw-r--r--puppet/modules/site_shorewall/manifests/eip.pp75
-rw-r--r--puppet/modules/site_shorewall/manifests/ip_forward.pp10
-rw-r--r--puppet/modules/site_shorewall/manifests/monitor.pp8
-rw-r--r--puppet/modules/site_shorewall/manifests/service/http.pp13
-rw-r--r--puppet/modules/site_shorewall/manifests/service/https.pp12
-rw-r--r--puppet/modules/site_shorewall/manifests/service/webapp_api.pp22
-rw-r--r--puppet/modules/site_shorewall/manifests/sshd.pp24
-rw-r--r--puppet/modules/site_shorewall/manifests/tor.pp25
-rw-r--r--puppet/modules/site_shorewall/manifests/webapp.pp6
-rw-r--r--puppet/modules/site_sshd/manifests/init.pp1
-rw-r--r--puppet/modules/site_sshd/manifests/ssh_key.pp3
-rw-r--r--puppet/modules/site_tor/manifests/disable_exit.pp7
-rw-r--r--puppet/modules/site_tor/manifests/init.pp28
-rw-r--r--puppet/modules/site_webapp/manifests/apache.pp65
-rw-r--r--puppet/modules/site_webapp/manifests/client_ca.pp25
-rw-r--r--puppet/modules/site_webapp/manifests/couchdb.pp16
-rw-r--r--puppet/modules/site_webapp/manifests/init.pp117
-rw-r--r--puppet/modules/site_webapp/templates/config.yml.erb5
-rw-r--r--puppet/modules/site_webapp/templates/couchdb.yml.erb8
m---------puppet/modules/sshd0
m---------puppet/modules/stdlib0
m---------puppet/modules/tor0
-rw-r--r--puppet/modules/try/README.md13
-rw-r--r--puppet/modules/try/manifests/file.pp51
-rw-r--r--puppet/modules/try/manifests/init.pp3
m---------puppet/modules/unbound0
m---------puppet/modules/vcsrepo8
m---------puppet/modules/x5090
107 files changed, 4686 insertions, 7 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..21966fc3
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,69 @@
+[submodule "puppet/modules/openvpn"]
+ path = puppet/modules/openvpn
+ url = git://github.com/luxflux/puppet-openvpn.git
+[submodule "puppet/modules/concat"]
+ path = puppet/modules/concat
+ url = git://code.leap.se/puppet_concat
+[submodule "puppet/modules/sshd"]
+ path = puppet/modules/sshd
+ url = git://labs.riseup.net/shared-sshd
+[submodule "puppet/modules/apt"]
+ path = puppet/modules/apt
+ url = git://code.leap.se/puppet_apt
+[submodule "puppet/modules/lsb"]
+ path = puppet/modules/lsb
+ url = git://labs.riseup.net/shared-lsb
+[submodule "puppet/modules/ntp"]
+ path = puppet/modules/ntp
+ url = git://github.com/puppetlabs/puppetlabs-ntp.git
+[submodule "puppet/modules/git"]
+ path = puppet/modules/git
+ url = git://code.leap.se/puppet_git
+[submodule "puppet/modules/common"]
+ path = puppet/modules/common
+ url = git://labs.riseup.net/shared-common
+[submodule "puppet/modules/shorewall"]
+ path = puppet/modules/shorewall
+ url = git://code.leap.se/puppet_shorewall
+[submodule "puppet/modules/resolvconf"]
+ path = puppet/modules/resolvconf
+ url = git://git.puppet.immerda.ch/module-resolvconf.git
+[submodule "puppet/modules/couchdb"]
+ path = puppet/modules/couchdb
+ url = git://code.leap.se/puppet_couchdb
+[submodule "puppet/modules/apache"]
+ path = puppet/modules/apache
+ url = git://code.leap.se/puppet_apache
+[submodule "puppet/modules/bundler"]
+ path = puppet/modules/bundler
+ url = git://code.leap.se/puppet_bundler
+[submodule "puppet/modules/vcsrepo"]
+ path = puppet/modules/vcsrepo
+ url = git://github.com/puppetlabs/puppetlabs-vcsrepo.git
+[submodule "puppet/modules/rubygems"]
+ path = puppet/modules/rubygems
+ url = git://code.leap.se/puppet_rubygems
+[submodule "puppet/modules/ruby"]
+ path = puppet/modules/ruby
+ url = git://code.leap.se/puppet_ruby
+[submodule "puppet/modules/x509"]
+ path = puppet/modules/x509
+ url = git://code.leap.se/puppet_x509
+[submodule "puppet/modules/passenger"]
+ path = puppet/modules/passenger
+ url = git://code.leap.se/puppet_passenger
+[submodule "puppet/modules/augeas"]
+ path = puppet/modules/augeas
+ url = git://code.leap.se/puppet_augeas
+[submodule "puppet/modules/stdlib"]
+ path = puppet/modules/stdlib
+ url = git://code.leap.se/puppet_stdlib
+[submodule "puppet/modules/unbound"]
+ path = puppet/modules/unbound
+ url = git://code.leap.se/puppet_unbound
+[submodule "puppet/modules/nagios"]
+ path = puppet/modules/nagios
+ url = git://code.leap.se/puppet_nagios
+[submodule "puppet/modules/tor"]
+ path = puppet/modules/tor
+ url = git://labs.riseup.net/shared-tor
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..94a9ed02
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/README.md b/README.md
index 16cc34ef..c41e27c7 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,83 @@
+=============
Leap Platform
=============
-... still under development, see README.md in the develop branch for details.
+What is it?
+===========
+
+The LEAP Provider Platform is the server-side part of the LEAP Encryption Access Project that is run by service providers. It consists of a set of complementary modules and recipes to automate the maintenance of LEAP services in a hardened GNU/Linux environment. LEAP makes it easy and straightforward for service providers and ISPs to deploy a secure communications platform for their users.
+
+The LEAP Platform is essentially a git repository of puppet recipes, with a few scripts to help with bootstrapping and deployment. A service provider who wants to deploy LEAP services will clone or fork this repository, edit the main configuration file to specify which services should run on which hosts, and run scripts to deploy this configuration.
+
+Documentation
+=============
+
+Most of the current documentation can be found in Readme files of the different pieces. This will be consolidated on the website https://leap.se soon.
+
+Requirements
+============
+
+This highly depends on your (expected) user base.
+For a minimal test or develop install we recommend a fairly recent computer x86_64 with hardware virtualization features (AMD-V or VT-x) with plenty of RAM.
+You could use Vagrant or KVM to simulate a live deployment.
+
+For a live deployment of the platform the amount of required (virtual) servers depends on your needs and which services you want to deploy.
+In it's initial release you can deploy Tor, OpenVPN, CouchDB and a webapp to administer your users (billing, help tickets,...).
+While you can deploy all services on one server, we stronly recommend to use seperate servers for better security.
+
+
+Usage
+=====
+
+As mentioned above, Leap Platform are the server-side Puppet manifests, for deploying a service provider, you need the leap command line interface,
+available here: https://github.com/leapcode/leap_cli
+
+We strongly recommend to follow the `Quick Start` Documentaion which can be found on the website https://leap.se
+
+
+Clone leap_platform and its submodules
+--------------------------------------
+
+ git checkout develop
+
+Initialize Submodules:
+
+ git submodule update --init
+
+
+More Information
+================
+
+For more information about the LEAP Encryption Access Project, please visit the website https://leap.se which also lists contact data.
+
+
+Copyright/License
+-----------------
+
+Read LICENSE
+
+
+Known bugs
+----------
+
+* currently none known, there will probably be some around !
+
+Troubleshooting
+---------------
+
+Visit https://leap.se/en/development for contact possibilities.
+
+Changelog
+---------
+
+For a changelog of the current branch:
+
+ git log
+
+Authors and Credits
+------------------
+
+See contributors:
+
+ git shortlog -es --all
-Stay tuned !
diff --git a/deploy.sh b/deploy.sh
deleted file mode 100755
index c8f89b90..00000000
--- a/deploy.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-puppet apply --modulepath=$PWD/puppet/modules $PWD/puppet/manifests/site.pp $@
diff --git a/provider_base/README b/provider_base/README
new file mode 100644
index 00000000..bb80df50
--- /dev/null
+++ b/provider_base/README
@@ -0,0 +1,9 @@
+This directory holds the base provider files that actual providers inherit from.
+
+For example:
+
+ the file........ myproject/provider/common.json
+ inherits from... myproject/leap_platform/provider_base/common.json
+
+
+
diff --git a/provider_base/common.json b/provider_base/common.json
new file mode 100644
index 00000000..e674edb6
--- /dev/null
+++ b/provider_base/common.json
@@ -0,0 +1,34 @@
+{
+ "ip_address": null,
+ "services": [],
+ "tags": [],
+ "domain": {
+ "full_suffix": "= global.provider.domain",
+ "internal_suffix": "= global.provider.domain_internal",
+ "full": "= node.name + '.' + domain.full_suffix",
+ "internal": "= node.name + '.' + domain.internal_suffix",
+ "name": "= node.name + '.' + (dns.public ? domain.full_suffix : domain.internal_suffix)"
+ },
+ "dns": {
+ "public": "= service_type != 'internal_service'"
+ },
+ "ssh": {
+ "authorized_keys": "= file :authorized_keys",
+ "known_hosts": "=> known_hosts_file",
+ "port": 22
+ },
+ "hosts": "=> hosts_file",
+ "x509": {
+ "use": false,
+ "cert": "= x509.use ? file(:node_x509_cert, :missing => 'x509 certificate for node $node. Run `leap cert update`') : nil",
+ "key": "= x509.use ? file(:node_x509_key, :missing => 'x509 key for node $node. Run `leap cert update`') : nil",
+ "ca_cert": "= try_file :ca_cert"
+ },
+ "local": false,
+ "production": false,
+ "service_type": "internal_service",
+ "development": {
+ "site_config": true
+ },
+ "name": "common"
+}
diff --git a/provider_base/files/branding/head.scss b/provider_base/files/branding/head.scss
new file mode 100644
index 00000000..c100a004
--- /dev/null
+++ b/provider_base/files/branding/head.scss
@@ -0,0 +1 @@
+// no head.scss set
diff --git a/provider_base/files/branding/tail.scss b/provider_base/files/branding/tail.scss
new file mode 100644
index 00000000..919aeec6
--- /dev/null
+++ b/provider_base/files/branding/tail.scss
@@ -0,0 +1 @@
+// no tail.scss set
diff --git a/provider_base/files/service-definitions/eip-service.json.erb b/provider_base/files/service-definitions/eip-service.json.erb
new file mode 100644
index 00000000..8dc7211d
--- /dev/null
+++ b/provider_base/files/service-definitions/eip-service.json.erb
@@ -0,0 +1,37 @@
+<%=
+ def underscore(words)
+ words = words.to_s.dup
+ words.downcase!
+ words.gsub! /[^a-z]/, '_'
+ words
+ end
+
+ hsh = {}
+ hsh["serial"] = 1
+ hsh["version"] = 1
+ clusters = {}
+ gateways = []
+ global.services['openvpn'].node_list.each_node do |node|
+ next if node.vagrant?
+ gateway = {}
+ gateway["capabilities"] = node.openvpn.pick(
+ :ports, :protocols, :user_ips, :adblock, :filter_dns)
+ gateway["capabilities"]["transport"] = ["openvpn"]
+ gateway["ip_address"] = node.openvpn.gateway_address
+ gateway["host"] = node.domain.full
+ gateway["cluster"] = underscore(node.openvpn.location)
+ gateways << gateway
+ clusters[gateway["cluster"]] ||= {
+ "name" => gateway["cluster"],
+ "label" => {"en" => node.openvpn.location}
+ }
+ end
+ hsh["gateways"] = gateways
+ hsh["clusters"] = clusters.values
+ hsh["openvpn_configuration"] = {
+ "tls-cipher" => "DHE-RSA-AES128-SHA",
+ "auth" => "SHA1",
+ "cipher" => "AES-128-CBC"
+ }
+ generate_json hsh
+%> \ No newline at end of file
diff --git a/provider_base/files/service-definitions/provider.json.erb b/provider_base/files/service-definitions/provider.json.erb
new file mode 100644
index 00000000..f26f25a2
--- /dev/null
+++ b/provider_base/files/service-definitions/provider.json.erb
@@ -0,0 +1,20 @@
+<%=
+ hsh = {}
+
+ # grab some fields from provider.json
+ hsh = global.provider.pick(
+ :languages, :description, :name,
+ :enrollment_policy, :default_language, :domain
+ )
+
+ # advertise services that are 'user services'
+ hsh['services'] = global.services[:service_type => :user_service].field(:name)
+
+ hsh['api_version'] = "1"
+ hsh['api_uri'] = "https://" + api.domain + ':' + api.port
+
+ hsh['ca_cert_uri'] = 'https://' + global.provider.domain + '/ca.crt'
+ hsh['ca_cert_fingerprint'] = fingerprint(:ca_cert)
+
+ generate_json hsh
+%> \ No newline at end of file
diff --git a/provider_base/provider.json b/provider_base/provider.json
new file mode 100644
index 00000000..8ce848f3
--- /dev/null
+++ b/provider_base/provider.json
@@ -0,0 +1,30 @@
+{
+ "domain": "REQUIRED",
+ "domain_internal": "= domain.sub(/\\..*$/,'.i')",
+ "name": {
+ "en": "REQUIRED"
+ },
+ "description": {
+ "en": "REQUIRED"
+ },
+ "contacts": {
+ "default": "REQUIRED"
+ },
+ "languages": ["en"],
+ "default_language": "en",
+ "enrollment_policy": "open",
+ "ca": {
+ "name": "= global.provider.ca.organization + ' Root CA'",
+ "organization": "= global.provider.name[global.provider.default_language]",
+ "organizational_unit": "= 'https://' + global.common.domain.full_suffix",
+ "bit_size": 4096,
+ "digest": "SHA256",
+ "life_span": "10y",
+ "server_certificates": {
+ "bit_size": 3248,
+ "digest": "SHA256",
+ "life_span": "1y"
+ }
+ },
+ "hiera_sync_destination": "/etc/leap"
+}
diff --git a/provider_base/services/ca.json b/provider_base/services/ca.json
new file mode 100644
index 00000000..3fb8bf6c
--- /dev/null
+++ b/provider_base/services/ca.json
@@ -0,0 +1,11 @@
+{
+ "ca_daemon": {
+ "couchdb_hosts": "= hostnames nodes[:services => :couchdb][:local => local]",
+ "couchdb_user": "= global.services[:couchdb].couch.users[:ca_daemon]"
+ },
+ "service_type": "internal_service",
+ "x509": {
+ "use": true,
+ "ca_key": "= file(:ca_key, :missing => 'CA key. Run `leap cert ca` to create the Certificate Authority.')"
+ }
+}
diff --git a/provider_base/services/couchdb.json b/provider_base/services/couchdb.json
new file mode 100644
index 00000000..1c8005c2
--- /dev/null
+++ b/provider_base/services/couchdb.json
@@ -0,0 +1,22 @@
+{
+ "service_type": "internal_service",
+ "x509": {
+ "use": true
+ },
+ "couch": {
+ "users": {
+ "admin": {
+ "username": "admin",
+ "password": "= secret :couch_admin_password"
+ },
+ "webapp": {
+ "username": "webapp",
+ "password": "= secret :couch_webapp_password"
+ },
+ "ca_daemon": {
+ "username": "ca_daemon",
+ "password": "= secret :couch_ca_daemon_password"
+ }
+ }
+ }
+}
diff --git a/provider_base/services/dns.json b/provider_base/services/dns.json
new file mode 100644
index 00000000..677d9b2c
--- /dev/null
+++ b/provider_base/services/dns.json
@@ -0,0 +1,7 @@
+{
+ "hosts": {
+ "public": "= nodes['dns.public' => true].fields('domain.name', 'dns.aliases', 'ip_address')",
+ "private": "= nodes['dns.public' => false].fields('domain.name', 'dns.aliases', 'ip_address')"
+ },
+ "service_type": "public_service"
+} \ No newline at end of file
diff --git a/provider_base/services/monitor.json b/provider_base/services/monitor.json
new file mode 100644
index 00000000..f5e4d922
--- /dev/null
+++ b/provider_base/services/monitor.json
@@ -0,0 +1,6 @@
+{
+ "nagios": {
+ "nagiosadmin_pw": "= secret :nagios_admin_password",
+ "hosts": "= nodes_like_me.fields('domain.internal', 'ip_address', 'services', 'openvpn.gateway_address')"
+ }
+}
diff --git a/provider_base/services/openvpn.json b/provider_base/services/openvpn.json
new file mode 100644
index 00000000..7b67ccb3
--- /dev/null
+++ b/provider_base/services/openvpn.json
@@ -0,0 +1,16 @@
+{
+ "service_type": "user_service",
+ "x509": {
+ "use": true,
+ "client_ca_cert": "= file :client_ca_cert, :missing => 'Certificate Authority. Run `leap cert ca`'",
+ "dh": "= file :dh_params, :missing => 'Diffie-Hellman parameters. Run `leap cert dh`'"
+ },
+ "openvpn": {
+ "location": "Location Unknown",
+ "ports": ["80", "443", "53", "1194"],
+ "protocols": ["tcp", "udp"],
+ "filter_dns": false,
+ "adblock": false,
+ "user_ips": false
+ }
+}
diff --git a/provider_base/services/tor.json b/provider_base/services/tor.json
new file mode 100644
index 00000000..9173b8d4
--- /dev/null
+++ b/provider_base/services/tor.json
@@ -0,0 +1,6 @@
+{
+ "tor": {
+ "bandwidth_rate": 6550,
+ "contacts": "= global.provider.contacts['tor'] || global.provider.contacts.default"
+ }
+}
diff --git a/provider_base/services/webapp.json b/provider_base/services/webapp.json
new file mode 100644
index 00000000..e3055c6f
--- /dev/null
+++ b/provider_base/services/webapp.json
@@ -0,0 +1,34 @@
+{
+ "webapp": {
+ "modules": ["user", "billing", "help"],
+ "couchdb_hosts": "= hostnames nodes[:services => :couchdb][:local => local]",
+ # NOTE: this is bad, but pending a fix to https://leap.se/code/issues/1163
+ # before we can use user "webapp"
+ "couchdb_user": "= global.services[:couchdb].couch.users[:admin]",
+ "favicon": "= file_path 'branding/favicon.ico'",
+ "tail_scss": "= file_path 'branding/tail.scss'",
+ "head_scss": "= file_path 'branding/head.scss'",
+ "img_dir": "= file_path 'branding/img'"
+ },
+ "definition_files": {
+ "provider": "= file :provider_json_template",
+ "eip_service": "= file :eip_service_json_template"
+ },
+ "service_type": "public_service",
+ "api": {
+ "domain": "= 'api.' + domain.full_suffix",
+ "port": "4430"
+ },
+ "dns": {
+ "aliases": "= [domain.full, api.domain]"
+ },
+ "x509": {
+ "use": true,
+ "ca_cert": "= file :ca_cert, :missing => 'provider CA. Run `leap cert ca`'",
+ "client_ca_cert": "= file_path :client_ca_cert",
+ "client_ca_key": "= file_path :client_ca_key",
+ "commercial_cert": "= file [:commercial_cert, global.provider.domain]",
+ "commercial_key": "= file [:commercial_key, global.provider.domain]",
+ "commercial_ca_cert": "= try_file :commercial_ca_cert"
+ }
+} \ No newline at end of file
diff --git a/provider_base/tags/local.json b/provider_base/tags/local.json
new file mode 100644
index 00000000..9cb16602
--- /dev/null
+++ b/provider_base/tags/local.json
@@ -0,0 +1,3 @@
+{
+ "local": true
+} \ No newline at end of file
diff --git a/provider_base/tags/production.json b/provider_base/tags/production.json
new file mode 100644
index 00000000..b35c0650
--- /dev/null
+++ b/provider_base/tags/production.json
@@ -0,0 +1,3 @@
+{
+ "production": true
+} \ No newline at end of file
diff --git a/provider_base/test/openvpn/client.ovpn.erb b/provider_base/test/openvpn/client.ovpn.erb
new file mode 100644
index 00000000..a0bdd307
--- /dev/null
+++ b/provider_base/test/openvpn/client.ovpn.erb
@@ -0,0 +1,26 @@
+client
+dev tun
+remote-cert-tls server
+remote-random
+nobind
+script-security 2
+verb 3
+auth SHA1
+cipher AES-128-CBC
+tls-cipher DHE-RSA-AES128-SHA
+
+<% vpn_nodes.each_node do |node| -%>
+<%= "remote #{node.openvpn.gateway_address} 1194 udp"%>
+<% end -%>
+
+<ca>
+<%= read_file! :ca_cert -%>
+</ca>
+
+<cert>
+<%= read_file! :test_client_cert -%>
+</cert>
+
+<key>
+<%= read_file! :test_client_key -%>
+</key>
diff --git a/puppet/hiera.yaml b/puppet/hiera.yaml
new file mode 100644
index 00000000..93448e23
--- /dev/null
+++ b/puppet/hiera.yaml
@@ -0,0 +1,15 @@
+---
+:backends:
+ - yaml
+ - puppet
+
+:logger: console
+
+:yaml:
+ :datadir: /etc/leap
+
+:hierarchy:
+ - hiera
+
+:puppet:
+ :datasource: data
diff --git a/puppet/lib/puppet/parser/functions/create_resources_hash_from.rb b/puppet/lib/puppet/parser/functions/create_resources_hash_from.rb
new file mode 100644
index 00000000..47d0df9c
--- /dev/null
+++ b/puppet/lib/puppet/parser/functions/create_resources_hash_from.rb
@@ -0,0 +1,116 @@
+#
+# create_resources_hash_from.rb
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+module Puppet::Parser::Functions
+ newfunction(:create_resources_hash_from, :type => :rvalue, :doc => <<-EOS
+Given:
+ A formatted string (to use as the resource name)
+ An array to loop through (because puppet cannot loop)
+ A hash defining the parameters for a resource
+ And optionally an hash of parameter names to add to the resource and an
+ associated formatted string that should be configured with the current
+ element of the loop array
+
+This function will return a hash of hashes that can be used with the
+create_resources function.
+
+*Examples:*
+ $allowed_hosts = ['10.0.0.0/8', '192.168.0.0/24']
+ $resource_name = "100 allow %s to apache on ports 80"
+ $my_resource_hash = {
+ 'proto' => 'tcp',
+ 'action' => 'accept',
+ 'dport' => 80
+ }
+ $dynamic_parameters = {
+ 'source' => '%s'
+ }
+
+ $created_resource_hash = create_resources_hash_from($resource_name, $allowed_hosts, $my_resource_hash, $dynamic_parameters)
+
+$created_resource_hash would equal:
+ {
+ '100 allow 10.0.0.0/8 to apache on ports 80' => {
+ 'proto' => 'tcp',
+ 'action' => 'accept',
+ 'dport' => 80,
+ 'source' => '10.0.0.0/8'
+ },
+ '100 allow 192.168.0.0/24 to apache on ports 80' => {
+ 'proto' => 'tcp',
+ 'action' => 'accept',
+ 'dport' => 80,
+ 'source' => '192.168.0.0/24'
+ }
+ }
+
+$created_resource_hash could then be used with create_resources
+
+ create_resources(firewall, $created_resource_hash)
+
+To create a bunch of resources in a way that would only otherwise be possible
+with a loop of some description.
+ EOS
+ ) do |arguments|
+
+ raise Puppet::ParseError, "create_resources_hash_from(): Wrong number of arguments " +
+ "given (#{arguments.size} for 3 or 4)" if arguments.size < 3 or arguments.size > 4
+
+ formatted_string = arguments[0]
+
+ unless formatted_string.is_a?(String)
+ raise(Puppet::ParseError, 'create_resources_hash_from(): first argument must be a string')
+ end
+
+ loop_array = arguments[1]
+
+ unless loop_array.is_a?(Array)
+ raise(Puppet::ParseError, 'create_resources_hash_from(): second argument must be an array')
+ end
+
+ resource_hash = arguments[2]
+ unless resource_hash.is_a?(Hash)
+ raise(Puppet::ParseError, 'create_resources_hash_from(): third argument must be a hash')
+ end
+
+ if arguments.size == 4
+ dynamic_parameters = arguments[3]
+ unless dynamic_parameters.is_a?(Hash)
+ raise(Puppet::ParseError, 'create_resources_hash_from(): fourth argument must be a hash')
+ end
+ end
+
+ result = {}
+
+ loop_array.each do |i|
+ my_resource_hash = resource_hash.clone
+ if dynamic_parameters
+ dynamic_parameters.each do |param, value|
+ if my_resource_hash.member?(param)
+ raise(Puppet::ParseError, "create_resources_hash_from(): dynamic_parameter '#{param}' already exists in resource hash")
+ end
+ my_resource_hash[param] = sprintf(value,[i])
+ end
+ end
+ result[sprintf(formatted_string,[i])] = my_resource_hash
+ end
+
+ result
+ end
+end
+
+# vim: set ts=2 sw=2 et :
+# encoding: utf-8
diff --git a/puppet/manifests/site.pp b/puppet/manifests/site.pp
index 3a136015..1ec806d9 100644
--- a/puppet/manifests/site.pp
+++ b/puppet/manifests/site.pp
@@ -1,3 +1,39 @@
-node "default" {
- notify {'Hello World':}
+# set a default exec path
+Exec { path => '/usr/bin:/usr/sbin/:/bin:/sbin:/usr/local/bin:/usr/local/sbin' }
+
+stage { 'initial':
+ before => Stage['main'],
+}
+
+import 'common'
+include site_config::default
+include site_config::slow
+
+# parse services for host
+$services=hiera_array('services')
+notice("Services for ${fqdn}: ${services}")
+
+# configure eip
+if 'openvpn' in $services {
+ include site_openvpn
+}
+
+if 'couchdb' in $services {
+ include site_couchdb
+}
+
+if 'webapp' in $services {
+ include site_webapp
+}
+
+if 'ca' in $services {
+ include site_ca_daemon
+}
+
+if 'monitor' in $services {
+ include site_nagios
+}
+
+if 'tor' in $services {
+ include site_tor
}
diff --git a/puppet/modules/apache b/puppet/modules/apache
new file mode 160000
+Subproject 077d4d1508b9ff3355f73ff8597991043b3ba5d
diff --git a/puppet/modules/apt b/puppet/modules/apt
new file mode 160000
+Subproject f16a0727dce187d07389388da8b816f7b520205
diff --git a/puppet/modules/augeas b/puppet/modules/augeas
new file mode 160000
+Subproject 4d8c8ba362cc57c12451e581f27feea97797e8c
diff --git a/puppet/modules/bundler b/puppet/modules/bundler
new file mode 160000
+Subproject b4a4a8434616247156e59b860b47cc6256ead8d
diff --git a/puppet/modules/common b/puppet/modules/common
new file mode 160000
+Subproject 0961ad453b8befb4ea61bbd19f6ecea32b9619c
diff --git a/puppet/modules/concat b/puppet/modules/concat
new file mode 160000
+Subproject abce1280e07b544d8455f1572dd870bbd2f1489
diff --git a/puppet/modules/couchdb b/puppet/modules/couchdb
new file mode 160000
+Subproject dcb8a082ac842b0660819ea61f9448c4e373746
diff --git a/puppet/modules/git b/puppet/modules/git
new file mode 160000
+Subproject 497a1034489e0dc3cab5dab2fb0a85778576973
diff --git a/puppet/modules/lsb b/puppet/modules/lsb
new file mode 160000
+Subproject 3742c1a00c5602154a81834443ec5b0ca32c4ca
diff --git a/puppet/modules/nagios b/puppet/modules/nagios
new file mode 160000
+Subproject 57a1140b437a8cfb9cfd5d94a5759b1e3ed86d4
diff --git a/puppet/modules/ntp b/puppet/modules/ntp
new file mode 160000
+Subproject 27f2bc72110b1001233eb0907aa07e06cdf3319
diff --git a/puppet/modules/openvpn b/puppet/modules/openvpn
new file mode 160000
+Subproject 25f1fe8d813f6128068d890a40f5e24be78fb47
diff --git a/puppet/modules/passenger b/puppet/modules/passenger
new file mode 160000
+Subproject d1b46de84acf4d9e3582b64e019935fb1125f9b
diff --git a/puppet/modules/resolvconf b/puppet/modules/resolvconf
new file mode 160000
+Subproject c7eca077fdda063edc96d3bea02c4774569e4b1
diff --git a/puppet/modules/ruby b/puppet/modules/ruby
new file mode 160000
+Subproject e4de25d78eefc7df70a35dee22a3e0dc1b7e1d0
diff --git a/puppet/modules/rubygems b/puppet/modules/rubygems
new file mode 160000
+Subproject 1e5ed3dbef9381bb9d5e2a7b4957bb3f5288d6a
diff --git a/puppet/modules/shorewall b/puppet/modules/shorewall
new file mode 160000
+Subproject e4a54e30bf2ad7fa45c73cc544e1da4524a287a
diff --git a/puppet/modules/site-apache b/puppet/modules/site-apache
new file mode 120000
index 00000000..f0517fa5
--- /dev/null
+++ b/puppet/modules/site-apache
@@ -0,0 +1 @@
+site_apache \ No newline at end of file
diff --git a/puppet/modules/site_apache/files/vhosts.d/couchdb_proxy.conf b/puppet/modules/site_apache/files/vhosts.d/couchdb_proxy.conf
new file mode 100644
index 00000000..0dff2cd6
--- /dev/null
+++ b/puppet/modules/site_apache/files/vhosts.d/couchdb_proxy.conf
@@ -0,0 +1,10 @@
+Listen 0.0.0.0:6984
+
+<VirtualHost *:6984>
+ SSLEngine On
+ SSLProxyEngine On
+ SSLCertificateKeyFile /etc/x509/keys/leap_couchdb.key
+ SSLCertificateFile /etc/x509/certs/leap_couchdb.crt
+ ProxyPass / http://127.0.0.1:5984/
+ ProxyPassReverse / http://127.0.0.1:5984/
+</VirtualHost>
diff --git a/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb
new file mode 100644
index 00000000..cdfcbd68
--- /dev/null
+++ b/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb
@@ -0,0 +1,39 @@
+<VirtualHost *:80>
+ ServerName <%= api_domain %>
+ RewriteEngine On
+ RewriteRule ^.*$ https://<%= api_domain -%>:<%= api_port -%>%{REQUEST_URI} [R=permanent,L]
+</VirtualHost>
+
+Listen 0.0.0.0:<%= api_port %>
+
+<VirtualHost *:<%= api_port -%>>
+ ServerName <%= api_domain %>
+
+ SSLEngine on
+ SSLProtocol -all +SSLv3 +TLSv1
+ SSLCipherSuite HIGH:MEDIUM:!aNULL:!SSLv2:!MD5:@STRENGTH
+ SSLHonorCipherOrder on
+
+ SSLCACertificatePath /etc/ssl/certs
+ SSLCertificateChainFile /etc/ssl/certs/leap_api.pem
+ SSLCertificateKeyFile /etc/x509/keys/leap_api.key
+ SSLCertificateFile /etc/x509/certs/leap_api.crt
+
+ RequestHeader set X_FORWARDED_PROTO 'https'
+
+ DocumentRoot /srv/leap-webapp/public
+ Alias /1 /srv/leap-webapp/public
+
+ # Check for maintenance file and redirect all requests
+ RewriteEngine On
+ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
+ RewriteCond %{SCRIPT_FILENAME} !maintenance.html
+ RewriteCond %{REQUEST_URI} !/images/maintenance.jpg
+ RewriteRule ^.*$ %{DOCUMENT_ROOT}/system/maintenance.html [L]
+
+ # http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerallowencodedslashes_lt_on_off_gt
+ AllowEncodedSlashes on
+ PassengerAllowEncodedSlashes on
+ PassengerFriendlyErrorPages off
+ SetEnv TMPDIR /var/tmp
+</VirtualHost>
diff --git a/puppet/modules/site_apache/templates/vhosts.d/leap_webapp.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/leap_webapp.conf.erb
new file mode 100644
index 00000000..4928cdd6
--- /dev/null
+++ b/puppet/modules/site_apache/templates/vhosts.d/leap_webapp.conf.erb
@@ -0,0 +1,47 @@
+<VirtualHost *:80>
+ ServerName <%= domain %>
+ ServerAlias www.<%= domain %>
+ RewriteEngine On
+ RewriteRule ^.*$ https://<%= domain -%>%{REQUEST_URI} [R=permanent,L]
+</VirtualHost>
+
+<VirtualHost *:443>
+ ServerName <%= domain %>
+ ServerAlias www.<%= domain %>
+
+ SSLEngine on
+ SSLProtocol -all +SSLv3 +TLSv1
+ SSLCipherSuite HIGH:MEDIUM:!aNULL:!SSLv2:!MD5:@STRENGTH
+ SSLHonorCipherOrder on
+
+ SSLCACertificatePath /etc/ssl/certs
+ SSLCertificateChainFile /etc/ssl/certs/leap_webapp.pem
+ SSLCertificateKeyFile /etc/x509/keys/leap_webapp.key
+ SSLCertificateFile /etc/x509/certs/leap_webapp.crt
+
+ RequestHeader set X_FORWARDED_PROTO 'https'
+
+ DocumentRoot /srv/leap-webapp/public
+ Alias /1 /srv/leap-webapp/public
+
+ RewriteEngine On
+ # Check for maintenance file and redirect all requests
+ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
+ RewriteCond %{SCRIPT_FILENAME} !maintenance.html
+ RewriteCond %{REQUEST_URI} !/images/maintenance.jpg
+ RewriteRule ^.*$ %{DOCUMENT_ROOT}/system/maintenance.html [L]
+
+ # http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengerallowencodedslashes_lt_on_off_gt
+ AllowEncodedSlashes on
+ PassengerAllowEncodedSlashes on
+ PassengerFriendlyErrorPages off
+ SetEnv TMPDIR /var/tmp
+
+ <% if (defined? @services) and (services.is_a? Array) and (@services.include? 'monitor') -%>
+ <DirectoryMatch (/usr/share/nagios3/htdocs|/usr/lib/cgi-bin/nagios3|/etc/nagios3/stylesheets)>
+ PassengerEnabled off
+ AllowOverride all
+ </DirectoryMatch>
+ <% end -%>
+</VirtualHost>
+
diff --git a/puppet/modules/site_apt/manifests/dist_upgrade.pp b/puppet/modules/site_apt/manifests/dist_upgrade.pp
new file mode 100644
index 00000000..f129dd73
--- /dev/null
+++ b/puppet/modules/site_apt/manifests/dist_upgrade.pp
@@ -0,0 +1,15 @@
+class site_apt::dist_upgrade {
+
+ if $::apt_running == 'true' {
+ fail ('apt-get is running in background - Please wait until it finishes. Exiting.')
+ } else {
+ exec{'initial_apt_update':
+ command => '/usr/bin/apt-get update && /usr/bin/apt-get autoclean',
+ refreshonly => false,
+ }
+ exec{'initial_apt_dist_upgrade':
+ command => "/usr/bin/apt-get -q -y -o 'DPkg::Options::=--force-confold' dist-upgrade",
+ refreshonly => false,
+ }
+ }
+}
diff --git a/puppet/modules/site_apt/manifests/init.pp b/puppet/modules/site_apt/manifests/init.pp
new file mode 100644
index 00000000..80c6fbde
--- /dev/null
+++ b/puppet/modules/site_apt/manifests/init.pp
@@ -0,0 +1,15 @@
+class site_apt {
+
+ include ::apt
+
+ apt::apt_conf { '90disable-pdiffs':
+ content => 'Acquire::PDiffs "false";';
+ }
+
+ include ::apt::unattended_upgrades
+
+ apt::sources_list { 'fallback.list.disabled':
+ content => template('site_apt/fallback.list');
+ }
+
+}
diff --git a/puppet/modules/site_apt/templates/fallback.list b/puppet/modules/site_apt/templates/fallback.list
new file mode 100644
index 00000000..41334b0b
--- /dev/null
+++ b/puppet/modules/site_apt/templates/fallback.list
@@ -0,0 +1,3 @@
+# basic
+deb http://ftp.debian.org/debian/ <%= lsbdistcodename %> main contrib non-free
+
diff --git a/puppet/modules/site_ca_daemon/manifests/apache.pp b/puppet/modules/site_ca_daemon/manifests/apache.pp
new file mode 100644
index 00000000..ab6b08fd
--- /dev/null
+++ b/puppet/modules/site_ca_daemon/manifests/apache.pp
@@ -0,0 +1,62 @@
+class site_ca_daemon::apache {
+
+ $api_domain = hiera('api_domain')
+ $x509 = hiera('x509')
+ $commercial_key = $x509['commercial_key']
+ $commercial_cert = $x509['commercial_cert']
+ $commercial_root = $x509['commercial_ca_cert']
+ $api_key = $x509['key']
+ $api_cert = $x509['cert']
+ $api_root = $x509['ca_cert']
+
+ $apache_no_default_site = true
+ include apache::ssl
+
+ apache::module {
+ 'alias': ensure => present;
+ 'rewrite': ensure => present;
+ 'headers': ensure => present;
+ }
+
+ class { 'passenger': use_munin => false }
+
+ apache::vhost::file {
+ 'leap_ca_daemon':
+ content => template('site_apache/vhosts.d/leap_ca_daemon.conf.erb')
+ }
+
+ apache::vhost::file {
+ 'api':
+ content => template('site_apache/vhosts.d/api.conf.erb')
+ }
+
+ x509::key {
+ 'leap_ca_daemon':
+ content => $commercial_key,
+ notify => Service[apache];
+
+ 'leap_api':
+ content => $api_key,
+ notify => Service[apache];
+ }
+
+ x509::cert {
+ 'leap_ca_daemon':
+ content => $commercial_cert,
+ notify => Service[apache];
+
+ 'leap_api':
+ content => $api_cert,
+ notify => Service[apache];
+ }
+
+ x509::ca {
+ 'leap_ca_daemon':
+ content => $commercial_root,
+ notify => Service[apache];
+
+ 'leap_api':
+ content => $api_root,
+ notify => Service[apache];
+ }
+}
diff --git a/puppet/modules/site_ca_daemon/manifests/couchdb.pp b/puppet/modules/site_ca_daemon/manifests/couchdb.pp
new file mode 100644
index 00000000..f446a05b
--- /dev/null
+++ b/puppet/modules/site_ca_daemon/manifests/couchdb.pp
@@ -0,0 +1,16 @@
+class site_ca_daemon::couchdb {
+
+ $ca = hiera('ca_daemon')
+ $couchdb_host = $ca['couchdb_hosts']
+ $couchdb_user = $ca['couchdb_user']['username']
+ $couchdb_password = $ca['couchdb_user']['password']
+
+ file {
+ '/etc/leap/leap_ca.yaml':
+ content => template('site_ca_daemon/leap_ca.yaml.erb'),
+ owner => leap_ca_daemon,
+ group => leap_ca_daemon,
+ mode => '0600';
+ }
+
+}
diff --git a/puppet/modules/site_ca_daemon/manifests/init.pp b/puppet/modules/site_ca_daemon/manifests/init.pp
new file mode 100644
index 00000000..8ba9c506
--- /dev/null
+++ b/puppet/modules/site_ca_daemon/manifests/init.pp
@@ -0,0 +1,103 @@
+class site_ca_daemon {
+ tag 'leap_service'
+ #$definition_files = hiera('definition_files')
+ #$provider = $definition_files['provider']
+ #$eip_service = $definition_files['eip_service']
+ $x509 = hiera('x509')
+
+ Class[Ruby] -> Class[rubygems] -> Class[bundler::install]
+
+ class { 'ruby': ruby_version => '1.9.3' }
+
+ class { 'bundler::install': install_method => 'package' }
+
+ include rubygems
+ #include site_ca_daemon::apache
+ include site_ca_daemon::couchdb
+
+ group { 'leap_ca_daemon':
+ ensure => present,
+ allowdupe => false;
+ }
+
+ user { 'leap_ca_daemon':
+ ensure => present,
+ allowdupe => false,
+ gid => 'leap_ca_daemon',
+ home => '/srv/leap_ca_daemon',
+ require => [ Group['leap_ca_daemon'] ];
+ }
+
+
+ x509::key {
+ 'leap_ca_daemon':
+ content => $x509['ca_key'];
+ #notify => Service['leap_ca_daemon']; <== no service yet for leap_ca_daemon
+ }
+
+ x509::cert {
+ 'leap_ca_daemon':
+ content => $x509['ca_cert'];
+ #notify => Service['leap_ca_daemon']; <== no service yet for leap_ca_daemon
+ }
+
+ #
+ # Does CA need a server key/cert? I think not now.
+ #
+ # x509::key {
+ # 'server':
+ # content => $x509['key'];
+ # }
+ #
+ # x509::cert {
+ # 'server':
+ # content => $x509['cert'];
+ # }
+
+ # x509::ca {
+ # 'leap_ca_daemon':
+ # content => $x509['ca_cert'];
+ # }
+
+
+ file { '/srv/leap_ca_daemon':
+ ensure => directory,
+ owner => 'leap_ca_daemon',
+ group => 'leap_ca_daemon',
+ require => User['leap_ca_daemon'];
+ }
+
+ vcsrepo { '/srv/leap_ca_daemon':
+ ensure => present,
+ revision => 'origin/master',
+ provider => git,
+ source => 'git://code.leap.se/leap_ca',
+ owner => 'leap_ca_daemon',
+ group => 'leap_ca_daemon',
+ require => [ User['leap_ca_daemon'], Group['leap_ca_daemon'] ],
+ notify => Exec['bundler_update']
+ }
+
+ exec { 'bundler_update':
+ cwd => '/srv/leap_ca_daemon',
+ command => '/bin/bash -c "/usr/bin/bundle check || /usr/bin/bundle install"',
+ unless => '/usr/bin/bundle check',
+ timeout => 600,
+ require => [ Class['bundler::install'], Vcsrepo['/srv/leap_ca_daemon'] ];
+ }
+
+ file { '/usr/local/bin/leap_ca_daemon':
+ ensure => link,
+ target => '/srv/leap_ca_daemon/bin/leap_ca_daemon',
+ }
+
+ file { '/etc/cron.hourly/leap_ca':
+ ensure => present,
+ content => "#/bin/sh\n/srv/leap_ca_daemon/bin/leap_ca_daemon --run-once > /dev/null",
+ owner => 'root',
+ group => 0,
+ mode => '0755',
+ }
+
+
+}
diff --git a/puppet/modules/site_ca_daemon/templates/leap_ca.yaml.erb b/puppet/modules/site_ca_daemon/templates/leap_ca.yaml.erb
new file mode 100644
index 00000000..e0b95278
--- /dev/null
+++ b/puppet/modules/site_ca_daemon/templates/leap_ca.yaml.erb
@@ -0,0 +1,31 @@
+#
+# Default configuration options for LEAP Certificate Authority Daemon
+#
+
+#
+# Certificate Authority
+#
+ca_key_path: "/etc/x509/keys/leap_ca_daemon.key"
+ca_key_password: nil
+ca_cert_path: "/etc/x509/certs/leap_ca_daemon.crt"
+
+#
+# Certificate pool
+#
+max_pool_size: 100
+client_cert_lifespan: 2
+client_cert_bit_size: 2024
+client_cert_hash: "SHA256"
+
+#
+# Database
+#
+db_name: "client_certificates"
+couch_connection:
+ protocol: "https"
+ host: <%= couchdb_host %>
+ port: 6984
+ username: <%= couchdb_user %>
+ password: <%= couchdb_password %>
+ prefix: ""
+ suffix: ""
diff --git a/puppet/modules/site_config/lib/facter/ip_interface.rb b/puppet/modules/site_config/lib/facter/ip_interface.rb
new file mode 100644
index 00000000..45764bfc
--- /dev/null
+++ b/puppet/modules/site_config/lib/facter/ip_interface.rb
@@ -0,0 +1,13 @@
+require 'facter/util/ip'
+
+Facter::Util::IP.get_interfaces.each do |interface|
+ ip = Facter.value("ipaddress_#{interface}")
+ if ip != nil
+ Facter.add("interface_" + ip ) do
+ setcode do
+ interface
+ end
+ end
+ end
+end
+
diff --git a/puppet/modules/site_config/manifests/caching_resolver.pp b/puppet/modules/site_config/manifests/caching_resolver.pp
new file mode 100644
index 00000000..922c394f
--- /dev/null
+++ b/puppet/modules/site_config/manifests/caching_resolver.pp
@@ -0,0 +1,41 @@
+class site_config::caching_resolver {
+
+ # Setup a conf.d directory to place additional unbound configuration files.
+ # There must be at least one file in the directory, or unbound will not start,
+ # so create an empty placeholder to ensure this.
+
+ # Note: the version of unbound we are working with does not accept a wildcard
+ # for an include directive, so we are not able to use this. When we can use
+ # the newer unbound, then we will add 'include: /etc/unbound.d/*' to the
+ # configuration file
+
+ file {
+ '/etc/unbound/conf.d':
+ ensure => directory,
+ owner => root, group => root, mode => '0755',
+ require => Package['unbound'];
+
+ '/etc/unbound/conf.d/placeholder':
+ ensure => present,
+ content => '',
+ owner => root, group => root, mode => '0644';
+ }
+
+ class { 'unbound':
+ root_hints => false,
+ anchor => false,
+ ssl => false,
+ require => File['/etc/unbound/conf.d/placeholder'],
+ settings => {
+ server => {
+ verbosity => '1',
+ interface => [ '127.0.0.1', '::1' ],
+ port => '53',
+ hide-identity => 'yes',
+ hide-version => 'yes',
+ harden-glue => 'yes',
+ access-control => [ '127.0.0.0/8 allow', '::1 allow' ]
+ }
+ }
+ }
+}
diff --git a/puppet/modules/site_config/manifests/default.pp b/puppet/modules/site_config/manifests/default.pp
new file mode 100644
index 00000000..2191e9a1
--- /dev/null
+++ b/puppet/modules/site_config/manifests/default.pp
@@ -0,0 +1,36 @@
+class site_config::default {
+ tag 'leap_base'
+
+ $domain_hash = hiera('domain')
+
+ include concat::setup
+
+ # default class, used by all hosts
+
+ include lsb, git
+
+ # configure apt
+ include site_apt
+
+
+ # configure ssh and include ssh-keys
+ include site_config::sshd
+
+ # configure /etc/resolv.conf
+ include site_config::resolvconf
+
+ # configure caching, local resolver
+ include site_config::caching_resolver
+
+ # configure /etc/hosts
+ class { 'site_config::hosts':
+ stage => initial,
+ }
+
+ package { [ 'etckeeper' ]:
+ ensure => installed,
+ }
+
+ # include basic shorewall config
+ include site_shorewall::defaults
+}
diff --git a/puppet/modules/site_config/manifests/hosts.pp b/puppet/modules/site_config/manifests/hosts.pp
new file mode 100644
index 00000000..6c00f3b6
--- /dev/null
+++ b/puppet/modules/site_config/manifests/hosts.pp
@@ -0,0 +1,22 @@
+class site_config::hosts() {
+
+ $hosts = hiera('hosts','')
+ $hostname = hiera('name')
+
+ $domain_public = $site_config::default::domain_hash['full_suffix']
+
+ file { "/etc/hostname":
+ ensure => present,
+ content => $hostname
+ }
+
+ exec { "/bin/hostname $hostname":
+ subscribe => [ File['/etc/hostname'], File['/etc/hosts'] ],
+ refreshonly => true;
+ }
+
+ file { '/etc/hosts':
+ content => template('site_config/hosts'),
+ mode => '0644', owner => root, group => root;
+ }
+}
diff --git a/puppet/modules/site_config/manifests/resolvconf.pp b/puppet/modules/site_config/manifests/resolvconf.pp
new file mode 100644
index 00000000..d73f0b78
--- /dev/null
+++ b/puppet/modules/site_config/manifests/resolvconf.pp
@@ -0,0 +1,24 @@
+class site_config::resolvconf {
+
+ # bind9 purging can be taken out after some time
+ package { 'bind9':
+ ensure => absent,
+ }
+ file { '/etc/default/bind9':
+ ensure => absent;
+ }
+ file { '/etc/bind/named.conf.options':
+ ensure => absent;
+ }
+
+ $domain_public = $site_config::default::domain_hash['full_suffix']
+
+ # 127.0.0.1: caching-only local bind
+ # 87.118.100.175: http://server.privacyfoundation.de
+ # 62.141.58.13: http://www.privacyfoundation.ch/de/service/server.html
+ class { '::resolvconf':
+ domain => $domain_public,
+ search => $domain_public,
+ nameservers => [ '127.0.0.1', '87.118.100.175', '62.141.58.13' ]
+ }
+}
diff --git a/puppet/modules/site_config/manifests/slow.pp b/puppet/modules/site_config/manifests/slow.pp
new file mode 100644
index 00000000..18b22a9c
--- /dev/null
+++ b/puppet/modules/site_config/manifests/slow.pp
@@ -0,0 +1,6 @@
+class site_config::slow {
+ tag 'leap_slow'
+ class { 'site_apt::dist_upgrade':
+ stage => initial,
+ }
+}
diff --git a/puppet/modules/site_config/manifests/sshd.pp b/puppet/modules/site_config/manifests/sshd.pp
new file mode 100644
index 00000000..944dbce2
--- /dev/null
+++ b/puppet/modules/site_config/manifests/sshd.pp
@@ -0,0 +1,9 @@
+class site_config::sshd {
+ # configure sshd
+ include sshd
+ include site_sshd
+ # no need for configuring authorized_keys as leap_cli cares for that
+ #$ssh_pubkeys=hiera_hash('ssh_pubkeys')
+ #notice($ssh_pubkeys)
+ #create_resources('site_sshd::ssh_key', $ssh_pubkeys)
+}
diff --git a/puppet/modules/site_config/templates/hosts b/puppet/modules/site_config/templates/hosts
new file mode 100644
index 00000000..00cc6a79
--- /dev/null
+++ b/puppet/modules/site_config/templates/hosts
@@ -0,0 +1,15 @@
+# This file is managed by puppet, any changes will be overwritten!
+
+127.0.0.1 localhost
+127.0.1.1 <%= hostname %>.<%= @domain_public %> <%= hostname %>
+
+<%- if hosts.to_s != '' then -%>
+<%= hosts %>
+<% end -%>
+
+# The following lines are desirable for IPv6 capable hosts
+::1 ip6-localhost ip6-loopback
+fe00::0 ip6-localnet
+ff00::0 ip6-mcastprefix
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
diff --git a/puppet/modules/site_couchdb/files/couchdb b/puppet/modules/site_couchdb/files/couchdb
new file mode 100755
index 00000000..ccdfe716
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/couchdb
@@ -0,0 +1,160 @@
+#!/bin/sh -e
+
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+### BEGIN INIT INFO
+# Provides: couchdb
+# Required-Start: $local_fs $remote_fs
+# Required-Stop: $local_fs $remote_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Apache CouchDB init script
+# Description: Apache CouchDB init script for the database server.
+### END INIT INFO
+
+SCRIPT_OK=0
+SCRIPT_ERROR=1
+
+DESCRIPTION="database server"
+NAME=couchdb
+SCRIPT_NAME=`basename $0`
+COUCHDB=/usr/bin/couchdb
+CONFIGURATION_FILE=/etc/default/couchdb
+RUN_DIR=/var/run/couchdb
+LSB_LIBRARY=/lib/lsb/init-functions
+
+if test ! -x $COUCHDB; then
+ exit $SCRIPT_ERROR
+fi
+
+if test -r $CONFIGURATION_FILE; then
+ . $CONFIGURATION_FILE
+fi
+
+log_daemon_msg () {
+ # Dummy function to be replaced by LSB library.
+
+ echo $@
+}
+
+log_end_msg () {
+ # Dummy function to be replaced by LSB library.
+
+ if test "$1" != "0"; then
+ echo "Error with $DESCRIPTION: $NAME"
+ fi
+ return $1
+}
+
+if test -r $LSB_LIBRARY; then
+ . $LSB_LIBRARY
+fi
+
+run_command () {
+ command="$1"
+ if test -n "$COUCHDB_OPTIONS"; then
+ command="$command $COUCHDB_OPTIONS"
+ fi
+ if test -n "$COUCHDB_USER"; then
+ if su $COUCHDB_USER -c "$command"; then
+ return $SCRIPT_OK
+ else
+ return $SCRIPT_ERROR
+ fi
+ else
+ if $command; then
+ return $SCRIPT_OK
+ else
+ return $SCRIPT_ERROR
+ fi
+ fi
+}
+
+start_couchdb () {
+ # Start Apache CouchDB as a background process.
+
+ mkdir -p "$RUN_DIR"
+ chown -R "$COUCHDB_USER" "$RUN_DIR"
+ command="$COUCHDB -b"
+ if test -n "$COUCHDB_STDOUT_FILE"; then
+ command="$command -o $COUCHDB_STDOUT_FILE"
+ fi
+ if test -n "$COUCHDB_STDERR_FILE"; then
+ command="$command -e $COUCHDB_STDERR_FILE"
+ fi
+ if test -n "$COUCHDB_RESPAWN_TIMEOUT"; then
+ command="$command -r $COUCHDB_RESPAWN_TIMEOUT"
+ fi
+ run_command "$command" > /dev/null
+}
+
+stop_couchdb () {
+ # Stop the running Apache CouchDB process.
+
+ run_command "$COUCHDB -d" > /dev/null
+ pkill -u couchdb
+ # always return true even if no remaining couchdb procs got killed
+ /bin/true
+}
+
+display_status () {
+ # Display the status of the running Apache CouchDB process.
+
+ run_command "$COUCHDB -s"
+}
+
+parse_script_option_list () {
+ # Parse arguments passed to the script and take appropriate action.
+
+ case "$1" in
+ start)
+ log_daemon_msg "Starting $DESCRIPTION" $NAME
+ if start_couchdb; then
+ log_end_msg $SCRIPT_OK
+ else
+ log_end_msg $SCRIPT_ERROR
+ fi
+ ;;
+ stop)
+ log_daemon_msg "Stopping $DESCRIPTION" $NAME
+ if stop_couchdb; then
+ log_end_msg $SCRIPT_OK
+ else
+ log_end_msg $SCRIPT_ERROR
+ fi
+ ;;
+ restart|force-reload)
+ log_daemon_msg "Restarting $DESCRIPTION" $NAME
+ if stop_couchdb; then
+ if start_couchdb; then
+ log_end_msg $SCRIPT_OK
+ else
+ log_end_msg $SCRIPT_ERROR
+ fi
+ else
+ log_end_msg $SCRIPT_ERROR
+ fi
+ ;;
+ status)
+ display_status
+ ;;
+ *)
+ cat << EOF >&2
+Usage: $SCRIPT_NAME {start|stop|restart|force-reload|status}
+EOF
+ exit $SCRIPT_ERROR
+ ;;
+ esac
+}
+
+parse_script_option_list $@
diff --git a/puppet/modules/site_couchdb/files/leap_ca_daemon b/puppet/modules/site_couchdb/files/leap_ca_daemon
new file mode 100755
index 00000000..9a1a0bc7
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/leap_ca_daemon
@@ -0,0 +1,157 @@
+#! /bin/sh
+### BEGIN INIT INFO
+# Provides: leap_ca_daemon
+# Required-Start: $remote_fs $syslog
+# Required-Stop: $remote_fs $syslog
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: leap_ca_daemon initscript
+# Description: Controls leap_ca_daemon (see https://github.com/leapcode/leap_ca
+# for more information.
+### END INIT INFO
+
+# Author: varac <varac@leap.se>
+#
+
+# Do NOT "set -e"
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+DESC="leap_ca_daemon initscript"
+NAME=leap_ca_daemon
+DAEMON=/usr/local/bin/$NAME
+DAEMON_ARGS="run "
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
+
+# Read configuration variable file if it is present
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
+
+# Load the VERBOSE setting and other rcS variables
+. /lib/init/vars.sh
+
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
+# and status_of_proc is working.
+. /lib/lsb/init-functions
+
+#
+# Function that starts the daemon/service
+#
+do_start()
+{
+ # Return
+ # 0 if daemon has been started
+ # 1 if daemon was already running
+ # 2 if daemon could not be started
+ start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
+ || return 1
+ start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
+ $DAEMON_ARGS \
+ || return 2
+ # Add code here, if necessary, that waits for the process to be ready
+ # to handle requests from services started subsequently which depend
+ # on this one. As a last resort, sleep for some time.
+}
+
+#
+# Function that stops the daemon/service
+#
+do_stop()
+{
+ # Return
+ # 0 if daemon has been stopped
+ # 1 if daemon was already stopped
+ # 2 if daemon could not be stopped
+ # other if a failure occurred
+ start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
+ RETVAL="$?"
+ [ "$RETVAL" = 2 ] && return 2
+ # Wait for children to finish too if this is a daemon that forks
+ # and if the daemon is only ever run from this initscript.
+ # If the above conditions are not satisfied then add some other code
+ # that waits for the process to drop all resources that could be
+ # needed by services started subsequently. A last resort is to
+ # sleep for some time.
+ start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
+ [ "$?" = 2 ] && return 2
+ # Many daemons don't delete their pidfiles when they exit.
+ rm -f $PIDFILE
+ return "$RETVAL"
+}
+
+#
+# Function that sends a SIGHUP to the daemon/service
+#
+do_reload() {
+ #
+ # If the daemon can reload its configuration without
+ # restarting (for example, when it is sent a SIGHUP),
+ # then implement that here.
+ #
+ start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
+ return 0
+}
+
+case "$1" in
+ start)
+ [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+ do_start
+ case "$?" in
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+ esac
+ ;;
+ stop)
+ [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+ esac
+ ;;
+ status)
+ status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
+ ;;
+ #reload|force-reload)
+ #
+ # If do_reload() is not implemented then leave this commented out
+ # and leave 'force-reload' as an alias for 'restart'.
+ #
+ #log_daemon_msg "Reloading $DESC" "$NAME"
+ #do_reload
+ #log_end_msg $?
+ #;;
+ restart|force-reload)
+ #
+ # If the "reload" option is implemented then remove the
+ # 'force-reload' alias
+ #
+ log_daemon_msg "Restarting $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1)
+ do_start
+ case "$?" in
+ 0) log_end_msg 0 ;;
+ 1) log_end_msg 1 ;; # Old process is still running
+ *) log_end_msg 1 ;; # Failed to start
+ esac
+ ;;
+ *)
+ # Failed to stop
+ log_end_msg 1
+ ;;
+ esac
+ ;;
+ *)
+ #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
+ echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+ exit 3
+ ;;
+esac
+
+:
diff --git a/puppet/modules/site_couchdb/files/local.ini b/puppet/modules/site_couchdb/files/local.ini
new file mode 100644
index 00000000..b3376cbb
--- /dev/null
+++ b/puppet/modules/site_couchdb/files/local.ini
@@ -0,0 +1,89 @@
+; CouchDB Configuration Settings
+
+; Custom settings should be made in this file. They will override settings
+; in default.ini, but unlike changes made to default.ini, this file won't be
+; overwritten on server upgrade.
+
+[couchdb]
+;max_document_size = 4294967296 ; bytes
+
+[httpd]
+;port = 5984
+;bind_address = 127.0.0.1
+; Options for the MochiWeb HTTP server.
+;server_options = [{backlog, 128}, {acceptor_pool_size, 16}]
+; For more socket options, consult Erlang's module 'inet' man page.
+;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}]
+
+; Uncomment next line to trigger basic-auth popup on unauthorized requests.
+;WWW-Authenticate = Basic realm="administrator"
+
+; Uncomment next line to set the configuration modification whitelist. Only
+; whitelisted values may be changed via the /_config URLs. To allow the admin
+; to change this value over HTTP, remember to include {httpd,config_whitelist}
+; itself. Excluding it from the list would require editing this file to update
+; the whitelist.
+;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}]
+
+[httpd_global_handlers]
+;_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>}
+
+# enable futon
+_utils = {couch_httpd_misc_handlers, handle_utils_dir_req, "/usr/share/couchdb/www"}
+# disable futon
+#_utils = {couch_httpd_misc_handlers, handle_welcome_req, <<"Welcome, Futon is disabled!">>}
+
+[couch_httpd_auth]
+; If you set this to true, you should also uncomment the WWW-Authenticate line
+; above. If you don't configure a WWW-Authenticate header, CouchDB will send
+; Basic realm="server" in order to prevent you getting logged out.
+; require_valid_user = false
+
+[log]
+;level = debug
+
+[os_daemons]
+; For any commands listed here, CouchDB will attempt to ensure that
+; the process remains alive while CouchDB runs as well as shut them
+; down when CouchDB exits.
+;foo = /path/to/command -with args
+
+[daemons]
+; enable SSL support by uncommenting the following line and supply the PEM's below.
+; the default ssl port CouchDB listens on is 6984
+;httpsd = {couch_httpd, start_link, [https]}
+
+[ssl]
+;cert_file = /etc/couchdb/server_cert.pem
+;key_file = /etc/couchdb/server_key.pem
+;password = somepassword
+; set to true to validate peer certificates
+;verify_ssl_certificates = false
+; Path to file containing PEM encoded CA certificates (trusted
+; certificates used for verifying a peer certificate). May be omitted if
+; you do not want to verify the peer.
+;cacert_file = /full/path/to/cacertf
+; The verification fun (optionnal) if not specidied, the default
+; verification fun will be used.
+;verify_fun = {Module, VerifyFun}
+;ssl_certificate_max_depth = 1
+; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to
+; the Virual Host will be redirected to the path. In the example below all requests
+; to http://example.com/ are redirected to /database.
+; If you run CouchDB on a specific port, include the port number in the vhost:
+; example.com:5984 = /database
+
+[vhosts]
+;example.com = /database/
+
+[update_notification]
+;unique notifier name=/full/path/to/exe -with "cmd line arg"
+
+; To create an admin account uncomment the '[admins]' section below and add a
+; line in the format 'username = password'. When you next start CouchDB, it
+; will change the password to a hash (so that your passwords don't linger
+; around in plain-text files). You can add more admin accounts with more
+; 'username = password' lines. Don't forget to restart CouchDB after
+; changing this.
+;[admins]
+;admin = mysecretpassword
diff --git a/puppet/modules/site_couchdb/manifests/apache_ssl_proxy.pp b/puppet/modules/site_couchdb/manifests/apache_ssl_proxy.pp
new file mode 100644
index 00000000..7739473e
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/apache_ssl_proxy.pp
@@ -0,0 +1,25 @@
+define site_couchdb::apache_ssl_proxy ($key, $cert) {
+
+ $apache_no_default_site = true
+ include apache
+ apache::module {
+ 'proxy': ensure => present;
+ 'proxy_http': ensure => present;
+ 'rewrite': ensure => present;
+ 'ssl': ensure => present;
+ }
+ apache::vhost::file { 'couchdb_proxy': }
+
+ x509::key {
+ 'leap_couchdb':
+ content => $key,
+ notify => Service[apache];
+ }
+
+ x509::cert {
+ 'leap_couchdb':
+ content => $cert,
+ notify => Service[apache];
+ }
+
+}
diff --git a/puppet/modules/site_couchdb/manifests/configure.pp b/puppet/modules/site_couchdb/manifests/configure.pp
new file mode 100644
index 00000000..333511b5
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/configure.pp
@@ -0,0 +1,27 @@
+class site_couchdb::configure {
+
+ file { '/etc/init.d/couchdb':
+ source => 'puppet:///modules/site_couchdb/couchdb',
+ mode => '0755',
+ owner => 'root',
+ group => 'root',
+ }
+
+ file { '/etc/couchdb/local.d/admin.ini':
+ content => "[admins]
+admin = $site_couchdb::couchdb_admin_pw
+",
+ mode => '0600',
+ owner => 'couchdb',
+ group => 'couchdb',
+ notify => Service[couchdb]
+ }
+
+
+ exec { '/etc/init.d/couchdb restart; sleep 6':
+ path => ['/bin', '/usr/bin',],
+ subscribe => File['/etc/couchdb/local.d/admin.ini',
+ '/etc/couchdb/local.ini'],
+ refreshonly => true
+ }
+}
diff --git a/puppet/modules/site_couchdb/manifests/init.pp b/puppet/modules/site_couchdb/manifests/init.pp
new file mode 100644
index 00000000..9ecde5e6
--- /dev/null
+++ b/puppet/modules/site_couchdb/manifests/init.pp
@@ -0,0 +1,64 @@
+class site_couchdb {
+ tag 'leap_service'
+ include couchdb
+
+ $x509 = hiera('x509')
+ $key = $x509['key']
+ $cert = $x509['cert']
+ $couchdb_config = hiera('couch')
+ $couchdb_users = $couchdb_config['users']
+ $couchdb_admin = $couchdb_users['admin']
+ $couchdb_admin_user = $couchdb_admin['username']
+ $couchdb_admin_pw = $couchdb_admin['password']
+ $couchdb_webapp = $couchdb_users['webapp']
+ $couchdb_webapp_user = $couchdb_webapp['username']
+ $couchdb_webapp_pw = $couchdb_webapp['password']
+ $couchdb_ca_daemon = $couchdb_users['ca_daemon']
+ $couchdb_ca_daemon_user = $couchdb_ca_daemon['username']
+ $couchdb_ca_daemon_pw = $couchdb_ca_daemon['password']
+
+ Package ['couchdb']
+ -> File['/etc/init.d/couchdb']
+ -> File['/etc/couchdb/local.ini']
+ -> File['/etc/couchdb/local.d/admin.ini']
+ -> File['/etc/couchdb/couchdb.netrc']
+ -> Couchdb::Create_db['users']
+ -> Couchdb::Create_db['client_certificates']
+ -> Couchdb::Add_user[$couchdb_webapp_user]
+ -> Couchdb::Add_user[$couchdb_ca_daemon_user]
+ -> Site_couchdb::Apache_ssl_proxy['apache_ssl_proxy']
+
+ include site_couchdb::configure
+ include couchdb::deploy_config
+
+ site_couchdb::apache_ssl_proxy { 'apache_ssl_proxy':
+ key => $key,
+ cert => $cert
+ }
+
+ couchdb::query::setup { 'localhost':
+ user => $couchdb_admin_user,
+ pw => $couchdb_admin_pw
+ }
+
+ # Populate couchdb
+ couchdb::add_user { $couchdb_webapp_user:
+ roles => '["certs"]',
+ pw => $couchdb_webapp_pw
+ }
+
+ couchdb::add_user { $couchdb_ca_daemon_user:
+ roles => '["certs"]',
+ pw => $couchdb_ca_daemon_pw
+ }
+
+ couchdb::create_db { 'users':
+ readers => "{ \"names\": [\"$couchdb_webapp_user\"], \"roles\": [] }"
+ }
+
+ couchdb::create_db { 'client_certificates':
+ readers => "{ \"names\": [], \"roles\": [\"certs\"] }"
+ }
+
+ include site_shorewall::couchdb
+}
diff --git a/puppet/modules/site_nagios/files/configs/Debian/nagios.cfg b/puppet/modules/site_nagios/files/configs/Debian/nagios.cfg
new file mode 100644
index 00000000..753d1610
--- /dev/null
+++ b/puppet/modules/site_nagios/files/configs/Debian/nagios.cfg
@@ -0,0 +1,1273 @@
+##############################################################################
+#
+# NAGIOS.CFG - Sample Main Config File for Nagios
+#
+#
+##############################################################################
+
+
+# LOG FILE
+# This is the main log file where service and host events are logged
+# for historical purposes. This should be the first option specified
+# in the config file!!!
+
+log_file=/var/log/nagios3/nagios.log
+
+
+
+# OBJECT CONFIGURATION FILE(S)
+# These are the object configuration files in which you define hosts,
+# host groups, contacts, contact groups, services, etc.
+# You can split your object definitions across several config files
+# if you wish (as shown below), or keep them all in a single config file.
+#cfg_file=/etc/nagios3/commands.cfg
+
+# Puppet-managed configuration files
+cfg_dir=/etc/nagios3/conf.d
+
+# Debian also defaults to using the check commands defined by the debian
+# nagios-plugins package
+cfg_dir=/etc/nagios-plugins/config
+
+
+
+# OBJECT CACHE FILE
+# This option determines where object definitions are cached when
+# Nagios starts/restarts. The CGIs read object definitions from
+# this cache file (rather than looking at the object config files
+# directly) in order to prevent inconsistencies that can occur
+# when the config files are modified after Nagios starts.
+
+object_cache_file=/var/cache/nagios3/objects.cache
+
+
+
+# PRE-CACHED OBJECT FILE
+# This options determines the location of the precached object file.
+# If you run Nagios with the -p command line option, it will preprocess
+# your object configuration file(s) and write the cached config to this
+# file. You can then start Nagios with the -u option to have it read
+# object definitions from this precached file, rather than the standard
+# object configuration files (see the cfg_file and cfg_dir options above).
+# Using a precached object file can speed up the time needed to (re)start
+# the Nagios process if you've got a large and/or complex configuration.
+# Read the documentation section on optimizing Nagios to find our more
+# about how this feature works.
+
+precached_object_file=/var/lib/nagios3/objects.precache
+
+
+
+# RESOURCE FILE
+# This is an optional resource file that contains $USERx$ macro
+# definitions. Multiple resource files can be specified by using
+# multiple resource_file definitions. The CGIs will not attempt to
+# read the contents of resource files, so information that is
+# considered to be sensitive (usernames, passwords, etc) can be
+# defined as macros in this file and restrictive permissions (600)
+# can be placed on this file.
+
+resource_file=/etc/nagios3/private/resource.cfg
+
+
+
+# STATUS FILE
+# This is where the current status of all monitored services and
+# hosts is stored. Its contents are read and processed by the CGIs.
+# The contents of the status file are deleted every time Nagios
+# restarts.
+
+status_file=/var/cache/nagios3/status.dat
+
+
+
+# STATUS FILE UPDATE INTERVAL
+# This option determines the frequency (in seconds) that
+# Nagios will periodically dump program, host, and
+# service status data.
+
+status_update_interval=10
+
+
+
+# NAGIOS USER
+# This determines the effective user that Nagios should run as.
+# You can either supply a username or a UID.
+
+nagios_user=nagios
+
+
+
+# NAGIOS GROUP
+# This determines the effective group that Nagios should run as.
+# You can either supply a group name or a GID.
+
+nagios_group=nagios
+
+
+
+# EXTERNAL COMMAND OPTION
+# This option allows you to specify whether or not Nagios should check
+# for external commands (in the command file defined below). By default
+# Nagios will *not* check for external commands, just to be on the
+# cautious side. If you want to be able to use the CGI command interface
+# you will have to enable this.
+# Values: 0 = disable commands, 1 = enable commands
+
+check_external_commands=1
+
+
+
+# EXTERNAL COMMAND CHECK INTERVAL
+# This is the interval at which Nagios should check for external commands.
+# This value works of the interval_length you specify later. If you leave
+# that at its default value of 60 (seconds), a value of 1 here will cause
+# Nagios to check for external commands every minute. If you specify a
+# number followed by an "s" (i.e. 15s), this will be interpreted to mean
+# actual seconds rather than a multiple of the interval_length variable.
+# Note: In addition to reading the external command file at regularly
+# scheduled intervals, Nagios will also check for external commands after
+# event handlers are executed.
+# NOTE: Setting this value to -1 causes Nagios to check the external
+# command file as often as possible.
+
+#command_check_interval=15s
+command_check_interval=-1
+
+
+
+# EXTERNAL COMMAND FILE
+# This is the file that Nagios checks for external command requests.
+# It is also where the command CGI will write commands that are submitted
+# by users, so it must be writeable by the user that the web server
+# is running as (usually 'nobody'). Permissions should be set at the
+# directory level instead of on the file, as the file is deleted every
+# time its contents are processed.
+# Debian Users: In case you didn't read README.Debian yet, _NOW_ is the
+# time to do it.
+
+command_file=/var/lib/nagios3/rw/nagios.cmd
+
+
+
+# EXTERNAL COMMAND BUFFER SLOTS
+# This settings is used to tweak the number of items or "slots" that
+# the Nagios daemon should allocate to the buffer that holds incoming
+# external commands before they are processed. As external commands
+# are processed by the daemon, they are removed from the buffer.
+
+external_command_buffer_slots=4096
+
+
+
+# LOCK FILE
+# This is the lockfile that Nagios will use to store its PID number
+# in when it is running in daemon mode.
+
+lock_file=/var/run/nagios3/nagios3.pid
+
+
+
+# TEMP FILE
+# This is a temporary file that is used as scratch space when Nagios
+# updates the status log, cleans the comment file, etc. This file
+# is created, used, and deleted throughout the time that Nagios is
+# running.
+
+temp_file=/var/cache/nagios3/nagios.tmp
+
+
+
+# TEMP PATH
+# This is path where Nagios can create temp files for service and
+# host check results, etc.
+
+temp_path=/tmp
+
+
+
+# EVENT BROKER OPTIONS
+# Controls what (if any) data gets sent to the event broker.
+# Values: 0 = Broker nothing
+# -1 = Broker everything
+# <other> = See documentation
+
+event_broker_options=-1
+
+
+
+# EVENT BROKER MODULE(S)
+# This directive is used to specify an event broker module that should
+# by loaded by Nagios at startup. Use multiple directives if you want
+# to load more than one module. Arguments that should be passed to
+# the module at startup are seperated from the module path by a space.
+#
+#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING
+#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#
+# Do NOT overwrite modules while they are being used by Nagios or Nagios
+# will crash in a fiery display of SEGFAULT glory. This is a bug/limitation
+# either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios...
+#
+# The correct/safe way of updating a module is by using one of these methods:
+# 1. Shutdown Nagios, replace the module file, restart Nagios
+# 2. Delete the original module file, move the new module file into place, restart Nagios
+#
+# Example:
+#
+# broker_module=<modulepath> [moduleargs]
+
+#broker_module=/somewhere/module1.o
+#broker_module=/somewhere/module2.o arg1 arg2=3 debug=0
+
+
+
+# LOG ROTATION METHOD
+# This is the log rotation method that Nagios should use to rotate
+# the main log file. Values are as follows..
+# n = None - don't rotate the log
+# h = Hourly rotation (top of the hour)
+# d = Daily rotation (midnight every day)
+# w = Weekly rotation (midnight on Saturday evening)
+# m = Monthly rotation (midnight last day of month)
+
+log_rotation_method=d
+
+
+
+# LOG ARCHIVE PATH
+# This is the directory where archived (rotated) log files should be
+# placed (assuming you've chosen to do log rotation).
+
+log_archive_path=/var/log/nagios3/archives
+
+
+
+# LOGGING OPTIONS
+# If you want messages logged to the syslog facility, as well as the
+# Nagios log file set this option to 1. If not, set it to 0.
+
+use_syslog=1
+
+
+
+# NOTIFICATION LOGGING OPTION
+# If you don't want notifications to be logged, set this value to 0.
+# If notifications should be logged, set the value to 1.
+
+log_notifications=1
+
+
+
+# SERVICE RETRY LOGGING OPTION
+# If you don't want service check retries to be logged, set this value
+# to 0. If retries should be logged, set the value to 1.
+
+log_service_retries=1
+
+
+
+# HOST RETRY LOGGING OPTION
+# If you don't want host check retries to be logged, set this value to
+# 0. If retries should be logged, set the value to 1.
+
+log_host_retries=1
+
+
+
+# EVENT HANDLER LOGGING OPTION
+# If you don't want host and service event handlers to be logged, set
+# this value to 0. If event handlers should be logged, set the value
+# to 1.
+
+log_event_handlers=1
+
+
+
+# INITIAL STATES LOGGING OPTION
+# If you want Nagios to log all initial host and service states to
+# the main log file (the first time the service or host is checked)
+# you can enable this option by setting this value to 1. If you
+# are not using an external application that does long term state
+# statistics reporting, you do not need to enable this option. In
+# this case, set the value to 0.
+
+log_initial_states=0
+
+
+
+# EXTERNAL COMMANDS LOGGING OPTION
+# If you don't want Nagios to log external commands, set this value
+# to 0. If external commands should be logged, set this value to 1.
+# Note: This option does not include logging of passive service
+# checks - see the option below for controlling whether or not
+# passive checks are logged.
+
+log_external_commands=1
+
+
+
+# PASSIVE CHECKS LOGGING OPTION
+# If you don't want Nagios to log passive host and service checks, set
+# this value to 0. If passive checks should be logged, set
+# this value to 1.
+
+log_passive_checks=1
+
+
+
+# GLOBAL HOST AND SERVICE EVENT HANDLERS
+# These options allow you to specify a host and service event handler
+# command that is to be run for every host or service state change.
+# The global event handler is executed immediately prior to the event
+# handler that you have optionally specified in each host or
+# service definition. The command argument is the short name of a
+# command definition that you define in your host configuration file.
+# Read the HTML docs for more information.
+
+#global_host_event_handler=somecommand
+#global_service_event_handler=somecommand
+
+
+
+# SERVICE INTER-CHECK DELAY METHOD
+# This is the method that Nagios should use when initially
+# "spreading out" service checks when it starts monitoring. The
+# default is to use smart delay calculation, which will try to
+# space all service checks out evenly to minimize CPU load.
+# Using the dumb setting will cause all checks to be scheduled
+# at the same time (with no delay between them)! This is not a
+# good thing for production, but is useful when testing the
+# parallelization functionality.
+# n = None - don't use any delay between checks
+# d = Use a "dumb" delay of 1 second between checks
+# s = Use "smart" inter-check delay calculation
+# x.xx = Use an inter-check delay of x.xx seconds
+
+service_inter_check_delay_method=s
+
+
+
+# MAXIMUM SERVICE CHECK SPREAD
+# This variable determines the timeframe (in minutes) from the
+# program start time that an initial check of all services should
+# be completed. Default is 30 minutes.
+
+max_service_check_spread=30
+
+
+
+# SERVICE CHECK INTERLEAVE FACTOR
+# This variable determines how service checks are interleaved.
+# Interleaving the service checks allows for a more even
+# distribution of service checks and reduced load on remote
+# hosts. Setting this value to 1 is equivalent to how versions
+# of Nagios previous to 0.0.5 did service checks. Set this
+# value to s (smart) for automatic calculation of the interleave
+# factor unless you have a specific reason to change it.
+# s = Use "smart" interleave factor calculation
+# x = Use an interleave factor of x, where x is a
+# number greater than or equal to 1.
+
+service_interleave_factor=s
+
+
+
+# HOST INTER-CHECK DELAY METHOD
+# This is the method that Nagios should use when initially
+# "spreading out" host checks when it starts monitoring. The
+# default is to use smart delay calculation, which will try to
+# space all host checks out evenly to minimize CPU load.
+# Using the dumb setting will cause all checks to be scheduled
+# at the same time (with no delay between them)!
+# n = None - don't use any delay between checks
+# d = Use a "dumb" delay of 1 second between checks
+# s = Use "smart" inter-check delay calculation
+# x.xx = Use an inter-check delay of x.xx seconds
+
+host_inter_check_delay_method=s
+
+
+
+# MAXIMUM HOST CHECK SPREAD
+# This variable determines the timeframe (in minutes) from the
+# program start time that an initial check of all hosts should
+# be completed. Default is 30 minutes.
+
+max_host_check_spread=30
+
+
+
+# MAXIMUM CONCURRENT SERVICE CHECKS
+# This option allows you to specify the maximum number of
+# service checks that can be run in parallel at any given time.
+# Specifying a value of 1 for this variable essentially prevents
+# any service checks from being parallelized. A value of 0
+# will not restrict the number of concurrent checks that are
+# being executed.
+
+max_concurrent_checks=0
+
+
+
+# HOST AND SERVICE CHECK REAPER FREQUENCY
+# This is the frequency (in seconds!) that Nagios will process
+# the results of host and service checks.
+
+check_result_reaper_frequency=10
+
+
+
+
+# MAX CHECK RESULT REAPER TIME
+# This is the max amount of time (in seconds) that a single
+# check result reaper event will be allowed to run before
+# returning control back to Nagios so it can perform other
+# duties.
+
+max_check_result_reaper_time=30
+
+
+
+
+# CHECK RESULT PATH
+# This is directory where Nagios stores the results of host and
+# service checks that have not yet been processed.
+#
+# Note: Make sure that only one instance of Nagios has access
+# to this directory!
+
+check_result_path=/var/lib/nagios3/spool/checkresults
+
+
+
+
+# MAX CHECK RESULT FILE AGE
+# This option determines the maximum age (in seconds) which check
+# result files are considered to be valid. Files older than this
+# threshold will be mercilessly deleted without further processing.
+
+max_check_result_file_age=3600
+
+
+
+
+# CACHED HOST CHECK HORIZON
+# This option determines the maximum amount of time (in seconds)
+# that the state of a previous host check is considered current.
+# Cached host states (from host checks that were performed more
+# recently that the timeframe specified by this value) can immensely
+# improve performance in regards to the host check logic.
+# Too high of a value for this option may result in inaccurate host
+# states being used by Nagios, while a lower value may result in a
+# performance hit for host checks. Use a value of 0 to disable host
+# check caching.
+
+cached_host_check_horizon=15
+
+
+
+# CACHED SERVICE CHECK HORIZON
+# This option determines the maximum amount of time (in seconds)
+# that the state of a previous service check is considered current.
+# Cached service states (from service checks that were performed more
+# recently that the timeframe specified by this value) can immensely
+# improve performance in regards to predictive dependency checks.
+# Use a value of 0 to disable service check caching.
+
+cached_service_check_horizon=15
+
+
+
+# ENABLE PREDICTIVE HOST DEPENDENCY CHECKS
+# This option determines whether or not Nagios will attempt to execute
+# checks of hosts when it predicts that future dependency logic test
+# may be needed. These predictive checks can help ensure that your
+# host dependency logic works well.
+# Values:
+# 0 = Disable predictive checks
+# 1 = Enable predictive checks (default)
+
+enable_predictive_host_dependency_checks=1
+
+
+
+# ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS
+# This option determines whether or not Nagios will attempt to execute
+# checks of service when it predicts that future dependency logic test
+# may be needed. These predictive checks can help ensure that your
+# service dependency logic works well.
+# Values:
+# 0 = Disable predictive checks
+# 1 = Enable predictive checks (default)
+
+enable_predictive_service_dependency_checks=1
+
+
+
+# SOFT STATE DEPENDENCIES
+# This option determines whether or not Nagios will use soft state
+# information when checking host and service dependencies. Normally
+# Nagios will only use the latest hard host or service state when
+# checking dependencies. If you want it to use the latest state (regardless
+# of whether its a soft or hard state type), enable this option.
+# Values:
+# 0 = Don't use soft state dependencies (default)
+# 1 = Use soft state dependencies
+
+soft_state_dependencies=0
+
+
+
+# TIME CHANGE ADJUSTMENT THRESHOLDS
+# These options determine when Nagios will react to detected changes
+# in system time (either forward or backwards).
+
+#time_change_threshold=900
+
+
+
+# AUTO-RESCHEDULING OPTION
+# This option determines whether or not Nagios will attempt to
+# automatically reschedule active host and service checks to
+# "smooth" them out over time. This can help balance the load on
+# the monitoring server.
+# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE
+# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY
+
+auto_reschedule_checks=0
+
+
+
+# AUTO-RESCHEDULING INTERVAL
+# This option determines how often (in seconds) Nagios will
+# attempt to automatically reschedule checks. This option only
+# has an effect if the auto_reschedule_checks option is enabled.
+# Default is 30 seconds.
+# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE
+# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY
+
+auto_rescheduling_interval=30
+
+
+
+# AUTO-RESCHEDULING WINDOW
+# This option determines the "window" of time (in seconds) that
+# Nagios will look at when automatically rescheduling checks.
+# Only host and service checks that occur in the next X seconds
+# (determined by this variable) will be rescheduled. This option
+# only has an effect if the auto_reschedule_checks option is
+# enabled. Default is 180 seconds (3 minutes).
+# WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE
+# PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY
+
+auto_rescheduling_window=180
+
+
+
+# SLEEP TIME
+# This is the number of seconds to sleep between checking for system
+# events and service checks that need to be run.
+
+sleep_time=0.25
+
+
+
+# TIMEOUT VALUES
+# These options control how much time Nagios will allow various
+# types of commands to execute before killing them off. Options
+# are available for controlling maximum time allotted for
+# service checks, host checks, event handlers, notifications, the
+# ocsp command, and performance data commands. All values are in
+# seconds.
+
+service_check_timeout=60
+host_check_timeout=30
+event_handler_timeout=30
+notification_timeout=30
+ocsp_timeout=5
+perfdata_timeout=5
+
+
+
+# RETAIN STATE INFORMATION
+# This setting determines whether or not Nagios will save state
+# information for services and hosts before it shuts down. Upon
+# startup Nagios will reload all saved service and host state
+# information before starting to monitor. This is useful for
+# maintaining long-term data on state statistics, etc, but will
+# slow Nagios down a bit when it (re)starts. Since its only
+# a one-time penalty, I think its well worth the additional
+# startup delay.
+
+retain_state_information=1
+
+
+
+# STATE RETENTION FILE
+# This is the file that Nagios should use to store host and
+# service state information before it shuts down. The state
+# information in this file is also read immediately prior to
+# starting to monitor the network when Nagios is restarted.
+# This file is used only if the preserve_state_information
+# variable is set to 1.
+
+state_retention_file=/var/lib/nagios3/retention.dat
+
+
+
+# RETENTION DATA UPDATE INTERVAL
+# This setting determines how often (in minutes) that Nagios
+# will automatically save retention data during normal operation.
+# If you set this value to 0, Nagios will not save retention
+# data at regular interval, but it will still save retention
+# data before shutting down or restarting. If you have disabled
+# state retention, this option has no effect.
+
+retention_update_interval=60
+
+
+
+# USE RETAINED PROGRAM STATE
+# This setting determines whether or not Nagios will set
+# program status variables based on the values saved in the
+# retention file. If you want to use retained program status
+# information, set this value to 1. If not, set this value
+# to 0.
+
+use_retained_program_state=1
+
+
+
+# USE RETAINED SCHEDULING INFO
+# This setting determines whether or not Nagios will retain
+# the scheduling info (next check time) for hosts and services
+# based on the values saved in the retention file. If you
+# If you want to use retained scheduling info, set this
+# value to 1. If not, set this value to 0.
+
+use_retained_scheduling_info=1
+
+
+
+# RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE)
+# The following variables are used to specify specific host and
+# service attributes that should *not* be retained by Nagios during
+# program restarts.
+#
+# The values of the masks are bitwise ANDs of values specified
+# by the "MODATTR_" definitions found in include/common.h.
+# For example, if you do not want the current enabled/disabled state
+# of flap detection and event handlers for hosts to be retained, you
+# would use a value of 24 for the host attribute mask...
+# MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24
+
+# This mask determines what host attributes are not retained
+retained_host_attribute_mask=0
+
+# This mask determines what service attributes are not retained
+retained_service_attribute_mask=0
+
+# These two masks determine what process attributes are not retained.
+# There are two masks, because some process attributes have host and service
+# options. For example, you can disable active host checks, but leave active
+# service checks enabled.
+retained_process_host_attribute_mask=0
+retained_process_service_attribute_mask=0
+
+# These two masks determine what contact attributes are not retained.
+# There are two masks, because some contact attributes have host and
+# service options. For example, you can disable host notifications for
+# a contact, but leave service notifications enabled for them.
+retained_contact_host_attribute_mask=0
+retained_contact_service_attribute_mask=0
+
+
+
+# INTERVAL LENGTH
+# This is the seconds per unit interval as used in the
+# host/contact/service configuration files. Setting this to 60 means
+# that each interval is one minute long (60 seconds). Other settings
+# have not been tested much, so your mileage is likely to vary...
+
+interval_length=60
+
+
+
+# AGGRESSIVE HOST CHECKING OPTION
+# If you don't want to turn on aggressive host checking features, set
+# this value to 0 (the default). Otherwise set this value to 1 to
+# enable the aggressive check option. Read the docs for more info
+# on what aggressive host check is or check out the source code in
+# base/checks.c
+
+use_aggressive_host_checking=0
+
+
+
+# SERVICE CHECK EXECUTION OPTION
+# This determines whether or not Nagios will actively execute
+# service checks when it initially starts. If this option is
+# disabled, checks are not actively made, but Nagios can still
+# receive and process passive check results that come in. Unless
+# you're implementing redundant hosts or have a special need for
+# disabling the execution of service checks, leave this enabled!
+# Values: 1 = enable checks, 0 = disable checks
+
+execute_service_checks=1
+
+
+
+# PASSIVE SERVICE CHECK ACCEPTANCE OPTION
+# This determines whether or not Nagios will accept passive
+# service checks results when it initially (re)starts.
+# Values: 1 = accept passive checks, 0 = reject passive checks
+
+accept_passive_service_checks=1
+
+
+
+# HOST CHECK EXECUTION OPTION
+# This determines whether or not Nagios will actively execute
+# host checks when it initially starts. If this option is
+# disabled, checks are not actively made, but Nagios can still
+# receive and process passive check results that come in. Unless
+# you're implementing redundant hosts or have a special need for
+# disabling the execution of host checks, leave this enabled!
+# Values: 1 = enable checks, 0 = disable checks
+
+execute_host_checks=1
+
+
+
+# PASSIVE HOST CHECK ACCEPTANCE OPTION
+# This determines whether or not Nagios will accept passive
+# host checks results when it initially (re)starts.
+# Values: 1 = accept passive checks, 0 = reject passive checks
+
+accept_passive_host_checks=1
+
+
+
+# NOTIFICATIONS OPTION
+# This determines whether or not Nagios will sent out any host or
+# service notifications when it is initially (re)started.
+# Values: 1 = enable notifications, 0 = disable notifications
+
+enable_notifications=1
+
+
+
+# EVENT HANDLER USE OPTION
+# This determines whether or not Nagios will run any host or
+# service event handlers when it is initially (re)started. Unless
+# you're implementing redundant hosts, leave this option enabled.
+# Values: 1 = enable event handlers, 0 = disable event handlers
+
+enable_event_handlers=1
+
+
+
+# PROCESS PERFORMANCE DATA OPTION
+# This determines whether or not Nagios will process performance
+# data returned from service and host checks. If this option is
+# enabled, host performance data will be processed using the
+# host_perfdata_command (defined below) and service performance
+# data will be processed using the service_perfdata_command (also
+# defined below). Read the HTML docs for more information on
+# performance data.
+# Values: 1 = process performance data, 0 = do not process performance data
+
+process_performance_data=0
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS
+# These commands are run after every host and service check is
+# performed. These commands are executed only if the
+# enable_performance_data option (above) is set to 1. The command
+# argument is the short name of a command definition that you
+# define in your host configuration file. Read the HTML docs for
+# more information on performance data.
+
+#host_perfdata_command=process-host-perfdata
+#service_perfdata_command=process-service-perfdata
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILES
+# These files are used to store host and service performance data.
+# Performance data is only written to these files if the
+# enable_performance_data option (above) is set to 1.
+
+#host_perfdata_file=/tmp/host-perfdata
+#service_perfdata_file=/tmp/service-perfdata
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES
+# These options determine what data is written (and how) to the
+# performance data files. The templates may contain macros, special
+# characters (\t for tab, \r for carriage return, \n for newline)
+# and plain text. A newline is automatically added after each write
+# to the performance data file. Some examples of what you can do are
+# shown below.
+
+#host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$
+#service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILE MODES
+# This option determines whether or not the host and service
+# performance data files are opened in write ("w") or append ("a")
+# mode. If you want to use named pipes, you should use the special
+# pipe ("p") mode which avoid blocking at startup, otherwise you will
+# likely want the defult append ("a") mode.
+
+#host_perfdata_file_mode=a
+#service_perfdata_file_mode=a
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL
+# These options determine how often (in seconds) the host and service
+# performance data files are processed using the commands defined
+# below. A value of 0 indicates the files should not be periodically
+# processed.
+
+#host_perfdata_file_processing_interval=0
+#service_perfdata_file_processing_interval=0
+
+
+
+# HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS
+# These commands are used to periodically process the host and
+# service performance data files. The interval at which the
+# processing occurs is determined by the options above.
+
+#host_perfdata_file_processing_command=process-host-perfdata-file
+#service_perfdata_file_processing_command=process-service-perfdata-file
+
+
+
+# OBSESS OVER SERVICE CHECKS OPTION
+# This determines whether or not Nagios will obsess over service
+# checks and run the ocsp_command defined below. Unless you're
+# planning on implementing distributed monitoring, do not enable
+# this option. Read the HTML docs for more information on
+# implementing distributed monitoring.
+# Values: 1 = obsess over services, 0 = do not obsess (default)
+
+obsess_over_services=0
+
+
+
+# OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND
+# This is the command that is run for every service check that is
+# processed by Nagios. This command is executed only if the
+# obsess_over_services option (above) is set to 1. The command
+# argument is the short name of a command definition that you
+# define in your host configuration file. Read the HTML docs for
+# more information on implementing distributed monitoring.
+
+#ocsp_command=somecommand
+
+
+
+# OBSESS OVER HOST CHECKS OPTION
+# This determines whether or not Nagios will obsess over host
+# checks and run the ochp_command defined below. Unless you're
+# planning on implementing distributed monitoring, do not enable
+# this option. Read the HTML docs for more information on
+# implementing distributed monitoring.
+# Values: 1 = obsess over hosts, 0 = do not obsess (default)
+
+obsess_over_hosts=0
+
+
+
+# OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND
+# This is the command that is run for every host check that is
+# processed by Nagios. This command is executed only if the
+# obsess_over_hosts option (above) is set to 1. The command
+# argument is the short name of a command definition that you
+# define in your host configuration file. Read the HTML docs for
+# more information on implementing distributed monitoring.
+
+#ochp_command=somecommand
+
+
+
+# TRANSLATE PASSIVE HOST CHECKS OPTION
+# This determines whether or not Nagios will translate
+# DOWN/UNREACHABLE passive host check results into their proper
+# state for this instance of Nagios. This option is useful
+# if you have distributed or failover monitoring setup. In
+# these cases your other Nagios servers probably have a different
+# "view" of the network, with regards to the parent/child relationship
+# of hosts. If a distributed monitoring server thinks a host
+# is DOWN, it may actually be UNREACHABLE from the point of
+# this Nagios instance. Enabling this option will tell Nagios
+# to translate any DOWN or UNREACHABLE host states it receives
+# passively into the correct state from the view of this server.
+# Values: 1 = perform translation, 0 = do not translate (default)
+
+translate_passive_host_checks=0
+
+
+
+# PASSIVE HOST CHECKS ARE SOFT OPTION
+# This determines whether or not Nagios will treat passive host
+# checks as being HARD or SOFT. By default, a passive host check
+# result will put a host into a HARD state type. This can be changed
+# by enabling this option.
+# Values: 0 = passive checks are HARD, 1 = passive checks are SOFT
+
+passive_host_checks_are_soft=0
+
+
+
+# ORPHANED HOST/SERVICE CHECK OPTIONS
+# These options determine whether or not Nagios will periodically
+# check for orphaned host service checks. Since service checks are
+# not rescheduled until the results of their previous execution
+# instance are processed, there exists a possibility that some
+# checks may never get rescheduled. A similar situation exists for
+# host checks, although the exact scheduling details differ a bit
+# from service checks. Orphaned checks seem to be a rare
+# problem and should not happen under normal circumstances.
+# If you have problems with service checks never getting
+# rescheduled, make sure you have orphaned service checks enabled.
+# Values: 1 = enable checks, 0 = disable checks
+
+check_for_orphaned_services=1
+check_for_orphaned_hosts=1
+
+
+
+# SERVICE FRESHNESS CHECK OPTION
+# This option determines whether or not Nagios will periodically
+# check the "freshness" of service results. Enabling this option
+# is useful for ensuring passive checks are received in a timely
+# manner.
+# Values: 1 = enabled freshness checking, 0 = disable freshness checking
+
+check_service_freshness=1
+
+
+
+# SERVICE FRESHNESS CHECK INTERVAL
+# This setting determines how often (in seconds) Nagios will
+# check the "freshness" of service check results. If you have
+# disabled service freshness checking, this option has no effect.
+
+service_freshness_check_interval=60
+
+
+
+# HOST FRESHNESS CHECK OPTION
+# This option determines whether or not Nagios will periodically
+# check the "freshness" of host results. Enabling this option
+# is useful for ensuring passive checks are received in a timely
+# manner.
+# Values: 1 = enabled freshness checking, 0 = disable freshness checking
+
+check_host_freshness=0
+
+
+
+# HOST FRESHNESS CHECK INTERVAL
+# This setting determines how often (in seconds) Nagios will
+# check the "freshness" of host check results. If you have
+# disabled host freshness checking, this option has no effect.
+
+host_freshness_check_interval=60
+
+
+
+
+# ADDITIONAL FRESHNESS THRESHOLD LATENCY
+# This setting determines the number of seconds that Nagios
+# will add to any host and service freshness thresholds that
+# it calculates (those not explicitly specified by the user).
+
+additional_freshness_latency=15
+
+
+
+
+# FLAP DETECTION OPTION
+# This option determines whether or not Nagios will try
+# and detect hosts and services that are "flapping".
+# Flapping occurs when a host or service changes between
+# states too frequently. When Nagios detects that a
+# host or service is flapping, it will temporarily suppress
+# notifications for that host/service until it stops
+# flapping. Flap detection is very experimental, so read
+# the HTML documentation before enabling this feature!
+# Values: 1 = enable flap detection
+# 0 = disable flap detection (default)
+
+enable_flap_detection=1
+
+
+
+# FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES
+# Read the HTML documentation on flap detection for
+# an explanation of what this option does. This option
+# has no effect if flap detection is disabled.
+
+low_service_flap_threshold=5.0
+high_service_flap_threshold=20.0
+low_host_flap_threshold=5.0
+high_host_flap_threshold=20.0
+
+
+
+# DATE FORMAT OPTION
+# This option determines how short dates are displayed. Valid options
+# include:
+# us (MM-DD-YYYY HH:MM:SS)
+# euro (DD-MM-YYYY HH:MM:SS)
+# iso8601 (YYYY-MM-DD HH:MM:SS)
+# strict-iso8601 (YYYY-MM-DDTHH:MM:SS)
+#
+
+date_format=iso8601
+
+
+
+
+# TIMEZONE OFFSET
+# This option is used to override the default timezone that this
+# instance of Nagios runs in. If not specified, Nagios will use
+# the system configured timezone.
+#
+# NOTE: In order to display the correct timezone in the CGIs, you
+# will also need to alter the Apache directives for the CGI path
+# to include your timezone. Example:
+#
+# <Directory "/usr/local/nagios/sbin/">
+# SetEnv TZ "Australia/Brisbane"
+# ...
+# </Directory>
+
+#use_timezone=US/Mountain
+#use_timezone=Australia/Brisbane
+
+
+
+
+# P1.PL FILE LOCATION
+# This value determines where the p1.pl perl script (used by the
+# embedded Perl interpreter) is located. If you didn't compile
+# Nagios with embedded Perl support, this option has no effect.
+
+p1_file=/usr/lib/nagios3/p1.pl
+
+
+
+# EMBEDDED PERL INTERPRETER OPTION
+# This option determines whether or not the embedded Perl interpreter
+# will be enabled during runtime. This option has no effect if Nagios
+# has not been compiled with support for embedded Perl.
+# Values: 0 = disable interpreter, 1 = enable interpreter
+
+enable_embedded_perl=1
+
+
+
+# EMBEDDED PERL USAGE OPTION
+# This option determines whether or not Nagios will process Perl plugins
+# and scripts with the embedded Perl interpreter if the plugins/scripts
+# do not explicitly indicate whether or not it is okay to do so. Read
+# the HTML documentation on the embedded Perl interpreter for more
+# information on how this option works.
+
+use_embedded_perl_implicitly=1
+
+
+
+# ILLEGAL OBJECT NAME CHARACTERS
+# This option allows you to specify illegal characters that cannot
+# be used in host names, service descriptions, or names of other
+# object types.
+
+illegal_object_name_chars=`~!$%^&*|'"<>?,()=
+
+
+
+# ILLEGAL MACRO OUTPUT CHARACTERS
+# This option allows you to specify illegal characters that are
+# stripped from macros before being used in notifications, event
+# handlers, etc. This DOES NOT affect macros used in service or
+# host check commands.
+# The following macros are stripped of the characters you specify:
+# $HOSTOUTPUT$
+# $HOSTPERFDATA$
+# $HOSTACKAUTHOR$
+# $HOSTACKCOMMENT$
+# $SERVICEOUTPUT$
+# $SERVICEPERFDATA$
+# $SERVICEACKAUTHOR$
+# $SERVICEACKCOMMENT$
+
+illegal_macro_output_chars=`~$&|'"<>
+
+
+
+# REGULAR EXPRESSION MATCHING
+# This option controls whether or not regular expression matching
+# takes place in the object config files. Regular expression
+# matching is used to match host, hostgroup, service, and service
+# group names/descriptions in some fields of various object types.
+# Values: 1 = enable regexp matching, 0 = disable regexp matching
+
+use_regexp_matching=0
+
+
+
+# "TRUE" REGULAR EXPRESSION MATCHING
+# This option controls whether or not "true" regular expression
+# matching takes place in the object config files. This option
+# only has an effect if regular expression matching is enabled
+# (see above). If this option is DISABLED, regular expression
+# matching only occurs if a string contains wildcard characters
+# (* and ?). If the option is ENABLED, regexp matching occurs
+# all the time (which can be annoying).
+# Values: 1 = enable true matching, 0 = disable true matching
+
+use_true_regexp_matching=0
+
+
+
+# ADMINISTRATOR EMAIL/PAGER ADDRESSES
+# The email and pager address of a global administrator (likely you).
+# Nagios never uses these values itself, but you can access them by
+# using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification
+# commands.
+
+admin_email=root@localhost
+admin_pager=pageroot@localhost
+
+
+
+# DAEMON CORE DUMP OPTION
+# This option determines whether or not Nagios is allowed to create
+# a core dump when it runs as a daemon. Note that it is generally
+# considered bad form to allow this, but it may be useful for
+# debugging purposes. Enabling this option doesn't guarantee that
+# a core file will be produced, but that's just life...
+# Values: 1 - Allow core dumps
+# 0 - Do not allow core dumps (default)
+
+daemon_dumps_core=0
+
+
+
+# LARGE INSTALLATION TWEAKS OPTION
+# This option determines whether or not Nagios will take some shortcuts
+# which can save on memory and CPU usage in large Nagios installations.
+# Read the documentation for more information on the benefits/tradeoffs
+# of enabling this option.
+# Values: 1 - Enabled tweaks
+# 0 - Disable tweaks (default)
+
+use_large_installation_tweaks=0
+
+
+
+# ENABLE ENVIRONMENT MACROS
+# This option determines whether or not Nagios will make all standard
+# macros available as environment variables when host/service checks
+# and system commands (event handlers, notifications, etc.) are
+# executed. Enabling this option can cause performance issues in
+# large installations, as it will consume a bit more memory and (more
+# importantly) consume more CPU.
+# Values: 1 - Enable environment variable macros (default)
+# 0 - Disable environment variable macros
+
+enable_environment_macros=1
+
+
+
+# CHILD PROCESS MEMORY OPTION
+# This option determines whether or not Nagios will free memory in
+# child processes (processed used to execute system commands and host/
+# service checks). If you specify a value here, it will override
+# program defaults.
+# Value: 1 - Free memory in child processes
+# 0 - Do not free memory in child processes
+
+#free_child_process_memory=1
+
+
+
+# CHILD PROCESS FORKING BEHAVIOR
+# This option determines how Nagios will fork child processes
+# (used to execute system commands and host/service checks). Normally
+# child processes are fork()ed twice, which provides a very high level
+# of isolation from problems. Fork()ing once is probably enough and will
+# save a great deal on CPU usage (in large installs), so you might
+# want to consider using this. If you specify a value here, it will
+# program defaults.
+# Value: 1 - Child processes fork() twice
+# 0 - Child processes fork() just once
+
+#child_processes_fork_twice=1
+
+
+
+# DEBUG LEVEL
+# This option determines how much (if any) debugging information will
+# be written to the debug file. OR values together to log multiple
+# types of information.
+# Values:
+# -1 = Everything
+# 0 = Nothing
+# 1 = Functions
+# 2 = Configuration
+# 4 = Process information
+# 8 = Scheduled events
+# 16 = Host/service checks
+# 32 = Notifications
+# 64 = Event broker
+# 128 = External commands
+# 256 = Commands
+# 512 = Scheduled downtime
+# 1024 = Comments
+# 2048 = Macros
+
+debug_level=0
+
+
+
+# DEBUG VERBOSITY
+# This option determines how verbose the debug log out will be.
+# Values: 0 = Brief output
+# 1 = More detailed
+# 2 = Very detailed
+
+debug_verbosity=1
+
+
+
+# DEBUG FILE
+# This option determines where Nagios should write debugging information.
+
+debug_file=/var/lib/nagios3/nagios.debug
+
+
+
+# MAX DEBUG FILE SIZE
+# This option determines the maximum size (in bytes) of the debug file. If
+# the file grows larger than this size, it will be renamed with a .old
+# extension. If a file already exists with a .old extension it will
+# automatically be deleted. This helps ensure your disk space usage doesn't
+# get out of control when debugging Nagios.
+
+max_debug_file_size=1000000
+
+
diff --git a/puppet/modules/site_nagios/manifests/add_host.pp b/puppet/modules/site_nagios/manifests/add_host.pp
new file mode 100644
index 00000000..498552b5
--- /dev/null
+++ b/puppet/modules/site_nagios/manifests/add_host.pp
@@ -0,0 +1,31 @@
+define site_nagios::add_host {
+ $nagios_host = $name
+ $nagios_hostname = $name['domain_internal']
+ $nagios_ip = $name['ip_address']
+ $nagios_services = $name['services']
+ $nagios_openvpn_gw = $name['openvpn_gateway_address']
+
+ # Add Nagios host
+ nagios_host { $nagios_hostname:
+ address => $nagios_ip,
+ use => 'generic-host',
+ }
+
+ # Add Nagios service
+
+ # First, we need to turn the serice array into hash, using a "hash template"
+ # see https://github.com/ashak/puppet-resource-looping
+ $nagios_service_hashpart = {
+ 'hostname' => $nagios_hostname,
+ 'ip_address' => $nagios_ip,
+ 'openvpn_gw' => $nagios_openvpn_gw,
+ }
+ $dynamic_parameters = {
+ 'service' => '%s'
+ }
+ $nagios_servicename = "${nagios_hostname}_%s"
+
+ $nagios_service_hash = create_resources_hash_from($nagios_servicename, $nagios_services, $nagios_service_hashpart, $dynamic_parameters)
+
+ create_resources ( site_nagios::add_service, $nagios_service_hash )
+}
diff --git a/puppet/modules/site_nagios/manifests/add_service.pp b/puppet/modules/site_nagios/manifests/add_service.pp
new file mode 100644
index 00000000..6ef3cbf5
--- /dev/null
+++ b/puppet/modules/site_nagios/manifests/add_service.pp
@@ -0,0 +1,21 @@
+define site_nagios::add_service (
+ $hostname, $ip_address, $openvpn_gw = '', $service) {
+
+ case $service {
+ 'webapp': {
+ $check_command = 'check_https_cert'
+ $service_description = 'Website Certificate'
+ }
+ default: {
+ #notice ("No Nagios service check for service \"$service\"")
+ }
+ }
+
+ if ( $check_command != '' ) {
+ nagios_service { $name:
+ use => 'generic-service',
+ check_command => $check_command,
+ service_description => $service_description,
+ host_name => $hostname }
+ }
+}
diff --git a/puppet/modules/site_nagios/manifests/init.pp b/puppet/modules/site_nagios/manifests/init.pp
new file mode 100644
index 00000000..cab32905
--- /dev/null
+++ b/puppet/modules/site_nagios/manifests/init.pp
@@ -0,0 +1,4 @@
+class site_nagios {
+ tag 'leap_service'
+ include site_nagios::server
+}
diff --git a/puppet/modules/site_nagios/manifests/server.pp b/puppet/modules/site_nagios/manifests/server.pp
new file mode 100644
index 00000000..c98a8a1f
--- /dev/null
+++ b/puppet/modules/site_nagios/manifests/server.pp
@@ -0,0 +1,38 @@
+class site_nagios::server inherits nagios::base {
+
+ # First, purge old nagios config (see #1467)
+ class { 'site_nagios::server::purge':
+ stage => initial
+ }
+
+ $nagios_hiera=hiera('nagios')
+ $nagiosadmin_pw = htpasswd_sha1($nagios_hiera['nagiosadmin_pw'])
+ $hosts = $nagios_hiera['hosts']
+
+ include nagios::defaults
+ include nagios::base
+ #Class ['nagios'] -> Class ['nagios::defaults']
+ class {'nagios::apache':
+ allow_external_cmd => true,
+ stored_config => false,
+ #before => Class ['nagios::defaults']
+ }
+
+ File ['nagios_htpasswd'] {
+ source => undef,
+ content => "nagiosadmin:$nagiosadmin_pw",
+ mode => '0640',
+ }
+
+
+ # deploy serverside plugins
+ file { '/usr/lib/nagios/plugins/check_openvpn_server.pl':
+ source => 'puppet:///modules/nagios/plugins/check_openvpn_server.pl',
+ mode => '0755',
+ owner => 'nagios',
+ group => 'nagios',
+ }
+
+ site_nagios::add_host {$hosts:}
+ include site_shorewall::monitor
+}
diff --git a/puppet/modules/site_nagios/manifests/server/purge.pp b/puppet/modules/site_nagios/manifests/server/purge.pp
new file mode 100644
index 00000000..39735cd3
--- /dev/null
+++ b/puppet/modules/site_nagios/manifests/server/purge.pp
@@ -0,0 +1,7 @@
+class site_nagios::server::purge {
+ exec {'purge_conf.d':
+ command => '/bin/rm -rf /etc/nagios3/conf.d/*',
+ onlyif => 'test -e /etc/nagios3/conf.d'
+ }
+
+}
diff --git a/puppet/modules/site_openvpn/manifests/init.pp b/puppet/modules/site_openvpn/manifests/init.pp
new file mode 100644
index 00000000..e3d2a9af
--- /dev/null
+++ b/puppet/modules/site_openvpn/manifests/init.pp
@@ -0,0 +1,108 @@
+class site_openvpn {
+ tag 'leap_service'
+ # parse hiera config
+ $ip_address = hiera('ip_address')
+ $interface = getvar("interface_${ip_address}")
+ #$gateway_address = hiera('gateway_address')
+ $openvpn_config = hiera('openvpn')
+ $openvpn_gateway_address = $openvpn_config['gateway_address']
+ $openvpn_tcp_network_prefix = '10.1.0'
+ $openvpn_tcp_netmask = '255.255.248.0'
+ $openvpn_tcp_cidr = '21'
+ $openvpn_udp_network_prefix = '10.2.0'
+ $openvpn_udp_netmask = '255.255.248.0'
+ $openvpn_udp_cidr = '21'
+ $x509_config = hiera('x509')
+
+ # deploy ca + server keys
+ include site_openvpn::keys
+
+ # create 2 openvpn config files, one for tcp, one for udp
+ site_openvpn::server_config { 'tcp_config':
+ port => '1194',
+ proto => 'tcp',
+ local => $openvpn_gateway_address,
+ server => "${openvpn_tcp_network_prefix}.0 ${openvpn_tcp_netmask}",
+ push => "\"dhcp-option DNS ${openvpn_tcp_network_prefix}.1\"",
+ management => '127.0.0.1 1000'
+ }
+ site_openvpn::server_config { 'udp_config':
+ port => '1194',
+ proto => 'udp',
+ server => "${openvpn_udp_network_prefix}.0 ${openvpn_udp_netmask}",
+ push => "\"dhcp-option DNS ${openvpn_udp_network_prefix}.1\"",
+ local => $openvpn_gateway_address,
+ management => '127.0.0.1 1001'
+ }
+
+ # add second IP on given interface
+ file { '/usr/local/bin/leap_add_second_ip.sh':
+ content => "#!/bin/sh
+ip addr show dev $interface | grep -q ${openvpn_gateway_address}/24 || ip addr add ${openvpn_gateway_address}/24 dev $interface
+/bin/echo 1 > /proc/sys/net/ipv4/ip_forward
+",
+ mode => '0755',
+ }
+
+ exec { '/usr/local/bin/leap_add_second_ip.sh':
+ subscribe => File['/usr/local/bin/leap_add_second_ip.sh'],
+ }
+
+ cron { 'leap_add_second_ip.sh':
+ command => "/usr/local/bin/leap_add_second_ip.sh",
+ user => 'root',
+ special => 'reboot',
+ }
+
+ # setup the resolver to listen on the vpn IP
+ include site_openvpn::resolver
+
+ include site_shorewall::eip
+
+ package {
+ 'openvpn':
+ ensure => installed;
+ }
+ service {
+ 'openvpn':
+ ensure => running,
+ hasrestart => true,
+ hasstatus => true,
+ require => Exec['concat_/etc/default/openvpn'];
+ }
+
+ file {
+ '/etc/openvpn':
+ ensure => directory,
+ require => Package['openvpn'];
+ }
+
+ file {
+ '/etc/openvpn/keys':
+ ensure => directory,
+ require => Package['openvpn'];
+ }
+
+ concat {
+ '/etc/default/openvpn':
+ owner => root,
+ group => root,
+ mode => 644,
+ warn => true,
+ notify => Service['openvpn'];
+ }
+
+ concat::fragment {
+ 'openvpn.default.header':
+ content => template('openvpn/etc-default-openvpn.erb'),
+ target => '/etc/default/openvpn',
+ order => 01;
+ }
+
+ concat::fragment {
+ "openvpn.default.autostart.${name}":
+ content => 'AUTOSTART=all',
+ target => '/etc/default/openvpn',
+ order => 10;
+ }
+}
diff --git a/puppet/modules/site_openvpn/manifests/keys.pp b/puppet/modules/site_openvpn/manifests/keys.pp
new file mode 100644
index 00000000..f3c5b423
--- /dev/null
+++ b/puppet/modules/site_openvpn/manifests/keys.pp
@@ -0,0 +1,51 @@
+class site_openvpn::keys {
+
+ x509::key {
+ 'leap_openvpn':
+ content => $site_openvpn::x509_config['key'],
+ notify => Service[openvpn];
+ }
+
+ x509::cert {
+ 'leap_openvpn':
+ content => $site_openvpn::x509_config['cert'],
+ notify => Service[openvpn];
+ }
+
+ x509::ca {
+ 'leap_ca':
+ content => $site_openvpn::x509_config['ca_cert'],
+ notify => Service[openvpn];
+ }
+
+ file { '/etc/openvpn/keys/dh.pem':
+ content => $site_openvpn::x509_config['dh'],
+ mode => '0644',
+ }
+
+ #
+ # CA bundle -- we want to have the possibility of allowing multiple CAs.
+ # For now, the reason is to transition to using client CA. In the future,
+ # we will want to be able to smoothly phase out one CA and phase in another.
+ # I tried "--capath" for this, but it did not work.
+ #
+
+ concat {
+ '/etc/openvpn/ca_bundle.pem':
+ owner => root,
+ group => root,
+ mode => 644,
+ warn => true,
+ notify => Service['openvpn'];
+ }
+
+ concat::fragment {
+ 'client_ca_cert':
+ content => $site_openvpn::x509_config['client_ca_cert'],
+ target => '/etc/openvpn/ca_bundle.pem';
+ 'ca_cert':
+ content => $site_openvpn::x509_config['ca_cert'],
+ target => '/etc/openvpn/ca_bundle.pem';
+ }
+
+}
diff --git a/puppet/modules/site_openvpn/manifests/resolver.pp b/puppet/modules/site_openvpn/manifests/resolver.pp
new file mode 100644
index 00000000..d3963c95
--- /dev/null
+++ b/puppet/modules/site_openvpn/manifests/resolver.pp
@@ -0,0 +1,36 @@
+class site_openvpn::resolver {
+
+ # this is an unfortunate way to get around the fact that the version of
+ # unbound we are working with does not accept a wildcard include directive
+ # (/etc/unbound/conf.d/*), when it does, these line definitions should
+ # go away and instead the caching_resolver should be configured to
+ # include: /etc/unbound/conf.d/*
+
+ line {
+ 'add_tcp_resolver':
+ ensure => present,
+ file => '/etc/unbound/unbound.conf',
+ line => 'server: include: /etc/unbound/conf.d/vpn_tcp_resolver',
+ notify => Service['unbound'];
+
+ 'add_udp_resolver':
+ ensure => present,
+ file => '/etc/unbound/unbound.conf',
+ line => 'server: include: /etc/unbound/conf.d/vpn_udp_resolver',
+ notify => Service['unbound'];
+ }
+
+ file {
+ '/etc/unbound/conf.d/vpn_udp_resolver':
+ content => "interface: ${site_openvpn::openvpn_udp_network_prefix}.1\naccess-control: ${site_openvpn::openvpn_udp_network_prefix}.0/${site_openvpn::openvpn_udp_cidr} allow\n",
+ owner => root, group => root, mode => '0644',
+ require => Service['openvpn'],
+ notify => Service['unbound'];
+
+ '/etc/unbound/conf.d/vpn_tcp_resolver':
+ content => "interface: ${site_openvpn::openvpn_tcp_network_prefix}.1\naccess-control: ${site_openvpn::openvpn_tcp_network_prefix}.0/${site_openvpn::openvpn_tcp_cidr} allow\n",
+ owner => root, group => root, mode => '0644',
+ require => Service['openvpn'],
+ notify => Service['unbound'];
+ }
+}
diff --git a/puppet/modules/site_openvpn/manifests/server_config.pp b/puppet/modules/site_openvpn/manifests/server_config.pp
new file mode 100644
index 00000000..de273b46
--- /dev/null
+++ b/puppet/modules/site_openvpn/manifests/server_config.pp
@@ -0,0 +1,166 @@
+#
+# Cipher discussion
+# ================================
+#
+# We want to specify explicit values for the crypto options to prevent a MiTM from forcing
+# a weaker cipher. These should be set in both the server and the client ('auth' and 'cipher'
+# MUST be the same on both ends or no data will get transmitted).
+#
+# tls-cipher DHE-RSA-AES128-SHA
+#
+# dkg: For the TLS control channel, we want to make sure we choose a
+# key exchange mechanism that has PFS (meaning probably some form of ephemeral
+# Diffie-Hellman key exchange), and that uses a standard, well-tested cipher
+# (I recommend AES, and 128 bits is probably fine, since there are some known
+# weaknesses in the 192- and 256-bit key schedules). That leaves us with the
+# choice of public key algorithms: /usr/sbin/openvpn --show-tls | grep DHE |
+# grep AES128 | grep GCM.
+#
+# elijah:
+# I could not get any of these working:
+# * openvpn --show-tls | grep GCM
+# * openvpn --show-tls | grep DHE | grep AES128 | grep SHA256
+# so, i went with this:
+# * openvpn --show-tls | grep DHE | grep AES128 | grep -v SHA256 | grep -v GCM
+# Also, i couldn't get any of the elliptical curve algorithms to work. Not sure how
+# our cert generation interacts with the tls-cipher algorithms.
+#
+# note: in my tests, DHE-RSA-AES256-SHA is the one it negotiates if no value is set.
+#
+# auth SHA1
+#
+# dkg: For HMAC digest to authenticate packets, we just want SHA256. OpenVPN lists
+# a number of “digest” with names like “RSA-SHA256”, but this are legacy and
+# should be avoided.
+#
+# elijah: i am not so sure that the digest algo matters for 'auth' option, because
+# i think an attacker would have to forge the digest in real time, which is still far from
+# a possibility for SHA1. So, i am leaving the default for now (SHA1).
+#
+# cipher AES-128-CBC
+#
+# dkg: For the choice of cipher, we need to select an algorithm and a
+# cipher mode. OpenVPN defaults to Blowfish, which is a fine algorithm — but
+# our control channel is already relying on AES not being broken; if the
+# control channel is cracked, then the key material for the tunnel is exposed,
+# and the choice of algorithm is moot. So it makes more sense to me to rely on
+# the same cipher here: AES128. As for the cipher mode, OFB seems cleaner to
+# me, but CBC is more well-tested, and the OpenVPN man page (at least as of
+# version 2.2.1) says “CBC is recommended and CFB and OFB should be considered
+# advanced modes.”
+#
+# note: the default is BF-CBC (blowfish)
+#
+
+define site_openvpn::server_config ($port, $proto, $local, $server, $push, $management ) {
+
+ $openvpn_configname = $name
+
+ concat {
+ "/etc/openvpn/$openvpn_configname.conf":
+ owner => root,
+ group => root,
+ mode => 644,
+ warn => true,
+ require => File['/etc/openvpn'],
+ notify => Service['openvpn'];
+ }
+
+ openvpn::option {
+ "ca $openvpn_configname":
+ key => 'ca',
+ value => '/etc/openvpn/ca_bundle.pem',
+ server => $openvpn_configname;
+ "cert $openvpn_configname":
+ key => 'cert',
+ value => '/etc/x509/certs/leap_openvpn.crt',
+ server => $openvpn_configname;
+ "key $openvpn_configname":
+ key => 'key',
+ value => '/etc/x509/keys/leap_openvpn.key',
+ server => $openvpn_configname;
+ "dh $openvpn_configname":
+ key => 'dh',
+ value => '/etc/openvpn/keys/dh.pem',
+ server => $openvpn_configname;
+ "tls-cipher $openvpn_configname":
+ key => 'tls-cipher',
+ value => 'DHE-RSA-AES128-SHA',
+ server => $openvpn_configname;
+ "auth $openvpn_configname":
+ key => 'auth',
+ value => 'SHA1',
+ server => $openvpn_configname;
+ "cipher $openvpn_configname":
+ key => 'cipher',
+ value => 'AES-128-CBC',
+ server => $openvpn_configname;
+ "dev $openvpn_configname":
+ key => 'dev',
+ value => 'tun',
+ server => $openvpn_configname;
+ "duplicate-cn $openvpn_configname":
+ key => 'duplicate-cn',
+ server => $openvpn_configname;
+ "keepalive $openvpn_configname":
+ key => 'keepalive',
+ value => '5 20',
+ server => $openvpn_configname;
+ "local $openvpn_configname":
+ key => 'local',
+ value => $local,
+ server => $openvpn_configname;
+ "mute $openvpn_configname":
+ key => 'mute',
+ value => '5',
+ server => $openvpn_configname;
+ "mute-replay-warnings $openvpn_configname":
+ key => 'mute-replay-warnings',
+ server => $openvpn_configname;
+ "management $openvpn_configname":
+ key => 'management',
+ value => $management,
+ server => $openvpn_configname;
+ "proto $openvpn_configname":
+ key => 'proto',
+ value => $proto,
+ server => $openvpn_configname;
+ "push1 $openvpn_configname":
+ key => 'push',
+ value => $push,
+ server => $openvpn_configname;
+ "push2 $openvpn_configname":
+ key => 'push',
+ value => '"redirect-gateway def1"',
+ server => $openvpn_configname;
+ "script-security $openvpn_configname":
+ key => 'script-security',
+ value => '2',
+ server => $openvpn_configname;
+ "server $openvpn_configname":
+ key => 'server',
+ value => $server,
+ server => $openvpn_configname;
+ "status $openvpn_configname":
+ key => 'status',
+ value => '/var/run/openvpn-status 10',
+ server => $openvpn_configname;
+ "status-version $openvpn_configname":
+ key => 'status-version',
+ value => '3',
+ server => $openvpn_configname;
+ "topology $openvpn_configname":
+ key => 'topology',
+ value => 'subnet',
+ server => $openvpn_configname;
+ # no need for server-up.sh right now
+ #"up $openvpn_configname":
+ # key => 'up',
+ # value => '/etc/openvpn/server-up.sh',
+ # server => $openvpn_configname;
+ "verb $openvpn_configname":
+ key => 'verb',
+ value => '3',
+ server => $openvpn_configname;
+ }
+}
diff --git a/puppet/modules/site_shorewall/manifests/couchdb.pp b/puppet/modules/site_shorewall/manifests/couchdb.pp
new file mode 100644
index 00000000..9fa59569
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/couchdb.pp
@@ -0,0 +1,23 @@
+class site_shorewall::couchdb {
+
+ include site_shorewall::defaults
+
+ $couchdb_port = '6984'
+
+ # define macro for incoming services
+ file { '/etc/shorewall/macro.leap_couchdb':
+ content => "PARAM - - tcp $couchdb_port",
+ notify => Service['shorewall'],
+ require => Package['shorewall']
+ }
+
+
+ shorewall::rule {
+ 'net2fw-couchdb':
+ source => 'net',
+ destination => '$FW',
+ action => 'leap_couchdb(ACCEPT)',
+ order => 200;
+ }
+
+}
diff --git a/puppet/modules/site_shorewall/manifests/defaults.pp b/puppet/modules/site_shorewall/manifests/defaults.pp
new file mode 100644
index 00000000..d5639a90
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/defaults.pp
@@ -0,0 +1,54 @@
+class site_shorewall::defaults {
+ include shorewall
+
+ # be safe for development
+ #if ( $::virtual == 'virtualbox') { $shorewall_startup='0' }
+
+ $ip_address = hiera('ip_address')
+ # a special case for vagrant interfaces
+ $interface = $::virtual ? {
+ virtualbox => [ 'eth0', 'eth1' ],
+ default => getvar("interface_${ip_address}")
+ }
+
+
+ # If you want logging:
+ shorewall::params {
+ 'LOG': value => 'debug';
+ }
+
+ shorewall::zone {'net': type => 'ipv4'; }
+
+
+ # define interfaces
+ shorewall::interface { $interface:
+ zone => 'net',
+ options => 'tcpflags,blacklist,nosmurfs';
+ }
+
+ shorewall::routestopped { $interface: }
+
+ shorewall::policy {
+ 'fw-to-all':
+ sourcezone => 'fw',
+ destinationzone => 'all',
+ policy => 'ACCEPT',
+ order => 100;
+ 'all-to-all':
+ sourcezone => 'all',
+ destinationzone => 'all',
+ policy => 'DROP',
+ order => 200;
+ }
+
+ shorewall::rule {
+ # ping party
+ 'all2all-ping':
+ source => 'all',
+ destination => 'all',
+ action => 'Ping(ACCEPT)',
+ order => 200;
+ }
+
+ include site_shorewall::sshd
+}
diff --git a/puppet/modules/site_shorewall/manifests/dnat_rule.pp b/puppet/modules/site_shorewall/manifests/dnat_rule.pp
new file mode 100644
index 00000000..68f480d8
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/dnat_rule.pp
@@ -0,0 +1,25 @@
+define site_shorewall::dnat_rule {
+
+ $port = $name
+ if $port != 1194 {
+ shorewall::rule {
+ "dnat_tcp_port_$port":
+ action => 'DNAT',
+ source => 'net',
+ destination => "\$FW:${site_openvpn::openvpn_gateway_address}:1194",
+ proto => 'tcp',
+ destinationport => $port,
+ order => 100;
+ }
+
+ shorewall::rule {
+ "dnat_udp_port_$port":
+ action => 'DNAT',
+ source => 'net',
+ destination => "\$FW:${site_openvpn::openvpn_gateway_address}:1194",
+ proto => 'udp',
+ destinationport => $port,
+ order => 100;
+ }
+ }
+}
diff --git a/puppet/modules/site_shorewall/manifests/eip.pp b/puppet/modules/site_shorewall/manifests/eip.pp
new file mode 100644
index 00000000..4e5a5d48
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/eip.pp
@@ -0,0 +1,75 @@
+class site_shorewall::eip {
+
+ include site_shorewall::defaults
+ include site_shorewall::ip_forward
+
+ $openvpn_config = hiera('openvpn')
+ $openvpn_ports = $openvpn_config['ports']
+ $openvpn_gateway_address = $site_openvpn::openvpn_gateway_address
+
+ # define macro for incoming services
+ file { '/etc/shorewall/macro.leap_eip':
+ content => "PARAM - - tcp 1194
+PARAM - - udp 1194
+",
+ notify => Service['shorewall']
+ }
+
+
+ shorewall::interface {
+ 'tun0':
+ zone => 'eip',
+ options => 'tcpflags,blacklist,nosmurfs';
+ 'tun1':
+ zone => 'eip',
+ options => 'tcpflags,blacklist,nosmurfs'
+ }
+
+
+ shorewall::zone {'eip':
+ type => 'ipv4'; }
+
+ case $::virtual {
+ 'virtualbox': {
+ shorewall::masq {
+ 'eth0_tcp':
+ interface => 'eth0',
+ source => "${site_openvpn::openvpn_tcp_network_prefix}.0/${site_openvpn::openvpn_tcp_cidr}";
+ 'eth0_udp':
+ interface => 'eth0',
+ source => "${site_openvpn::openvpn_udp_network_prefix}.0/${site_openvpn::openvpn_udp_cidr}"; }
+ }
+ default: {
+ $interface = $site_shorewall::defaults::interface
+ shorewall::masq {
+ "${interface}_tcp":
+ interface => $interface,
+ source => "${site_openvpn::openvpn_tcp_network_prefix}.0/${site_openvpn::openvpn_tcp_cidr}";
+
+ "${interface}_udp":
+ interface => $interface,
+ source => "${site_openvpn::openvpn_udp_network_prefix}.0/${site_openvpn::openvpn_udp_cidr}"; }
+ }
+ }
+
+ shorewall::policy {
+ 'eip-to-all':
+ sourcezone => 'eip',
+ destinationzone => 'all',
+ policy => 'ACCEPT',
+ order => 100;
+ }
+
+ shorewall::rule {
+ 'net2fw-openvpn':
+ source => 'net',
+ destination => '$FW',
+ action => 'leap_eip(ACCEPT)',
+ order => 200;
+ }
+
+ # create dnat rule for each port
+ #create_resources('site_shorewall::dnat_rule', $openvpn_ports)
+ site_shorewall::dnat_rule { $openvpn_ports: }
+
+}
diff --git a/puppet/modules/site_shorewall/manifests/ip_forward.pp b/puppet/modules/site_shorewall/manifests/ip_forward.pp
new file mode 100644
index 00000000..d53ee8a5
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/ip_forward.pp
@@ -0,0 +1,10 @@
+class site_shorewall::ip_forward {
+ include augeas
+ augeas { 'enable_ip_forwarding':
+ changes => 'set /files/etc/shorewall/shorewall.conf/IP_FORWARDING Yes',
+ lens => 'Shellvars.lns',
+ incl => '/etc/shorewall/shorewall.conf',
+ notify => Service[shorewall],
+ require => [ Class[augeas], Package[shorewall] ];
+ }
+}
diff --git a/puppet/modules/site_shorewall/manifests/monitor.pp b/puppet/modules/site_shorewall/manifests/monitor.pp
new file mode 100644
index 00000000..f4ed4f7c
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/monitor.pp
@@ -0,0 +1,8 @@
+class site_shorewall::monitor {
+
+ include site_shorewall::defaults
+ include site_shorewall::service::http
+ include site_shorewall::service::https
+
+
+}
diff --git a/puppet/modules/site_shorewall/manifests/service/http.pp b/puppet/modules/site_shorewall/manifests/service/http.pp
new file mode 100644
index 00000000..74b874d5
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/service/http.pp
@@ -0,0 +1,13 @@
+class site_shorewall::service::http {
+
+ include site_shorewall::defaults
+
+ shorewall::rule {
+ 'net2fw-http':
+ source => 'net',
+ destination => '$FW',
+ action => 'HTTP(ACCEPT)',
+ order => 200;
+ }
+
+}
diff --git a/puppet/modules/site_shorewall/manifests/service/https.pp b/puppet/modules/site_shorewall/manifests/service/https.pp
new file mode 100644
index 00000000..4a8b119c
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/service/https.pp
@@ -0,0 +1,12 @@
+class site_shorewall::service::https {
+
+ include site_shorewall::defaults
+
+ shorewall::rule {
+ 'net2fw-https':
+ source => 'net',
+ destination => '$FW',
+ action => 'HTTPS(ACCEPT)',
+ order => 200;
+ }
+}
diff --git a/puppet/modules/site_shorewall/manifests/service/webapp_api.pp b/puppet/modules/site_shorewall/manifests/service/webapp_api.pp
new file mode 100644
index 00000000..0c6c824d
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/service/webapp_api.pp
@@ -0,0 +1,22 @@
+class site_shorewall::service::webapp_api {
+
+ $api = hiera('api')
+ $api_port = $api['port']
+
+ # define macro for incoming services
+ file { '/etc/shorewall/macro.leap_webapp_api':
+ content => "PARAM - - tcp $api_port ",
+ notify => Service['shorewall'],
+ require => Package['shorewall']
+ }
+
+
+ shorewall::rule {
+ 'net2fw-webapp_api':
+ source => 'net',
+ destination => '$FW',
+ action => 'leap_webapp_api(ACCEPT)',
+ order => 200;
+ }
+
+}
diff --git a/puppet/modules/site_shorewall/manifests/sshd.pp b/puppet/modules/site_shorewall/manifests/sshd.pp
new file mode 100644
index 00000000..a8e09e42
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/sshd.pp
@@ -0,0 +1,24 @@
+class site_shorewall::sshd {
+
+ $ssh_config = hiera('ssh')
+ $ssh_port = $ssh_config['port']
+
+ include shorewall
+
+ # define macro for incoming sshd
+ file { '/etc/shorewall/macro.leap_sshd':
+ content => "PARAM - - tcp $ssh_port",
+ notify => Service['shorewall'],
+ require => Package['shorewall']
+ }
+
+
+ shorewall::rule {
+ # outside to server
+ 'net2fw-ssh':
+ source => 'net',
+ destination => '$FW',
+ action => 'leap_sshd(ACCEPT)',
+ order => 200;
+ }
+}
diff --git a/puppet/modules/site_shorewall/manifests/tor.pp b/puppet/modules/site_shorewall/manifests/tor.pp
new file mode 100644
index 00000000..f35af985
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/tor.pp
@@ -0,0 +1,25 @@
+class site_shorewall::tor {
+
+ include site_shorewall::defaults
+ include site_shorewall::ip_forward
+
+ $tor_port = '9001'
+
+ # define macro for incoming services
+ file { '/etc/shorewall/macro.leap_tor':
+ content => "PARAM - - tcp $tor_port ",
+ notify => Service['shorewall'],
+ require => Package['shorewall']
+ }
+
+
+ shorewall::rule {
+ 'net2fw-tor':
+ source => 'net',
+ destination => '$FW',
+ action => 'leap_tor(ACCEPT)',
+ order => 200;
+ }
+
+ include site_shorewall::service::http
+}
diff --git a/puppet/modules/site_shorewall/manifests/webapp.pp b/puppet/modules/site_shorewall/manifests/webapp.pp
new file mode 100644
index 00000000..d12bbc8f
--- /dev/null
+++ b/puppet/modules/site_shorewall/manifests/webapp.pp
@@ -0,0 +1,6 @@
+class site_shorewall::webapp {
+
+ include site_shorewall::defaults
+ include site_shorewall::service::https
+ include site_shorewall::service::webapp_api
+}
diff --git a/puppet/modules/site_sshd/manifests/init.pp b/puppet/modules/site_sshd/manifests/init.pp
new file mode 100644
index 00000000..630e9bdf
--- /dev/null
+++ b/puppet/modules/site_sshd/manifests/init.pp
@@ -0,0 +1 @@
+class site_sshd {}
diff --git a/puppet/modules/site_sshd/manifests/ssh_key.pp b/puppet/modules/site_sshd/manifests/ssh_key.pp
new file mode 100644
index 00000000..b47b2ebd
--- /dev/null
+++ b/puppet/modules/site_sshd/manifests/ssh_key.pp
@@ -0,0 +1,3 @@
+define site_sshd::ssh_key($key) {
+ # ... todo: deploy ssh_key
+}
diff --git a/puppet/modules/site_tor/manifests/disable_exit.pp b/puppet/modules/site_tor/manifests/disable_exit.pp
new file mode 100644
index 00000000..73016646
--- /dev/null
+++ b/puppet/modules/site_tor/manifests/disable_exit.pp
@@ -0,0 +1,7 @@
+class site_tor::disable_exit {
+ tor::daemon::exit_policy {
+ 'no_exit_at_all':
+ reject => '*:*';
+ }
+}
+
diff --git a/puppet/modules/site_tor/manifests/init.pp b/puppet/modules/site_tor/manifests/init.pp
new file mode 100644
index 00000000..ceb6fb13
--- /dev/null
+++ b/puppet/modules/site_tor/manifests/init.pp
@@ -0,0 +1,28 @@
+class site_tor {
+ tag 'leap_service'
+
+ $tor = hiera('tor')
+ $bandwidth_rate = $tor['bandwidth_rate']
+ $tor_type = $tor['type']
+ $nickname = $tor['nickname']
+ $contact_email = $tor['contacts']
+
+ $address = hiera('ip_address')
+
+ class { 'tor::daemon': }
+ tor::daemon::relay { $nickname:
+ port => 9001,
+ address => $address,
+ contact_info => $contact_email,
+ bandwidth_rate => $bandwidth_rate,
+ }
+
+ tor::daemon::directory { $::hostname: port => 80 }
+
+ include site_shorewall::tor
+
+ if ( $tor_type != 'exit' ) {
+ include site_tor::disable_exit
+ }
+
+}
diff --git a/puppet/modules/site_webapp/manifests/apache.pp b/puppet/modules/site_webapp/manifests/apache.pp
new file mode 100644
index 00000000..554b9147
--- /dev/null
+++ b/puppet/modules/site_webapp/manifests/apache.pp
@@ -0,0 +1,65 @@
+class site_webapp::apache {
+
+ $web_api = hiera('api')
+ $api_domain = $web_api['domain']
+ $api_port = $web_api['port']
+
+ $x509 = hiera('x509')
+ $commercial_key = $x509['commercial_key']
+ $commercial_cert = $x509['commercial_cert']
+ $commercial_root = $x509['commercial_ca_cert']
+ $api_key = $x509['key']
+ $api_cert = $x509['cert']
+ $api_root = $x509['ca_cert']
+
+ $apache_no_default_site = true
+ include apache::ssl
+
+ apache::module {
+ 'alias': ensure => present;
+ 'rewrite': ensure => present;
+ 'headers': ensure => present;
+ }
+
+ class { 'passenger': use_munin => false }
+
+ apache::vhost::file {
+ 'leap_webapp':
+ content => template('site_apache/vhosts.d/leap_webapp.conf.erb')
+ }
+
+ apache::vhost::file {
+ 'api':
+ content => template('site_apache/vhosts.d/api.conf.erb')
+ }
+
+ x509::key {
+ 'leap_webapp':
+ content => $commercial_key,
+ notify => Service[apache];
+
+ 'leap_api':
+ content => $api_key,
+ notify => Service[apache];
+ }
+
+ x509::cert {
+ 'leap_webapp':
+ content => $commercial_cert,
+ notify => Service[apache];
+
+ 'leap_api':
+ content => $api_cert,
+ notify => Service[apache];
+ }
+
+ x509::ca {
+ 'leap_webapp':
+ content => $commercial_root,
+ notify => Service[apache];
+
+ 'leap_api':
+ content => $api_root,
+ notify => Service[apache];
+ }
+}
diff --git a/puppet/modules/site_webapp/manifests/client_ca.pp b/puppet/modules/site_webapp/manifests/client_ca.pp
new file mode 100644
index 00000000..0d9b15d6
--- /dev/null
+++ b/puppet/modules/site_webapp/manifests/client_ca.pp
@@ -0,0 +1,25 @@
+##
+## This is for the special CA that is used exclusively for generating
+## client certificates by the webapp.
+##
+
+class site_webapp::client_ca {
+ include x509::variables
+
+ $x509 = hiera('x509')
+ $cert_path = "${x509::variables::certs}/leap_client_ca.crt"
+ $key_path = "${x509::variables::keys}/leap_client_ca.key"
+
+ x509::key {
+ 'leap_client_ca':
+ source => $x509['client_ca_key'],
+ group => 'leap-webapp',
+ notify => Service[apache];
+ }
+
+ x509::cert {
+ 'leap_client_ca':
+ source => $x509['client_ca_cert'],
+ notify => Service[apache];
+ }
+}
diff --git a/puppet/modules/site_webapp/manifests/couchdb.pp b/puppet/modules/site_webapp/manifests/couchdb.pp
new file mode 100644
index 00000000..6cac666f
--- /dev/null
+++ b/puppet/modules/site_webapp/manifests/couchdb.pp
@@ -0,0 +1,16 @@
+class site_webapp::couchdb {
+
+ $webapp = hiera('webapp')
+ $couchdb_host = $webapp['couchdb_hosts']
+ $couchdb_user = $webapp['couchdb_user']['username']
+ $couchdb_password = $webapp['couchdb_user']['password']
+
+ file {
+ '/srv/leap-webapp/config/couchdb.yml':
+ content => template('site_webapp/couchdb.yml.erb'),
+ owner => leap-webapp,
+ group => leap-webapp,
+ mode => '0600';
+ }
+
+}
diff --git a/puppet/modules/site_webapp/manifests/init.pp b/puppet/modules/site_webapp/manifests/init.pp
new file mode 100644
index 00000000..e8134521
--- /dev/null
+++ b/puppet/modules/site_webapp/manifests/init.pp
@@ -0,0 +1,117 @@
+class site_webapp {
+ tag 'leap_service'
+ $definition_files = hiera('definition_files')
+ $provider = $definition_files['provider']
+ $eip_service = $definition_files['eip_service']
+ $node_domain = hiera('domain')
+ $provider_domain = $node_domain['full_suffix']
+ $webapp = hiera('webapp')
+
+ Class[Ruby] -> Class[rubygems] -> Class[bundler::install]
+
+ class { 'ruby': ruby_version => '1.9.3' }
+
+ class { 'bundler::install': install_method => 'package' }
+
+ include rubygems
+ include site_webapp::apache
+ include site_webapp::couchdb
+ include site_webapp::client_ca
+
+ group { 'leap-webapp':
+ ensure => present,
+ allowdupe => false;
+ }
+
+ user { 'leap-webapp':
+ ensure => present,
+ allowdupe => false,
+ gid => 'leap-webapp',
+ groups => 'ssl-cert',
+ home => '/srv/leap-webapp',
+ require => [ Group['leap-webapp'] ];
+ }
+
+ file { '/srv/leap-webapp':
+ ensure => directory,
+ owner => 'leap-webapp',
+ group => 'leap-webapp',
+ require => User['leap-webapp'];
+ }
+
+ vcsrepo { '/srv/leap-webapp':
+ ensure => present,
+ revision => 'origin/master',
+ provider => git,
+ source => 'git://code.leap.se/leap_web',
+ owner => 'leap-webapp',
+ group => 'leap-webapp',
+ require => [ User['leap-webapp'], Group['leap-webapp'] ],
+ notify => Exec['bundler_update']
+ }
+
+ exec { 'bundler_update':
+ cwd => '/srv/leap-webapp',
+ command => '/bin/bash -c "/usr/bin/bundle check || /usr/bin/bundle install --path vendor/bundle"',
+ unless => '/usr/bin/bundle check',
+ user => 'leap-webapp',
+ timeout => 600,
+ require => [ Class['bundler::install'], Vcsrepo['/srv/leap-webapp'] ],
+ notify => Service['apache'];
+ }
+
+ exec { 'compile_assets':
+ cwd => '/srv/leap-webapp',
+ command => '/bin/bash -c "/usr/bin/bundle exec rake assets:precompile"',
+ user => 'leap-webapp',
+ require => Exec['bundler_update'],
+ notify => Service['apache'];
+ }
+
+ file {
+ '/srv/leap-webapp/public/provider.json':
+ content => $provider,
+ owner => leap-webapp, group => leap-webapp, mode => '0644';
+
+ '/srv/leap-webapp/public/ca.crt':
+ ensure => link,
+ target => '/usr/local/share/ca-certificates/leap_api.crt';
+
+ '/srv/leap-webapp/public/config':
+ ensure => directory,
+ owner => leap-webapp, group => leap-webapp, mode => '0755';
+
+ '/srv/leap-webapp/public/config/eip-service.json':
+ content => $eip_service,
+ owner => leap-webapp, group => leap-webapp, mode => '0644';
+ }
+
+ try::file {
+ '/srv/leap-webapp/public/favicon.ico':
+ ensure => 'link',
+ target => $webapp['favicon'];
+
+ '/srv/leap-webapp/app/assets/stylesheets/tail.scss':
+ ensure => 'link',
+ target => $webapp['tail_scss'];
+
+ '/srv/leap-webapp/app/assets/stylesheets/head.scss':
+ ensure => 'link',
+ target => $webapp['head_scss'];
+
+ '/srv/leap-webapp/public/img':
+ ensure => 'link',
+ target => $webapp['img_dir'];
+ }
+
+ file {
+ '/srv/leap-webapp/config/config.yml':
+ content => template('site_webapp/config.yml.erb'),
+ owner => leap-webapp,
+ group => leap-webapp,
+ mode => '0600';
+ }
+
+ include site_shorewall::webapp
+
+}
diff --git a/puppet/modules/site_webapp/templates/config.yml.erb b/puppet/modules/site_webapp/templates/config.yml.erb
new file mode 100644
index 00000000..9cf85f0c
--- /dev/null
+++ b/puppet/modules/site_webapp/templates/config.yml.erb
@@ -0,0 +1,5 @@
+production:
+ admins: [admin]
+ domain: <%= @provider_domain %>
+ client_ca_key: <%= scope.lookupvar('site_webapp::client_ca::key_path') %>
+ client_ca_cert: <%= scope.lookupvar('site_webapp::client_ca::cert_path') %>
diff --git a/puppet/modules/site_webapp/templates/couchdb.yml.erb b/puppet/modules/site_webapp/templates/couchdb.yml.erb
new file mode 100644
index 00000000..ee521713
--- /dev/null
+++ b/puppet/modules/site_webapp/templates/couchdb.yml.erb
@@ -0,0 +1,8 @@
+production:
+ prefix: ""
+ protocol: 'https'
+ host: <%= @couchdb_host %>
+ port: 6984
+ username: <%= @couchdb_user %>
+ password: <%= @couchdb_password %>
+
diff --git a/puppet/modules/sshd b/puppet/modules/sshd
new file mode 160000
+Subproject bd2e283ab59430a7b3194804f1c8da7a9b58f8f
diff --git a/puppet/modules/stdlib b/puppet/modules/stdlib
new file mode 160000
+Subproject 2df66c041109ecca1099bf3977657572cc32ad2
diff --git a/puppet/modules/tor b/puppet/modules/tor
new file mode 160000
+Subproject a780e84001177f10a86a7bf824589c0553f513a
diff --git a/puppet/modules/try/README.md b/puppet/modules/try/README.md
new file mode 100644
index 00000000..3888661e
--- /dev/null
+++ b/puppet/modules/try/README.md
@@ -0,0 +1,13 @@
+This module provides a "try" wrapper around common resource types.
+
+For example:
+
+ try::file {
+ '/path/to/file':
+ ensure => 'link',
+ target => $target;
+ }
+
+This will work just like `file`, but will silently fail if `$target` is undefined or the file does not exist.
+
+So far, only `file` type with symlinks works.
diff --git a/puppet/modules/try/manifests/file.pp b/puppet/modules/try/manifests/file.pp
new file mode 100644
index 00000000..406c0b7a
--- /dev/null
+++ b/puppet/modules/try/manifests/file.pp
@@ -0,0 +1,51 @@
+#
+# like built-in type "file", but gets gracefully ignored if the target does not exist or is undefined.
+#
+# /bin/true and /usr/bin/test are hardcoded to their paths in debian.
+#
+
+define try::file (
+ $ensure = undef,
+ $target = undef,
+ $restore = true) {
+
+ if $target != undef {
+ exec { "check_${name}":
+ command => "/bin/true",
+ onlyif => "/usr/bin/test -e '${target}'",
+ loglevel => info;
+ }
+ file { "$name":
+ ensure => $ensure,
+ target => $target,
+ require => Exec["check_${name}"],
+ loglevel => info;
+ }
+ }
+
+ #
+ # if the target does not exist (or is undef), and the file happens to be in a git repo,
+ # then restore the file to its original state.
+ #
+ if $target == undef or $restore {
+ $file_basename = basename($name)
+ $file_dirname = dirname($name)
+ $command = "git rev-parse && unlink '${name}'; git checkout -- '${file_basename}' && chown --reference='${file_dirname}' '${name}'; true"
+ debug($command)
+
+ if $target == undef {
+ exec { "restore_${name}":
+ command => $command,
+ cwd => $file_dirname,
+ loglevel => info;
+ }
+ } else {
+ exec { "restore_${name}":
+ unless => "/usr/bin/test -e '${target}'",
+ command => $command,
+ cwd => $file_dirname,
+ loglevel => info;
+ }
+ }
+ }
+}
diff --git a/puppet/modules/try/manifests/init.pp b/puppet/modules/try/manifests/init.pp
new file mode 100644
index 00000000..1d2108c9
--- /dev/null
+++ b/puppet/modules/try/manifests/init.pp
@@ -0,0 +1,3 @@
+class try {
+
+}
diff --git a/puppet/modules/unbound b/puppet/modules/unbound
new file mode 160000
+Subproject ca7eb732064ce29fc83d4c32a4df7d9512d4580
diff --git a/puppet/modules/vcsrepo b/puppet/modules/vcsrepo
new file mode 160000
+Subproject 04851c28b12973c679fc9f234fd0f5a193df9d7
diff --git a/puppet/modules/x509 b/puppet/modules/x509
new file mode 160000
+Subproject 19254a38c1c372ae7912ea9f15500b9b1cbffe8