# Ansible Configuration Overview

The following is an overview of configurations (i.e., Ansible playbooks) applied to Enterprise 2025 infrastructure.

In terraform/range/, please run make create-vpn-profiles to generate OpenVPN profiles. These are stored as .zip files in terraform/range/publish/. Please use these to connect to your range and run host-based configurations.


# Table of Contents

  • Roles
  • Playbooks
  • Reusable Tasks

# Roles

# authentik

Task Name Module Variables
Create directories builtin/unknown shortname, dc, domain_name, tld, post_deploy
Create Authentik docker-compose.yml builtin/unknown shortname, dc, domain_name, tld, post_deploy
Move authentik cert builtin/unknown shortname, dc, domain_name, tld, post_deploy
Move authentik key builtin/unknown shortname, dc, domain_name, tld, post_deploy
Start Authentik community.docker.docker_compose_v2 shortname, dc, domain_name, tld, post_deploy
Wait for Authentik to be ready ansible.builtin.uri shortname, dc, domain_name, tld, post_deploy
debug builtin/unknown shortname, dc, domain_name, tld, post_deploy
Configure LDAP source ansible.builtin.include_tasks shortname, dc, domain_name, tld, post_deploy
query built-in brand ansible.builtin.uri shortname, dc, domain_name, tld, post_deploy
change default brand ansible.builtin.uri shortname, dc, domain_name, tld, post_deploy
query certificates ansible.builtin.uri shortname, dc, domain_name, tld, post_deploy
create brand ansible.builtin.uri shortname, dc, domain_name, tld, post_deploy
query brands ansible.builtin.uri shortname, dc, domain_name, tld, post_deploy
update brand to default ansible.builtin.uri shortname, dc, domain_name, tld, post_deploy
Finalize AWS authentication ansible.builtin.include_tasks shortname, dc, domain_name, tld, post_deploy
Configure AWS authentication ansible.builtin.include_tasks shortname, dc, domain_name, tld, post_deploy

# awscli

Task Name Module Variables
Install awscli windows builtin/unknown
Install awscli linux builtin/unknown

# certs

Task Name Module Variables
Create CA directory ansible.builtin.file cfssl_base_dir, certs_folder, ca_common_name, ca_country_name, ca_locality_name, ca_organization_name, ca_state_or_province_name, ca_cert_name, cert_domains, ca_domain, ca_crl_url, crl_enabled, crl_dir, crl_filename, crl_days, crl_nginx_port, crl_nginx_server_name
Create cfssl config directory ansible.builtin.file cfssl_base_dir, certs_folder, ca_common_name, ca_country_name, ca_locality_name, ca_organization_name, ca_state_or_province_name, ca_cert_name, cert_domains, ca_domain, ca_crl_url, crl_enabled, crl_dir, crl_filename, crl_days, crl_nginx_port, crl_nginx_server_name
Template CA configuration ansible.builtin.template cfssl_base_dir, certs_folder, ca_common_name, ca_country_name, ca_locality_name, ca_organization_name, ca_state_or_province_name, ca_cert_name, cert_domains, ca_domain, ca_crl_url, crl_enabled, crl_dir, crl_filename, crl_days, crl_nginx_port, crl_nginx_server_name
Template CA CSR configuration ansible.builtin.template cfssl_base_dir, certs_folder, ca_common_name, ca_country_name, ca_locality_name, ca_organization_name, ca_state_or_province_name, ca_cert_name, cert_domains, ca_domain, ca_crl_url, crl_enabled, crl_dir, crl_filename, crl_days, crl_nginx_port, crl_nginx_server_name
Generate CA certificate ansible.builtin.shell cfssl_base_dir, certs_folder, ca_common_name, ca_country_name, ca_locality_name, ca_organization_name, ca_state_or_province_name, ca_cert_name, cert_domains, ca_domain, ca_crl_url, crl_enabled, crl_dir, crl_filename, crl_days, crl_nginx_port, crl_nginx_server_name
Create site directories builtin/unknown cfssl_base_dir, certs_folder, ca_common_name, ca_country_name, ca_locality_name, ca_organization_name, ca_state_or_province_name, ca_cert_name, cert_domains, ca_domain, ca_crl_url, crl_enabled, crl_dir, crl_filename, crl_days, crl_nginx_port, crl_nginx_server_name
Template server CSR configurations ansible.builtin.template cfssl_base_dir, certs_folder, ca_common_name, ca_country_name, ca_locality_name, ca_organization_name, ca_state_or_province_name, ca_cert_name, cert_domains, ca_domain, ca_crl_url, crl_enabled, crl_dir, crl_filename, crl_days, crl_nginx_port, crl_nginx_server_name
Generate server certificates ansible.builtin.shell cfssl_base_dir, certs_folder, ca_common_name, ca_country_name, ca_locality_name, ca_organization_name, ca_state_or_province_name, ca_cert_name, cert_domains, ca_domain, ca_crl_url, crl_enabled, crl_dir, crl_filename, crl_days, crl_nginx_port, crl_nginx_server_name

