Version information
released Jun 27th 2017
This version is compatible with:
- ,
Start using this module
Add this module to your Puppetfile:
mod 'bibigon812-quagga', '2.0.3'
Learn more about managing modules with a PuppetfileDocumentation
bibigon812/quagga — version 2.0.3 Jun 27th 2017
Overview
This module provides management of network protocols without restarting services. All resources make changes to the configuration of services using commands, as if you are doing this through the CLI.
Currently it supports:
- BGP
- OSPF
- PIM
- Route maps
- Prefix lists
- Community lists
- AS-path lists
Usage
class { '::quagga':
as_paths => {
FROM_AS100 => {
rules => [
'permit _100$',
],
},
},
bgp => {
65000 => {
import_check => true,
ipv4_unicast => false,
maximum_paths_ebgp => 2,
maximum_paths_ibgp => 2,
networks => [
'1.1.1.0/24',
'1.1.2.0/24',
],
peers=> {
'192.168.0.2' => {
peer_group => 'INTERNAL',
},
'192.168.0.3' => {
peer_group => 'INTERNAL',
},
INTERNAL => {
activate => true,
next_hop_self => true,
peer_group => true,
remote_as => 65000,
update_source => '192.168.0.1',
},
},
redistribute => [
'ospf route-map BGP_FROM_OSPF',
],
router_id => '10.255.255.1',
},
},
community_lists => {
100 => {
rules => [
'permit 65000:101',
'permit 65000:102',
'permit 65000:103',
],
},
200 => {
rules => [
'permit 65000:201',
'permit 65000:202',
],
},
},
global => {
ip_forwarding => true,
ip_multicast_routing => true,
ipv6_forwarding => true,
service_password_encryption => true,
},
interfaces => {
lo => {
ip_address => [
'10.255.255.1/32',
'172.16.255.1/32',
],
},
eth0 => {
igmp => true,
ip_address => '172.16.0.1/24',
ospf_dead_interval => 8,
ospf_hello_interval => 2,
ospf_mtu_ignore => true,
pim_ssm => true,
},
},
ospf => {
areas => {
'0.0.0.0' => {
networks => [
'172.16.0.0/12',
],
}
},
redistribute => [
'connected route-map CONNECTED',
],
},
prefix_lists => {
CONNECTED_NETWORKS => {
rules => {
500 => {
action => 'permit',
le => 32,
prefix => '10.255.255.0/24',
},
},
},
OSPF_NETWORKS => {
rules => {
10 => {
action => 'permit',
prefix => '172.31.255.0/24',
},
},
},
},
route_maps => {
BGP_FROM_OSPF => {
rules => {
10 => {
action => 'permit',
match => 'ip address prefix-list OSPF_NETWORKS',
},
},
},
CONNECTED => {
rules => {
10 => {
action => 'permit',
match => 'ip address prefix-list CONNECTED_NETWORKS',
},
},
},
},
}
A full description of parameters can be found in the appropriate types.
- as_paths: quagga_as_path
- bgp: quagga_bgp
- bgp peers: quagga_bgp_peer
- community_lists: quagga_community_list
- global: quagga_global
- interfaces: quagga_interface
- ospf: quagga_ospf
- prefix_lists: quagga_prefix_list
- route_maps: quagga_route_map
Hiera
quagga::global:
ip_forwarding: true
ip_multicast_routing: true
ipv6_forwarding: true
service_password_encryption: true
quagga::interfaces:
lo:
ip_address:
- 10.255.255.1/32
- 172.16.255.1/32
eth0:
igmp: true
ip_address: 172.16.0.1/24
ospf_dead_interval: 8
ospf_hello_interval: 2
ospf_mtu_ignore: true
pim_ssm: true
quagga::bgp:
65000:
import_check: true
ipv4_unicast: false
maximum_paths_ebgp: 2
maximum_paths_ibgp: 10
networks:
- 1.1.1.0/24
- 1.1.2.0/24
router_id: 10.255.255.1
peers:
192.168.0.2:
peer_group: INTERNAL
192.168.0.3:
peer_group: INTERNAL
CLIENTS:
activate: true
default_originate: true
passive: true
peer_group: true
INTERNAL:
activate: true
next_hop_self: true
peer_group: true
remote_as: 65000
update_source: 192.168.0.1
redistribute:
- ospf route-map BGP_FROM_OSPF
quagga::ospf:
areas:
0.0.0.0:
networks:
- 172.16.0.0/12
default_originate: true
redistribute:
- connected route-map CONNECTED
router_id: 10.255.255.1
quagga::as_paths:
FROM_AS100:
rules:
- permit _100$
quagga::community_lists:
100:
rules:
- permit 65000:101
- permit 65000:102
- permit 65000:103
200:
rules:
- permit 65000:201
- permit 65000:202
quagga::prefix_lists:
CONNECTED_NETWORKS:
rules:
500:
action: permit
le: 32
prefix: 10.255.255.0/24
OSPF_NETWORKS:
rules:
10:
action: permit
prefix: 172.31.255.0/24
quagga::route_maps:
BGP_FROM_OSPF:
rules:
10:
action: permit
match: ip address prefix-list OSPF_NETWORKS
CONNECTED:
rules:
10:
action: permit
match: ip address prefix-list CONNECTED_NETWORKS
Reference
Classes
quagga
class { '::quagga': }
owner
. Overrides the default owner of quagga configuration files in the file system. Default value:quagga
.group
. Overrides the default group of quagga configuration files in the file system. Default value:quagga
.mode
. Overrides the default mode of quagga configuration files in the system. Default value:600
.package_name
. Overrides the default package name for the distribution you are installing to. Default value:quagga
.package_ensure
. Overrides the 'ensure' parameter during package installation. Default value:present
.content
. Overrides the initial content of quagga configuration files. Default value:hostname ${::fqdn}\n
.as_paths
. Contains as-path list settings. Default value:{}
.bgp
. Contains the setting of the bgp router. Default value:{}
.community_lists
: Contains community list settings. Default value:{}
.interfaces
: Contains network interface settings. Default value:{}
.global
: Contain global settings. Default value:{}
.ospf
. Contains the settings of the ospf router. Default value:{}
.prefix_lists
. Contains prefix list settings. Default value:{}
.route_maps
. Contains route-map settings. Default value:{}
.
Types
quagga_as_path
quagga_as_path { 'TEST_AS_PATH':
ensure => present,
rules => [
'permit _100$',
'permit _100_',
],
}
name
: The name of the as-path access-list.ensure
: Manage the state of this as-path list:absent
,present
. Default value:present
.rules
: Array of rulesaction regex
.
quagga_bgp
quagga_bgp { '65000':
ensure => present,
import_check => true,
ipv4_unicast => true,
maximum_paths_ebgp => 10,
maximum_paths_ibgp => 10,
networks => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16',],
router_id => '10.0.0.1',
}
name
: AS numberensure
: Manage the state of this BGP router:absent
,present
. Default value:present
.import_check
: Check BGP network route exists in IGP.ipv4_unicast
: Activate ipv4-unicast for a peer by default. Default value:true
.maximum_paths_ebgp
: Forward packets over multiple paths ebgp. Default value:1
.maximum_paths_ibgp
: Forward packets over multiple paths ibgp. Default value:1
.networks
: Specify a networks to announce via BGP. Default value:[]
.router_id
: Override configured router identifier.
quagga_bgp_peer
quagga_bgp_peer { '65000 internal':
ensure => present,
activate => true,
next_hop_self => true,
peer_group => true,
remote_as => 65000,
update_source => '10.0.0.1',
}
quagga_bgp_peer { '65000 10.0.0.2':
ensure => present,
peer_group => 'internal',
}
quagga_bgp_peer { '65000 10.0.0.3':
ensure => present,
peer_group => 'internal',
}
name
: It's consists of a AS number and a neighbor IP address or a peer-group name.ensure
: Manage the state of this BGP neighbor:absent
,present
. Default value:present
.activate
: Enable the Address Family for this Neighbor. Default value:true
.allow_as_in
: Accept as-path with my AS present in it.default_originate
: Originate default route to this neighbor. Default value:false
.local_as
: Specify a local-as number.next_hop_self
: Disable the next hop calculation for this neighbor. Default value:false
.passive
: Don't send open messages to this neighbor. Default value:false
.peer_group
: Member of the peer-group. Default value:false
.prefix_list_in
: Filter updates from this neighbor.prefix_list_out
: Filter updates to this neighbor.remote_as
: Specify a BGP neighbor as.route_map_export
: Apply map to routes coming from a Route-Server client.route_map_import
: Apply map to routes going into a Route-Server client's table.route_map_in
: Apply map to incoming routes.route_map_out
: Apply map to outbound routes.route_reflector_client
: Configure a neighbor as Route Reflector client. Default value:false
.route_server_client
: Configure a neighbor as Route Server client. Default value:false
.shutdown
: Administratively shut down this neighbor. Default value:false
.update_source
: Source of routing updates. It can be the interface name or IP address.
quagga_community_list
quagga_community_list { '100':
ensure => present,
rules => [
'permit 65000:50952',
'permit 65000:31500',
],
}
name
: Community list number.ensure
: Manage the state of this community list:absent
,present
. Default value:present
.rules
: Array of rulesaction community
.
quagga_global
quagga_global { 'router-1.sandbox.local':
password => 'password',
enable_password => 'enable_password',
ip_forwarding => true,
ipv6_forwarding => true,
ip_multicast_routing => true,
line_vty => true,
service_password_encryption => true,
}
name
: Router instance name.hostname
: Router hostname. Default value:name
.password
: Set password for vty interface. If there is no password, a vty won’t accept connections.enable_password
: Set enable password.ip_forwarding
: Enable IP forwarding. Default value:false
.ip_multicast_routing
: Enable IP multicast forwarding. Default value:false
.ipv6_forwarding
: Enable IPv6 forwarding. Default value:false
.line_vty
: Enter vty configuration mode. Default value:true
.service_password_encryption
: Encrypt passwords. Default value:false
.
quagga_interface
quagga_interface { 'eth0':
igmp => true,
ipaddress => [ '10.0.0.1/24', '172.16.0.1/24', ],
multicast => true,
ospf_mtu_ignore => true,
ospf_hello_interval => 2,
ospf_dead_interval => 8,
pim_ssm => true,
}
name
: The friendly name of the network interface.description
: Interface description.igmp
: Enable IGMP. Default value:false
.igmp_query_interval
: IGMP query interval. Default value:125
.igmp_query_max_response_time_dsec
: IGMP maximum query response time in deciseconds. Default value:100
.ipaddress
: IP addresses. Default value:[]
.multicast
: Enable multicast flag for the interface. Default value:false
.ospf_cost
: Interface cos. Default value:10
.ospf_dead_interval
: Interval after which a neighbor is declared dead. Default value:40
.ospf_hello_interval
: Time between HELLO packets. Default value:10
.ospf_mtu_ignore
: Disable mtu mismatch detection. Default value:false
.ospf_network
: Network type:broadcast
,non-broadcast
,point-to-multipoint
,point-to-point
orloopback
. Default value:broadcast
.ospf_priority
: Router priority. Default value:1
.ospf_retransmit_interval
: Time between retransmitting lost link state advertisements. Default value:5
.ospf_transmit_delay
: Link state transmit delay. Default value:1
.pim_ssm
: Enable PIM SSM operation. Default value:false
.
quagga_ospf
quagga_ospf { 'ospf':
ensure => present,
abr_type => 'cisco',
opaque => true,
rfc1583 => true,
router_id => '10.0.0.1',
}
name
: Name must beospf
.ensure
: Manage the state of this OSPF router:absent
,present
. Default value:present
.abr_type
: Set OSPF ABR type. Default value:cisco
.log_adjacency_changes
: Log changes in adjacency. Default value:false
.opaque
: Enable the Opaque-LSA capability (rfc2370). Default value:false
.rfc1583
: Enable the RFC1583Compatibility flag. Default value:false
.router_id
: Router-id for the OSPF process.
quagga_ospf_area
quagga_ospf_area { '0.0.0.0':
ensure => present,
network => [ '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16' ],
}
name
: OSPF area.ensure
: Manage the state of this OSPF area:absent
,present
. Default value:present
.access_list_expor
: Set the filter for networks announced to other areas.access_list_import
: Set the filter for networks from other areas announced to the specified one.prefix_list_export
: Filter networks sent from this area.prefix_list_import
: Filter networks sent to this area.networks
: Enable routing on an IP network. Default value:[]
.
quagga_prefix_list
The prefix_list resource is a single sequence. You can use a chain of resources to describe compex prefix lists, for example:
quagga_prefix_list {'ADVERTISED_PREFIXES:10':
ensure => present,
action => 'permit',
prefix => '192.168.0.0/16',
le => 24,
}
quagga_prefix_list {'ADVERTISED_PREFIXES:20':
ensure => present,
action => 'permit',
prefix => '172.16.0.0/12',
le => 24,
}
name
: Name of the prefix-list and sequence number of rule:name:sequence
.ensure
: Manage the state of this prefix list:absent
,present
. Default value:present
.action
: Action can bepermit
ordeny
.ge
: Minimum prefix length to be matched.le
: Maximum prefix length to be matched.prefix
: IP prefix<network>/<length>
.proto
: IP protocol version:ip
,ipv6
. Default value:ip
.
quagga_redistribution
quagga_redistribution { 'ospf::connected':
ensure => present,
metric => 100,
metric_type => 2,
route_map => 'CONNECTED',
}
quagga_redistribution { 'bgp:65000:ospf':
ensure => present,
metric => 100,
route_map => 'WORD',
}
name
: The name contains the main protocol, the id and the protocol for redistribution.ensure
: Manage the state of this redistribution:absent
,present
. Default value:present
.metric
: Metric for redistributed routes.metric_type
: OSPF exterior metric type for redistributed routes.route_map
: Route map reference.
quagga_route_map
The route_map resource is a single sequence. You can use a chain of resources to describe complex route maps, for example:
quagga_route_map { 'bgp_out:10':
ensure => present,
action => 'permit',
match => 'ip address prefix-list ADVERTISED-PREFIXES'
on_match => 'goto 65000',
}
quagga_route_map { 'bgp_out:99':
ensure => present,
action => 'deny',
}
quagga_route_map { 'bgp_out:65000':
ensure => present,
action => 'permit',
match => [
'as-path AS_PATH_LIST',
'community 100',
'community 300 exact-match',
'extcommunity 200',
'interface eth0',
'ip address 100',
'ip next-hop ACCESS_LIST',
'ip route-source prefix-list PREFIX_LIST',
'ipv6 address IPV6_ACCESS_LIST',
'ipv6 next-hop prefix-list IPV6_PREFIX_LIST',
'local-preference 1000',
'metric 0',
'origin igp',
'origin egp',
'origin incomplete',
'peer 1.1.1.1',
'peer 100',
'peer local',
'probability 50',
'tag 100',
],
on_match => 'next',
set => [
'aggregator as 65000',
'as-path exclude 100 200',
'as-path prepend 100 100 100',
'as-path prepend last-as 5',
'atomic-aggregate',
'comm-list 100 delete',
'community 0:666 additive',
'community none',
'forwarding address 1fff::',
'ip next-hop 1.1.1.1',
'ip next-hop peer-address',
'ipv6 next-hop global 1::',
'ipv6 next-hop local 1::',
'ipv6 next-hop peer-address',
'local-preference 1000',
'metric 0',
'metric-type type-1',
'origin egp',
'origin igp',
'origin incomplete',
'originator-id 1.1.1.1',
'src 1.1.1.1',
'tag 100',
'vpn4 next-hop 1.1.1.1',
'weight 100',
],
}
name
: Name of the route-map, action and sequence number of rule.action
: Route map actions:deny
,permit
.ensure
: Manage the state of this route map:absent
,present
. Default value:present
.match
: Match values from routing table. Default value:[]
.on_match
: Exit policy on matches.set
: Set values in destination routing protocol. Default value:[]
.
Types in this module release
[2.0.3] - 2017-06-27
Added
- tests
Fixed
- a name validation of the type
quagga_bgp_peer
Updated
- docs
- changelog
[2.0.2] - 2017-06-26
Fixed
- creating the resource
quagga_bgp_peer
Updated
- the provider of the type
quagga_bgp_peer
[2.0.1] - 2017-06-26
Fixed
- the router_id default value of the type
quagga_bgp
[2.0.0] - 2017-06-26
Added
- multicast-routing by @m4ce
- the resource
quagga_router
by @m4ce - the property
networks
to the resourcequagga_bgp
- tests
quagga_ip
properties to the resourcequagga_system
- the property
action
to the resourcequagga_route_map
- wrappers for resources
- hiera support
- the property
redistribute
to the resourcequagga_ospf
- the property
redistribute
to the resourcequagga_bgp
- the property
default_originate
to the resourcequagga_ospf
Changed
- boolean values of variables to
true
orfalse
in resourcebgp*
,ospf*
- types
ospf_interface
andpim_interface
toquagga_interface
- the type
as_path
toquagga_as_path
- a syntax of
quagga_as_path
rules - the type
bgp
toquagga_bgp
- the type
bgp_neighbor
toquagga_bgp_peer
- the type
bgp_network
toquagga_bgp_network
- the type
quagga_router
toquagga_system
- the type
community_list
toquagga_community_list
- a syntax of
quagga_community_list
rules - the type
ospf_area
toquagga_ospf_area
- the type
prefix_list
toquagga_prefix_list
- the type
redistribution
toquagga_redistribution
- the type
route_map
toquagga_route_map
- the name of the resource
quagga_route_map
- the property
ipaddress
toip_address
of the resourcequagga_interface
Deprecated
- the type
quagga_redistribution
Removed
- the method
purge
from resourcesbgp*
- the resource
quagga_bgp_network
- properties
default_cost
andstub
fromquagga_ospf_area
- the resource
quagga_ip
Updated
- changelog
- docs
[1.2.1] - 2017-06-07
Added
- pim support by @m4ce
Fixed
- the ipv6 support of the resource
bgp_network
[1.1.4] - 2017-06-05
Added
- the property
update_source
to the resourcebgp_neighbor
Updated
- docs
[1.1.3] - 2017-06-01
Fixed
- creation of the resource
ospf
Removed
- the property
reference_bandwidth
from the provider
Updated
- the method
flush
of the resourceospf
[1.1.2] - 2017-06-01
Fixed
- removing of
bgp
andbgp_neighbor
resources - the
flush
method in theospf
resource
Removed
- an unused code
Updated
- changelog
- proxy classes
[1.1.1] - 2017-05-31
Fixed
- NilClass in flush methods
- errors on creating all resources
Updated
- docs
- the ensurable method in types
- changelog
[1.1.0] - 2017-05-31
Fixed
- reading the activate property of the bgp_neighbor resource
Removed
- the shortcut property of the ospf_area type
Updated
- docs
- changelog
[1.0.5] - 2017-05-30
Added
- a default value of the activate property of the bgp_neighbor resource
Fixed
- an instantiation of the bgp_neighbor resource
- removing the allow_as_in property of the bgp_neighbor resource
Updated
- changelog
[1.0.4] - 2017-05-30
Fixed
- an instantiation of the ospf resource
Removed
- a default value of the activate property of the bgp_neighbor resource
[1.0.3] - 2017-05-30
Fixed
- typos
- autorequires in bgp_netighbor and bgp_network resources
Updated
- docs
- changelog
[1.0.2] - 2017-05-30
Added
- proxy classes to use hiera
Updated
- changelog
- docs
Fixed
- a control of services
[1.0.1] - 2017-05-29
Changed
- values of the stub property
Updated
- changelog
- docs
[1.0.0] - 2017-05-29
Added
- the ospf_interface type
- the quagga provider of the ospf_interface type
- the ospf type
- the quagga provider of the ospf type
- the ospf_area type and a provider for it
- the redistribution type and a provider for it
- the as_path type and a provider for it
- the community_list type and a provider for it
- the prefix_list type and a provider for it
- the route_map type and a provider for it
- the bgp type and a provider for it
- the bgp_neighbor type and a provider for it
- the bgp_network type and a provider for it
Updated
- changelog
- docs
Dependencies
- puppetlabs-stdlib (>=3.2.0 <5.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 {yyyy} {name of copyright owner} 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.