
# Copyright 2017-present Open Networking Foundation
#
# 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.


---
- hosts: 127.0.0.1
  connection: local
  vars:
    appname: {{ appname }}
    dependencies: {{ dependencies }}
{% if component_configs %}
    component_configs:
{% for component_config in component_configs %}
       - component: {{ component_config.component }}
         config_params: {{  component_config.config_params }}
{% endfor %}
{% endif %}
{% if rest_configs %}
    var_rest_configs:
{% for rest_config in rest_configs %}
       - endpoint: {{ rest_config.endpoint }}
         body: "{{ '{{' }} lookup('file', '{{ files_dir }}/{{ rest_config.fn }}') {{ '}}' }}"
{% endfor %}
{% endif %}
    rest_hostname: {{ rest_hostname }}
    rest_port: {{ rest_port }}

  tasks:
{% if install_dependencies %}
  - name: Install ONOS apps by URL
    uri:
        url: "http://{{ rest_hostname }}:{{ rest_port }}/{{ '{{' }}  item.endpoint {{ '}}' }}"
        body: "{{ '{{' }} item.body | to_json {{ '}}' }}"
        user: {{ rest_username }}
        password: {{ rest_password }}
        body_format: json
        method: POST
        status_code: 200, 409
    with_items:
       {% for install_dependency in install_dependencies %}
       - endpoint: "onos/v1/applications"
         body:
           url: "{{ install_dependency }}"
           activate: "true"
       {% endfor %}
{% endif %}

{% if dependencies %}
  - name: Add dependencies to ONOS
    uri:
      url: http://{{ rest_hostname }}:{{ rest_port }}/onos/v1/applications/{{ '{{' }} item {{ '}}' }}/active
      method: POST
      user: karaf
      password: karaf
    with_items:
        {% for dependency in dependencies %}
        - {{ dependency }}
        {% endfor %}
{% endif %}

{% if component_configs %}
  - name: Add ONOS component configuration values
    uri:
      url: http://{{ rest_hostname }}:{{ rest_port }}/onos/v1/configuration/{{ '{{' }} item.component {{ '}}' }} #http://localhost:8181/onos/v1/configuration/
      body: "{{ '{{' }} item.config_params {{ '}}' }}"
      body_format: json
      method: POST
      user: karaf
      password: karaf
    with_items: "{{ '{{' }} component_configs {{ '}}' }}"
{% endif %}

{% if rest_configs %}
# Do this after services have been activated, or it will cause an exception.
# vOLT will re-read its net config; vbng may not.
  - name: Add ONOS configuration values
    uri:
      url: http://{{ rest_hostname }}:{{ rest_port }}/{{ '{{' }} item.endpoint {{ '}}' }} #http://localhost:8181/onos/v1/network/configuration/
      body: "{{ '{{' }} item.body {{ '}}' }}"
      body_format: json
      method: POST
      user: karaf
      password: karaf
    with_items: "{{ '{{' }} var_rest_configs {{ '}}' }}"
{% endif %}