# certs_crl

Task Name Module Variables
No tasks

# certs_sync

Task Name Module Variables
Create certs dir ansible.builtin.file
Pull from AWS ansible.builtin.command
Push to AWS (complete two way sync) ansible.builtin.command

# evals_ad_domain

Task Name Module Variables
CREATE Windows Domain {{ ERROR }} microsoft.ad.domain domain_info, domain_users, domain_groups, range_dns_server_ip
Delay-start WinRM after system has booted and works reliably ansible.windows.win_service domain_info, domain_users, domain_groups, range_dns_server_ip
Configure AD Server DNS ansible.windows.win_dns_client domain_info, domain_users, domain_groups, range_dns_server_ip
set dns forwarder to use range dns ansible.windows.win_shell domain_info, domain_users, domain_groups, range_dns_server_ip
CREATE groups for scenario microsoft.ad.group domain_info, domain_users, domain_groups, range_dns_server_ip
CREATE Domain Users microsoft.ad.user domain_info, domain_users, domain_groups, range_dns_server_ip
Debug user creation ansible.builtin.debug domain_info, domain_users, domain_groups, range_dns_server_ip
Create domain dns records community.windows.win_dns_record domain_info, domain_users, domain_groups, range_dns_server_ip
Enable network sharing builtin/unknown domain_info, domain_users, domain_groups, range_dns_server_ip

# evals_exchange

Task Name Module Variables
Check if Exchange is installed builtin/unknown ludus_install_directory, exchange_dotnet_install_path, vcredist2013_install_path, rewrite_module_path, ucma_runtime_path, ludus_exchange_iso_directory, ludus_exchange_iso_url, ludus_exchange2016_iso_url, ludus_exchange_domain, ludus_exchange_dc, ludus_exchange_host, ludus_exchange_domain_username, ludus_exchange_domain_password, ludus_os_version, exchange_prereqs_complete_file, send_connector_name, send_connector_smtpserver, send_connector_address_spaces, send_connector_source_transport_servers, s3_bucket, s3_filename
Download Exchange ISO for Windows Server 2016 ansible.builtin.include_tasks ludus_install_directory, exchange_dotnet_install_path, vcredist2013_install_path, rewrite_module_path, ucma_runtime_path, ludus_exchange_iso_directory, ludus_exchange_iso_url, ludus_exchange2016_iso_url, ludus_exchange_domain, ludus_exchange_dc, ludus_exchange_host, ludus_exchange_domain_username, ludus_exchange_domain_password, ludus_os_version, exchange_prereqs_complete_file, send_connector_name, send_connector_smtpserver, send_connector_address_spaces, send_connector_source_transport_servers, s3_bucket, s3_filename
Download Exchange ISO for Windows Server 2019 ansible.builtin.include_tasks ludus_install_directory, exchange_dotnet_install_path, vcredist2013_install_path, rewrite_module_path, ucma_runtime_path, ludus_exchange_iso_directory, ludus_exchange_iso_url, ludus_exchange2016_iso_url, ludus_exchange_domain, ludus_exchange_dc, ludus_exchange_host, ludus_exchange_domain_username, ludus_exchange_domain_password, ludus_os_version, exchange_prereqs_complete_file, send_connector_name, send_connector_smtpserver, send_connector_address_spaces, send_connector_source_transport_servers, s3_bucket, s3_filename
Ludus Exchange Server features to be installed ansible.builtin.include_tasks ludus_install_directory, exchange_dotnet_install_path, vcredist2013_install_path, rewrite_module_path, ucma_runtime_path, ludus_exchange_iso_directory, ludus_exchange_iso_url, ludus_exchange2016_iso_url, ludus_exchange_domain, ludus_exchange_dc, ludus_exchange_host, ludus_exchange_domain_username, ludus_exchange_domain_password, ludus_os_version, exchange_prereqs_complete_file, send_connector_name, send_connector_smtpserver, send_connector_address_spaces, send_connector_source_transport_servers, s3_bucket, s3_filename
Install Exchange Server for Windows Server 2016 ansible.builtin.include_tasks ludus_install_directory, exchange_dotnet_install_path, vcredist2013_install_path, rewrite_module_path, ucma_runtime_path, ludus_exchange_iso_directory, ludus_exchange_iso_url, ludus_exchange2016_iso_url, ludus_exchange_domain, ludus_exchange_dc, ludus_exchange_host, ludus_exchange_domain_username, ludus_exchange_domain_password, ludus_os_version, exchange_prereqs_complete_file, send_connector_name, send_connector_smtpserver, send_connector_address_spaces, send_connector_source_transport_servers, s3_bucket, s3_filename
Install Exchange Server for Windows Server 2016 ansible.builtin.include_tasks ludus_install_directory, exchange_dotnet_install_path, vcredist2013_install_path, rewrite_module_path, ucma_runtime_path, ludus_exchange_iso_directory, ludus_exchange_iso_url, ludus_exchange2016_iso_url, ludus_exchange_domain, ludus_exchange_dc, ludus_exchange_host, ludus_exchange_domain_username, ludus_exchange_domain_password, ludus_os_version, exchange_prereqs_complete_file, send_connector_name, send_connector_smtpserver, send_connector_address_spaces, send_connector_source_transport_servers, s3_bucket, s3_filename
Install Exchange Server for Windows Server 2019 ansible.builtin.include_tasks ludus_install_directory, exchange_dotnet_install_path, vcredist2013_install_path, rewrite_module_path, ucma_runtime_path, ludus_exchange_iso_directory, ludus_exchange_iso_url, ludus_exchange2016_iso_url, ludus_exchange_domain, ludus_exchange_dc, ludus_exchange_host, ludus_exchange_domain_username, ludus_exchange_domain_password, ludus_os_version, exchange_prereqs_complete_file, send_connector_name, send_connector_smtpserver, send_connector_address_spaces, send_connector_source_transport_servers, s3_bucket, s3_filename
Run the send connector task ansible.builtin.include_tasks ludus_install_directory, exchange_dotnet_install_path, vcredist2013_install_path, rewrite_module_path, ucma_runtime_path, ludus_exchange_iso_directory, ludus_exchange_iso_url, ludus_exchange2016_iso_url, ludus_exchange_domain, ludus_exchange_dc, ludus_exchange_host, ludus_exchange_domain_username, ludus_exchange_domain_password, ludus_os_version, exchange_prereqs_complete_file, send_connector_name, send_connector_smtpserver, send_connector_address_spaces, send_connector_source_transport_servers, s3_bucket, s3_filename

