Version information
This version is compatible with:
- Puppet Enterprise 2019.8.x, 2019.7.x, 2019.5.x, 2019.4.x, 2019.3.x, 2019.2.x, 2019.1.x, 2019.0.x, 2018.1.x, 2017.3.x, 2017.2.x, 2017.1.x, 2016.5.x, 2016.4.x
- Puppet >= 4.2.1 < 7.0.0
- , ,
Start using this module
Add this module to your Puppetfile:
mod 'puppetlabs-kubernetes', '3.2.2'
Learn more about managing modules with a PuppetfileDocumentation
Kubernetes
Table of Contents
- Description
- Setup - The basics of getting started with kubernetes
- Reference - An under-the-hood peek at what the module is doing and how
- Limitations - OS compatibility, etc.
- Development - Guide for contributing to the module
Description
This module installs and configures Kubernetes which is an open-source system for automating deployment, scaling, and management of containerized applications. For efficient management and discovery, containers that make up an application are grouped into logical units.
To bootstrap a Kubernetes cluster in a secure and extensible way, this module uses the kubeadm toolkit.
Setup
Install this module, generate the configuration, add the OS and hostname yaml files to Hiera, and configure your node.
Included in this module is Kubetool, a configuration tool that auto-generates the Hiera security parameters, the discovery token hash, and other configurations for your Kubernetes cluster. To simplify installation and use, the tool is available as a Docker image.
Generating the module configuration
If Docker is not installed on your workstation, install it from here.
The Kubetool Docker image takes each parameter as an environment variable.
Note:: The version of Kubetool you use must match the version of the module on the Puppet Forge. For example, if using the module version 1.0.0, use puppet/kubetool:1.0.0
.
To output a yaml file into your working directory that corresponds to the operating system you want Kubernetes to run on, and for each controller node, run either of these docker run
commands:
docker run --rm -v $(pwd):/mnt --env-file env puppet/kubetool:{$module_version}
The docker run
command above includes an env
file which is included in the root folder of this repo.
docker run --rm -v $(pwd):/mnt -e OS=debian -e VERSION=1.10.2 -e CONTAINER_RUNTIME=docker -e CNI_PROVIDER=weave -e ETCD_INITIAL_CLUSTER=kube-master:172.17.10.101,kube-replica-master-01:172.17.10.210,kube-replica-master-02:172.17.10.220 -e ETCD_IP="%{::ipaddress_eth1}" -e KUBE_API_ADVERTISE_ADDRESS="%{::ipaddress_eth1}" -e INSTALL_DASHBOARD=true puppet/kubetool:{$module-version}
The above parameters are:
OS
: The operating system Kubernetes runs on.VERSION
: The version of Kubernetes to deploy.CONTAINER_RUNTIME
: The container runtime Kubernetes uses. Set this value todocker
(officially supported) orcri_containerd
. Advanced Kubernetes users can usecri_containerd
, however this requires an increased understanding of Kubernetes, specifically when running applications in a HA cluster. To run a HA cluster and access your applications, an external load balancer is required in front of your cluster. Setting this up is beyond the scope of this module. For more information, see the Kubernetes documentation.CNI_PROVIDER
: The CNI network to install. Set this value toweave
orflannel
.ETCD_INITIAL_CLUSTER
: The server hostnames and IPs in the form ofhostname:ip
. When in production, include three, five, or seven nodes for etcd.ETCD_IP
: The IP each etcd member listens on. We recommend passing the fact for the interface to be used by the cluster.KUBE_API_ADVERTISE_ADDRESS
: The IP each etcd/apiserver instance uses on each controller. We recommend passing the fact for the interface to be used by the cluster.INSTALL_DASHBOARD
: A boolean which specifies whether to install the dashboard.
Kubetool creates:
-
A yaml file that corresponds to the operating system specified by the
OS
parameter. To view the file contents, runcat Debian.yaml
for a Debian system, or runcat RedHat.yaml
for RedHat. The yaml files produced for each member of the etcd cluster contain certificate information to bootstrap an initial etcd cluster. Ensure these are also placed in your hieradata directory at the node level. -
A discovery token hash and encoded values required by Kubernetes. To regenerate the values, including certificates and tokens, run the
kubetool
command again.
Adding the {$OS}.yaml
and {$hostname}.yaml
files to Hiera
Add the {$OS}.yaml
file to the same control repo where your Hiera data is, usually the data
directory. By leveraging location facts, such as the pp_datacenter trusted fact, each cluster can be allocated its own configuration.
Configuring your node
After the {$OS}.yaml
and {$hostname}.yaml
files have been added to the Hiera directory on your Puppet server, configure your node as the controller or worker.
A controller node contains the control plane and etcd. In a production cluster, you should have three, five, or seven controllers. A worker node runs your applications. You can add as many worker nodes as Kubernetes can handle. For information about nodes in Kubernetes, see the Kubernetes documentation.
Note:: A node cannot be a controller and a worker. It must be one or the other.
To make a node a controller, add the following code to the manifest:
class {'kubernetes':
controller => true,
}
To make a node a worker, add the following code to the manifest:
class {'kubernetes':
worker => true,
}
Validating and unit testing the module
This module is compliant with the Puppet Development Kit (PDK), which provides tools to help run unit tests on the module and validate the modules's metadata, syntax, and style.
Note: To run static validations and
unit tests against this module using the pdk validate
and pdk test unit
commands, you must have Puppet 5 or higher installed. In the following examples we have specified Puppet 5.3.6.
To validate the metadata.json file, run the following command:
pdk validate metadata --puppet-version='5.3.6'
To validate the Puppet code and syntax, run the following command:
pdk validate puppet --puppet-version='5.3.6'
Note: The pdk validate ruby
command ignores the excluded directories specified in the .rubocop.yml file. Therefore, to validate the Ruby code style and syntax you must specify the directory the code exists in.
In the following example we validate the Ruby code contained in the lib directory:
pdk validate ruby lib --puppet-version='5.3.6'
To unit test the module, run the following command:
pdk test unit --puppet-version='5.3.6'
Reference
Classes
Public classes
- kubernetes
Private classes
- kubernetes::cluster_roles
- kubernetes::config
- kubernetes::kube_addons
- kubernetes::packages
- kubernetes::repos
- kubernetes::service
Defined types
- kubernetes::kubeadm_init
- kubernetes::kubeadm_join
Parameters
The following parameters are available in the kubernetes
class.
apiserver_cert_extra_sans
A string array of Subject Alternative Names for the API server certificates.
Defaults to []
.
apiserver_extra_arguments
A string array of extra arguments passed to the API server.
Defaults to []
.
cloud_provider
The name of the cloud provider configured in /etc/kubernetes/cloud-config
.
Note: This file is not managed within this module and must be present before bootstrapping the Kubernetes controller.
Defaults to undef
.
cloud_config
The location of the cloud config file used by cloud_provider
. For use with v1.12 and above.
Note: This file is not managed within this module and must be present before bootstrapping the Kubernetes controller.
Defaults to undef
.
cni_network_provider
The URL to get the CNI providers yaml file. kube_tool
sets this value.
Defaults to undef
.
cni_rbac_binding
The download URL for the cni providers rbac rules. Only for use with Calico.
Defaults to undef
.
cni_pod_cidr
Specifies the overlay (internal) network range to use. This value is set by kube_tool
per CNI_PROVIDER
.
Defaults to undef
.
container_runtime
Specifies the runtime that the Kubernetes cluster uses.
Valid values are cri_containerd
or docker
.
Defaults to docker
.
controller
Specifies whether to set the node as a Kubernetes controller.
Valid values are true
, false
.
Defaults to false
.
containerd_version
Specifies the version of the containerd runtime the module installs.
Defaults to 1.1.0
.
containerd_archive
The name of the containerd archive.
Defaults to containerd-${containerd_version}.linux-amd64.tar.gz
.
containerd_source
The download URL for the containerd archive.
Defaults to https://github.com/containerd/containerd/releases/download/v${containerd_version}/${containerd_archive}
.
controller_address
The IP address and port for the controller the worker node joins. For example 172.17.10.101:6443
.
Defaults to undef
.
create_repos
Specifies whether to install the upstream Kubernetes and Docker repos.
Valid values are true
, false
.
Defaults to true
.
disable_swap
Specifies whether to turn off swap setting. This is required for kubeadm.
Valid values are true
, false
.
Defaults to true
.
manage_kernel_modules
Specifies whether to manage the kernel modules needed for kubernetes
Valid values are true
, false
.
Defaults to true
manage_sysctl_settings
Specifies whether to manage the the sysctl settings needed for kubernetes
Valid values are true
, false
.
Defaults to true
discovery_token_hash
The string used to validate to the root CA public key when joining a cluster. This value is created by kubetool
.
Defaults to undef
.
docker_apt_location
The APT repo URL for the Docker packages.
Defaults to https://apt.dockerproject.org/repo
.
docker_apt_release
The release name for the APT repo for the Docker packages.
Defaults to 'ubuntu-${::lsbdistcodename}'
.
docker_apt_repos
The repos to install from the Docker APT url.
Defaults to main
.
docker_version
Specifies the version of the Docker runtime to install.
Defaults to:
17.03.0.ce-1.el7.centos
on RedHat.17.03.0~ce-0~ubuntu-xenial
on Ubuntu.
docker_package_name
The docker package name to download from an upstream repo.
Defaults to docker-engine
.
docker_key_id
The gpg key for the Docker APT repo.
Defaults to '58118E89F3A912897C070ADBF76221572C52609D'
.
docker_key_source
The URL for the Docker APT repo gpg key.
Defaults to https://apt.dockerproject.org/gpg
.
docker_yum_baseurl
The YUM repo URL for the Docker packages.
Defaults to https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
.
docker_yum_gpgkey
The URL for the Docker yum repo gpg key.
Defaults to https://yum.dockerproject.org/gpg
.
etcd_version
Specifies the version of etcd.
Defaults to 3.1.12
.
etcd_archive
Specifies the name of the etcd archive.
Defaults to etcd-v${etcd_version}-linux-amd64.tar.gz
.
etcd_source
The download URL for the etcd archive.
Defaults to https://github.com/coreos/etcd/releases/download/v${etcd_version}/${etcd_archive}
.
etcd_install_method
The method on how to install etcd. Can be either wget
(using etcd_source) or package
(using $etcd_package_name)
Defaults to wget
.
etcd_package_name
The system package name for installing etcd
Defaults to etcd-server
.
etcd_ip
Specifies the IP address etcd uses for communications.
A Hiera is kubernetes::etcd_ip:"%{::ipaddress_enp0s8}"
.
Defaults to undef
.
etcd_initial_cluster
Informs etcd on how many nodes are in the cluster.
A Hiera example is kubernetes::etcd_initial_cluster: kube-master:172.17.10.101,kube-replica-master-01:172.17.10.210,kube-replica-master-02:172.17.10.220
.
Defaults to undef
.
etcd_initial_cluster_state
Informs etcd on the state of the cluster when starting. Useful for adding single nodes to a cluster. Allowed values are new
or existing
.
Defaults to new
etcd_peers
Specifies how etcd lists the peers to connect to the cluster.
A Hiera example is kubernetes::etcd_peers
:
- 172.17.10.101
- 172.17.10.102
- 172.17.10.103
Defaults to undef
etcd_ca_key
The CA certificate key data for the etcd cluster. This value must be passed as string and not as a file.
Defaults to undef
.
etcd_ca_crt
The CA certificate data for the etcd cluster. This value must be passed as string and not as a file.
Defaults to undef
.
etcdclient_key
The client certificate key data for the etcd cluster. This value must be passed as string and not as a file.
Defaults to undef
.
etcdclient_crt
The client certificate data for the etcd cluster. This value must be passed as string not as a file.
Defaults to undef
.
etcdserver_key
The server certificate key data for the etcd cluster. This value must be passed as string not as a file.
Defaults to undef
.
etcdserver_crt
The server certificate data for the etcd cluster . This value must be passed as string not as a file.
Defaults to undef
.
etcdpeer_crt
The peer certificate data for the etcd cluster. This value must be passed as string not as a file.
Defaults to undef
.
etcdpeer_key
The peer certificate key data for the etcd cluster. This value must be passed as string not as a file.
Defaults to undef
.
image_repository
The container registry to pull control plane images from.
Defaults to k8s.gcr.io
install_dashboard
Specifies whether the Kubernetes dashboard is installed.
Valid values are true
, false
.
Defaults to false
.
kubernetes_ca_crt
The cluster's CA certificate. Must be passed as a string and not a file.
Defaults to undef
.
kubernetes_ca_key
The clusters CA key. Must be passed as a string and not a file.
Defaults to undef
.
kube_api_advertise_address
The IP address you want exposed by the API server.
A Hiera example is kubernetes::kube_api_advertise_address:"%{::ipaddress_enp0s8}"
.
Defaults to undef
.
kubernetes_version
The version of the Kubernetes containers to install.
Defaults to 1.10.2
.
kubernetes_package_version
The version the Kubernetes OS packages to install, such as kubectl
and kubelet
.
Defaults to 1.10.2
.
kubeadm_extra_config
A hash containing extra configuration data to be serialised with to_yaml
and appended to the config.yaml file used by kubeadm.
Defaults to {}
.
kubelet_extra_config
A hash containing extra configuration data to be serialised with to_yaml
and appended to Kubelet configuration file for the cluster. Requires DynamicKubeletConfig.
Defaults to {}
.
kubelet_extra_arguments
A string array to be appended to kubeletExtraArgs in the Kubelet's nodeRegistration configuration. It is applied to both masters and nodes. Use this for critical Kubelet settings such as pod-infra-container-image
which may be problematic to configure via kubelet_extra_config and DynamicKubeletConfig.
Defaults to []
.
kubernetes_apt_location
The APT repo URL for the Kubernetes packages.
Defaults to https://apt.kubernetes.io
.
kubernetes_apt_release
The release name for the APT repo for the Kubernetes packages.
Defaults to 'kubernetes-${::lsbdistcodename}'
.
kubernetes_apt_repos
The repos to install using the Kubernetes APT URL.
Defaults to main
.
kubernetes_key_id
The gpg key for the Kubernetes APT repo.
Defaults to '54A647F9048D5688D7DA2ABE6A030B21BA07F4FB'
.
kubernetes_key_source
The URL for the APT repo gpg key.
Defaults to https://packages.cloud.google.com/apt/doc/apt-key.gpg
.
kubernetes_yum_baseurl
The YUM repo URL for the Kubernetes packages.
Defaults to https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
.
kubernetes_yum_gpgkey
The URL for the Kubernetes yum repo gpg key.
Defaults to https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
.
manage_docker
Specifies whether to install Docker repositories and packages via this module.
Valid values are true
, false
.
Defaults to true
.
manage_etcd
Specifies whether to install an external Etcd via this module.
Valid values are true
, false
.
Defaults to true
.
node_label
An override to the label of a node.
Defaults to hostname
.
runc_source
The download URL for runc
.
Defaults to https://github.com/opencontainers/runc/releases/download/v${runc_version}/runc.amd64
.
runc_version
Specifies the version of runc
to install.
Defaults to 1.0.0-rc5
.
sa_key
The key for the service account. This value must be a certificate value and not a file.
Defaults to undef
.
sa_pub
The public key for the service account. This value must be a certificate value and not a file.
Defaults to undef
.
schedule_on_controller
Specifies whether to remove the master role and allow pod scheduling on controllers.
Valid values are true
, false
.
Defaults to false
.
service_cidr
The IP address range for service VIPs.
Defaults to 10.96.0.0/12
.
token
The string used to join nodes to the cluster. This value must be in the form of [a-z0-9]{6}.[a-z0-9]{16}
.
Defaults to undef
.
worker
Specifies whether to set the node as a Kubernetes worker.
Valid values are true
, false
.
Defaults to false
.
Limitations
This module supports:
- Puppet 4 or higher.
- Kubernetes 1.10.x or higher.
- Ruby 2.3.0 or higher.
This module has been tested on the following operating systems:
- RedHat 7.x.
- CentOS 7.x.
- Ubuntu 16.04
Docker is the supported container runtime for this module.
Development
If you would like to contribute to this module, please follow the rules in the CONTRIBUTING.md.
Version 3.2.2
Fixes bug where nodes in v1.10/11 could not join the cluster
A full list of PR's and issues closed can be found here here
Version 3.2.1
Fixes world readable PKI keys in /etc/kubernetes/config.yaml
Allows changing etcd cluster state with new param
A full list of PR's and issues closed can be found here here
Version 3.2.0
Includes support for 1.13.x with the alpha3 config files
Uses config file for join tasks
Versions Dashboard
Enables kubelet service on RHEL/Centos
Removes params.pp in favor of data in init.pp
A full list of PR's and issues closed can be found here here
Version 3.1.0
Adds support for Kubernetes 1.12.x
A full list of PR's and issues closed can be found here here
https://github.com/puppetlabs/puppetlabs-kubernetes/milestone/3?closed=1
Version 3.0.1
Fixes an incorrect default value for ignore_preflight_errors in the cluster_roles class
Version 3.0.0
Exposes a significant number of new params to allow the use of internal repos in restricted or airgapped systems.
A full list of PRs and issues closed can be found here
Version 2.0.2
Fixes issue with cgroup mismatch on docker PR #109
ignores docker warning ine prelifght checks when using containerd PR #109
Version 2.0.1
Changes default runtime to docker
Version 2.0.0
Architectural change to use kubeadm project to bootstrap kubernetes clusters.
Updates to kubetool and params to reflect this change. See the README.md in this repo and consult the official kubeadm documenation here
Version 1.1.0
Add parameters for networking
Minor bug fixes
Full list of PR's available at here
Version 1.0.3
Change exec path for controller PR #57
Fix gpg key for docker apt repo PR #58
Fix in kubetool for weave cni provider URL PR #63
Version 1.0.2
Hotfix for kubelet downgrading cni in the rhel family
Version 1.0.1
Support for weave and flannel
EPEL module removed as dependency
Added $apiserver_extra_arguments
PR #47
Added support for PDK
Added support for stdlib 4.24.0
Updated kubetool to include CNI information in hiera (see README)
Version 1.0.0
Officially supported version of puppetlabs-kubernetes
Version 0.2.0
Supports Kubernetes up to 1.9.x
Adds support for cri-containerd runtime
Provides additional os and runtime switches for Kubetool
Version 0.1.3
Provide cli switches for kubetool, and add Dockerfile
Version 0.1.2
Supports Kubernetes up to 1.8.x
Version 0.1.1
Hotfix for kubeproxy
Version 0.1.0
First release
Supports Kubernetes 1.6 - 1.7.5
Dependencies
- puppetlabs-stdlib (>= 4.20.0 < 5.0.0)
- puppetlabs-apt (>= 4.1.0 < 6.0.0)
- puppet-archive (>= 2.0.0 < 3.1.0)
- puppetlabs-translate (>= 0.0.1 < 1.1.0)
- herculesteam-augeasproviders_sysctl (>= 2.2.1 < 3.0.0)
- herculesteam-augeasproviders_core (>= 2.1.0 < 3.0.0)
- camptocamp-kmod (>= 2.2.0 < 3.0.0)
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2016 Puppet Labs 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.