##############################################################################
# Copyright (c) 2016 Ericsson AB and others.
# peter.barabas@ericsson.com
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################

======== TEMPLATING SUPPORT IN YAML CONFIGURATION FILES ========

deploy/templater.py makes it possible to use templates to generate configuration
files. It takes 2 input YAML files and an output file as arguments. One being
the dictionary (called the base file), which is used to look up values in; the
other file is the template, where the substitution will take place. Templater
will write the result to an output file, specified as the 3rd argument.


======== SYNTAX OF TEMPLATE FILES ========

A template file can contain any valid YAML data and template variables, whose
syntax is described below:

1. Single value references

   %{title}

   %{environment/net_segment_type}

   Either a root element, or a path can be specified.

2. YAML sections

   %{nodes}

   %{network/networking_parameters}

   Either a root element, or a path can be specified.

3. Interface lookup for network

   %{interface(storage)}

   Specify a network type as argument to interface().

4. Interface lookup for network and role

   %{interface(public,compute)}

   Specify a network type and a role as arguments to interface().

5. File inclusion

   %{include(templates/interfaces.yaml)}

   Filename with absolute or relative path.


======== EXAMPLES ========

Base YAML file (excerpt):

title: Deployment Environment Adapter (DEA)
version: 1.1
created: Wed Mar 30 08:16:04 2016
environment:
  name: vCity
  net_segment_type: tun
wanted_release: Liberty on Ubuntu 14.04
nodes:
- id: 1
  interfaces: interfaces_1
  role: ceph-osd,compute
  transformations: transformations_1
- id: 2
  interfaces: interfaces_1
  role: ceph-osd,compute
  transformations: transformations_1
- id: 3
  interfaces: interfaces_1
  role: ceph-osd,compute
  transformations: transformations_1
- id: 4
  interfaces: interfaces_2
  role: controller,mongo
  transformations: transformations_2
- id: 5
  interfaces: interfaces_2
  role: controller,mongo
  transformations: transformations_2
- id: 6
  interfaces: interfaces_2
  role: controller,mongo
  transformations: transformations_2
interfaces_1:
  ens3:
  - fuelweb_admin
  - management
  ens4:
  - storage
  ens5:
  - private
  ens6:
  - public
interfaces_2:
  ens3:
  - fuelweb_admin
  - management
  ens4:
  - storage
  - private
  - public
network:
  networks:
  - cidr: 172.16.0.0/24
    gateway: 172.16.0.1
    ip_ranges:
    - - 172.16.0.2
      - 172.16.0.126
    meta:
      cidr: 172.16.0.0/24
      configurable: true
      floating_range_var: floating_ranges
      ip_range:
      - 172.16.0.2
      - 172.16.0.126
      map_priority: 1
      name: public
      notation: ip_ranges
      render_addr_mask: public
      render_type: null
      use_gateway: true
      vips:
      - haproxy
      - vrouter
      vlan_start: null
    name: public
    vlan_start: null
  - cidr: 192.168.1.0/24
    gateway: null
    ip_ranges:
    - - 192.168.1.1
      - 192.168.1.254
    meta:
      cidr: 192.168.1.0/24
      configurable: true
      map_priority: 2
      name: storage
      notation: cidr
      render_addr_mask: storage
      render_type: cidr
      use_gateway: false
      vlan_start: 102
    name: storage
    vlan_start: 102


--- Example 1 ---

Template file:

deployment-scenario-metadata:
  title: %{title}
  version: 0.1
dea-override-config:
  environment:
    net_segment_type: %{environment/net_segment_type}
  nodes:
  %{nodes}


Result:

deployment-scenario-metadata:
  title: Deployment Environment Adapter (DEA)
  version: 0.1
dea-override-config:
  environment:
    net_segment_type: tun
  nodes:
  - id: 1
    interfaces: interfaces_1
    role: ceph-osd,compute
    transformations: transformations_1
  - id: 2
    interfaces: interfaces_1
    role: ceph-osd,compute
    transformations: transformations_1
  - id: 3
    interfaces: interfaces_1
    role: ceph-osd,compute
    transformations: transformations_1
  - id: 4
    interfaces: interfaces_2
    role: controller,mongo
    transformations: transformations_2
  - id: 5
    interfaces: interfaces_2
    role: controller,mongo
    transformations: transformations_2
  - id: 6
    interfaces: interfaces_2
    role: controller,mongo
    transformations: transformations_2


--- Example 2 ---

Template file:

dea-override-config:
  network:
    networks:
    %{network/networks}


Result:

dea-override-config:
  network:
    networks:
    - cidr: 172.16.0.0/24
      gateway: 172.16.0.1
      ip_ranges:
      - - 172.16.0.2
        - 172.16.0.126
      meta:
        cidr: 172.16.0.0/24
        configurable: true
        floating_range_var: floating_ranges
        ip_range:
        - 172.16.0.2
        - 172.16.0.126
        map_priority: 1
        name: public
        notation: ip_ranges
        render_addr_mask: public
        render_type: null
        use_gateway: true
        vips:
        - haproxy
        - vrouter
        vlan_start: null
      name: public
      vlan_start: null
    - cidr: 192.168.1.0/24
      gateway: null
      ip_ranges:
      - - 192.168.1.1
        - 192.168.1.254
      meta:
        cidr: 192.168.1.0/24
        configurable: true
        map_priority: 2
        name: storage
        notation: cidr
        render_addr_mask: storage
        render_type: cidr
        use_gateway: false
        vlan_start: 102
      name: storage
      vlan_start: 102


--- Example 3 ---

Template file:

storage_if: %{interface(storage)}
compute_private_if: %{interface(private,compute)}
# Management interface of a mongo node
mongo_mgmt_if: %{interface(management,mongo)}
controller_private_if: %{interface(private,controller)}


Result:

storage_if: ens4
compute_private_if: ens5
# Management interface of a mongo node
mongo_mgmt_if: ens3
controller_private_if: ens4


--- Example 4 ---

Template file:

version: 1.1
created: Mon Jun 13 19:39:35 2016
comment: None
%{include(environment.yaml)}


environment.yaml:

environment:
  name: F9-NOSDN-NOFEATURE-VXLAN-BAREMETAL
  net_segment_type: tun


Result:

version: 1.1
created: Mon Jun 13 19:39:35 2016
comment: None
environment:
  name: F9-NOSDN-NOFEATURE-VXLAN-BAREMETAL
  net_segment_type: tun


--- Example 5 ---

Template file (except):

settings:
  editable:
    access:
      email:
        description: Email address for Administrator
        label: Email
        regex:
          error: Invalid email
          source: ^\S+@\S+$
        type: text
        value: admin@localhost
        weight: 40
# ...
# lines omitted for brevity
    %{include(templates/cgroups.yaml)}


cgroups.yaml:

    cgroups:
      metadata:
        always_editable: true
        group: general
        label: Cgroups conguration for services
        restrictions:
        - action: hide
          condition: 'true'
        weight: 90


Result:

settings:
  editable:
    access:
      email:
        description: Email address for Administrator
        label: Email
        regex:
          error: Invalid email
          source: ^\S+@\S+$
        type: text
        value: admin@localhost
        weight: 40
# ...
# again, lines omitted for brevity
    cgroups:
      metadata:
        always_editable: true
        group: general
        label: Cgroups conguration for services
        restrictions:
        - action: hide
          condition: 'true'
        weight: 90