# ftp_setup

Task Name Module Variables
Create FTP users ansible.builtin.user ftp_srv_dir, ftp_user, ftp_users, ftp_passive_min_port, ftp_passive_max_port, use_ftp_redirector, ftp_redirector_ip
Configure VSFTPD ansible.builtin.template ftp_srv_dir, ftp_user, ftp_users, ftp_passive_min_port, ftp_passive_max_port, use_ftp_redirector, ftp_redirector_ip
Create FTP directories ansible.builtin.file ftp_srv_dir, ftp_user, ftp_users, ftp_passive_min_port, ftp_passive_max_port, use_ftp_redirector, ftp_redirector_ip
Enable and Restart VSFTP service ansible.builtin.systemd ftp_srv_dir, ftp_user, ftp_users, ftp_passive_min_port, ftp_passive_max_port, use_ftp_redirector, ftp_redirector_ip

# gitlab-authentik

Task Name Module Variables
query authentik authorization flow UUID ansible.builtin.uri app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
set auth flow uuid builtin/unknown app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
query authentik authentication flow UUID ansible.builtin.uri app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
set authentication flow uuid builtin/unknown app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
query authentik invalidation flow UUID ansible.builtin.uri app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
set invalidation flow uuid builtin/unknown app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
Create OIDC Provider for GitLab ansible.builtin.uri app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
query oidc provider ansible.builtin.uri app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
query scope mappings ansible.builtin.uri app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
query certificates ansible.builtin.uri app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
Update GitLab Provider in Authentik ansible.builtin.uri app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
Create GitLab Application in Authentik ansible.builtin.uri app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
set secret builtin/unknown app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
set oidc template content builtin/unknown app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file
render the template and append to the gitlab rb config file ansible.builtin.blockinfile app_name, app_slug, domain_info, domain_name, authentik_admin_token, authentik_port, authentik_domain, gitlab_domain, gitlab_port, oidc_client_id, gitlab_authentik_label_text, gitlab_config_file

# guacamole

Task Name Module Variables
query authentik authorization flow UUID ansible.builtin.uri
set auth flow uuid builtin/unknown
query authentik authentication flow UUID ansible.builtin.uri
set authentication flow uuid builtin/unknown
query authentik invalidation flow UUID ansible.builtin.uri
set invalidation flow uuid builtin/unknown
Create OIDC Provider for Guacamole ansible.builtin.uri
query oidc provider ansible.builtin.uri
query scope mappings ansible.builtin.uri
query certificates ansible.builtin.uri
Update Guacamole Provider in Authentik ansible.builtin.uri
Create Guacamole Application in Authentik ansible.builtin.uri
set secret builtin/unknown
Create Guacamole directories builtin/unknown
Create Guacamole docker-compose.yml builtin/unknown
Upload prepare script ansible.builtin.copy
Run prepare script ansible.builtin.shell
Create nginx template builtin/unknown
Move guac key ansible.builtin.copy
Move guac certs builtin/unknown
Move root cert builtin/unknown
Start Guacamole community.docker.docker_compose_v2
Add trusted ca cert to guac community.docker.docker_container_exec

# s3_user_key_management

Task Name Module Variables
Build vendor loop list builtin/unknown
Include create_user_output for each defined vendor from Terraform builtin/unknown
Check if key staging directory exists ansible.builtin.stat
Remove key staging directory ansible.builtin.file

# s3file_staging

Task Name Module Variables
Stage S3 directories from source to destination in bulk builtin/unknown source_bucket, source_path_prefix, source_path_suffix, dest_cloud_bucket, CrossAccountAccess_arn, Cloud_Protections_arn, cloud_detections_arn, target_account, source_cloud_directories, protections_cloud_files

# ssm_hybrid_activation

Task Name Module Variables
Perform SSM hybrid activation builtin/unknown ssm_activation_code, ssm_activation_id, ssm_region, ssm_agent_download_url

# windows_remote_desktop_session_host

Task Name Module Variables
Install RDS Session Host role ansible.windows.win_feature licensing_server_ad_group
Install RDS Licensing Server role ansible.windows.win_feature licensing_server_ad_group
Reboot if required ansible.windows.win_reboot licensing_server_ad_group
Set RDS licensing mode (Per User) builtin/unknown licensing_server_ad_group

# Playbooks

# Reusable Tasks

# add-local-admin-groups.yml

Required Variables: domain_shortname:, admin_group:

Task Name Module
Add domain admins to local admin ansible.windows.win_group_membership

# configure-addc-gpo.yml

Required Variables: deploy_dir:, gpo_src_dir:, gpo_dst_dir:, evals_range:, domain_shortname:, domain_tld:

Task Name Module
Create directory for gpo files: ansible.windows.win_file
Copy gpo folder to DC: ansible.windows.win_copy
install nuget provider ansible.windows.win_shell
Install GPOTools module builtin/unknown
Restore GPO policies in: builtin/unknown
Link GPO policies builtin/unknown
Cleanup ansible.windows.win_file

# configure-and-join-domain-linux.yml

Required Variables: linux_hostname:, domain_admin_user:, domain_admin_pass:, domain_dns_name:, tuned_profile:

Task Name Module
Install packages required for AD and some useful tools ansible.builtin.apt
restart sssd builtin/unknown
disable ufw builtin/unknown
Forcibly remove resolv.conf ansible.builtin.shell
disable systemd resolved builtin/unknown
Copy resolv dns configuration builtin/unknown
Set hostname ansible.builtin.hostname
Preserve hostname after reboot builtin/unknown
Disable Kerberos reverse dns during domain join ansible.builtin.copy
Join the AD domain ansible.builtin.shell
See the Results from Joining builtin/unknown
Check the AD join result builtin/unknown
Validate the AD join ansible.builtin.command
Check the validation result builtin/unknown
install sudo configuration ansible.builtin.copy
allow password auth for domain users over ssh ansible.builtin.copy
Enable home dir creation on first login ansible.builtin.shell
See the result from configuring mkhomedir builtin/unknown
Permit domain logins ansible.builtin.shell
Allow user Login without FQDN builtin/unknown
add gpo disable login configuration to sssd config builtin/unknown
check tuned profile ansible.builtin.shell
set tuned profile ansible.builtin.shell
reboot host ansible.builtin.reboot

# configure-and-join-domain-win-all.yml

Required Variables: ad_ip_addr:, domain_dns_name:, domain_shortname:, domain_admin_user:, domain_admin_pass:

Task Name Module
Configure DNS to use AD Server ansible.windows.win_dns_client
Join AD Domain microsoft.ad.membership
Add domain admins to local admin ansible.windows.win_group_membership
Add admins and users to RDP group ansible.windows.win_group_membership
Enable network sharing builtin/unknown

# configure-choco-mirror.yml

Required Variables: support_vars.choco_mirror_url:

Task Name Module
Install chocolatey chocolatey.chocolatey.win_chocolatey
Remove the default public source chocolatey.chocolatey.win_chocolatey_source
Add new internal source chocolatey.chocolatey.win_chocolatey_source

# configure-fleet-activity-exporter.yml

Required Variables: scripts_dir:, log_dir:

Task Name Module
Create scripts directory ansible.builtin.file
Create log directory ansible.builtin.file
Copy Fleet activity exporter script ansible.builtin.copy
Copy systemd service file ansible.builtin.copy
Copy systemd timer file ansible.builtin.copy
Reload systemd daemon ansible.builtin.systemd
Enable and start Fleet activity exporter timer ansible.builtin.systemd
Test the exporter (run once manually) ansible.builtin.command
Display test results ansible.builtin.debug
Configure logrotate for Fleet activity logs ansible.builtin.copy

# csv-to-s3.yml

Required Variables: item.username:, item.password:, red_dev.s3.red_bucket:, evals_cycle:

Task Name Module
Populate j2 template csv for s3 (github) builtin/unknown
Upload csv to s3 amazon.aws.aws_s3

# firefox-win-client-setup.yml

Required Variables: None

Task Name Module
install firefox builtin/unknown
Disable automatic firefox updates ansible.windows.win_regedit
Disable firefox default browser check ansible.windows.win_regedit
Disable firefox first run ansible.windows.win_regedit

# fix-domain-user-name-display.yml

Required Variables: domain_users:, domain_info.dns_domain_name:

Task Name Module
Update Domain Users to display first and last name microsoft.ad.user

# fix-rdp.yml

Required Variables: ad_domain:, ad_user:, ad_pass:

Task Name Module
Repairing Domain Trust to ansible.builtin.win_shell
Delete PSCrendential Automations ansible.builtin.win_shell

# fix-win-expired-logins.yml

Required Variables: None

Task Name Module
Ensure devadmin does not expire ansible.windows.win_user

# kali-firefox-trust-ca.yml

Required Variables: cert_name:, cert_path:, ca_cert_name:

Task Name Module
create firefox policy directory ansible.builtin.file
copy firefox policy file ansible.builtin.template
install libnss3-tools for certutil ansible.builtin.apt
add certificate to chrome nss database for all users ansible.builtin.shell

# kali-xfce-disable-screenlock.yml

Required Variables: None

Task Name Module
Get list of home directories ansible.builtin.find
Create XFCE config directories ansible.builtin.file
Configure power manager settings ansible.builtin.copy
Configure screensaver settings ansible.builtin.copy

# prepop-profile-directories.yml

Required Variables: prepop_domain_users:, office_dest_prefix:, office_cfg_dest_dir:, office_cfg_src_file:, office_cfg_filename:

Task Name Module
Create profile directories if they do not exist community.windows.win_user_profile
Create directory for office profile dir ansible.windows.win_file
Upload office configuration to profile ansible.windows.win_copy

# redirect-setup.yml

Required Variables: None

Task Name Module
Copy resolv dns configuration builtin/unknown
Install redirector deps and useful tools ansible.builtin.apt
Get primary interface MAC ansible.builtin.shell
Get primary interface IPs ansible.builtin.shell
Get all interface MACs ansible.builtin.shell
Initialize local IPs list ansible.builtin.set_fact
Add primary IPs to local IPs list ansible.builtin.set_fact
Process secondary interfaces for local IPs builtin/unknown
Configure redirect script for host builtin/unknown
Copy disable script builtin/unknown
Copy print script builtin/unknown
Copy sysctl conf builtin/unknown
Apply sysctl conf ansible.builtin.shell
Configure netplan for additional IPs builtin/unknown
Apply netplan rules ansible.builtin.shell
Flush iptables rules ansible.builtin.command
Process forwarding rules ansible.builtin.command
Save and persist forwarding rules ansible.builtin.shell
reboot hosts ansible.builtin.reboot

# run-windows-reg-file.yml

Required Variables: winrar_dest_dir:, winrar_reg_file:, winrar_dest_file:

Task Name Module
make sure dest dir exists ansible.windows.win_file
copy reg file to host ansible.windows.win_copy
run winrar reg file on windows host ansible.windows.win_shell
cleanup and remove reg file from host ansible.windows.win_file

# Notice

© 2025 MITRE. Approved for public release. Document number 25-2969.

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.