Support OpenDaylight statistics driver

Change-Id: I6aa24a625387c39d4c0a2af666fde41682a37aaf
Closes-Bug: PROD-22021
diff --git a/.kitchen.yml b/.kitchen.yml
index fec26e7..277fded 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -65,6 +65,16 @@
             agent:
               version: <%= ENV['OS_VERSION'] || 'pike' %>
 
+  - name: agent_single_odl
+    provisioner:
+      pillars-from-files:
+        ceilometer.sls: tests/pillar/agent_single_odl.sls
+      pillars:
+        release.sls:
+          ceilometer:
+            agent:
+              version: <%= ENV['OS_VERSION'] || 'pike' %>
+
   - name: server_cluster
     provisioner:
       pillars-from-files:
diff --git a/README.rst b/README.rst
index 25b2fcd..3855b53 100644
--- a/README.rst
+++ b/README.rst
@@ -300,6 +300,31 @@
             level: WARNING
 
 
+Enable OpenDaylight statistics driver
+---------------------
+
+.. code-block:: yaml
+
+    ceilometer:
+      server:
+        opendaylight: true
+        .....
+      agent:
+        polling:
+          sources:
+            odl_source:
+              meters:
+                - switch
+                - switch.ports
+                - switch.port.receive.bytes
+                .....
+              interval: 300
+              resources:
+                - opendaylight.v2://<odl-controller-ip>:8080/controller/statistics?auth=basic&user=admin&password=unsegreto
+              sinks:
+                - meter_sink
+
+
 More Information
 ================
 
diff --git a/ceilometer/files/pike/polling.yaml b/ceilometer/files/pike/polling.yaml
index 48a51c4..33dd16e 100644
--- a/ceilometer/files/pike/polling.yaml
+++ b/ceilometer/files/pike/polling.yaml
@@ -4,8 +4,20 @@
 {%- for source_name, source in agent.polling.sources.items() %}
     - name: {{ source_name }}
       interval: {{ source.get('interval', 300) }}
+      {%- if source.resources is defined %}
+      resources:
+        {%- for resource in source.resources %}
+        - {{ resource }}
+        {%- endfor %}
+      {%- endif %}
       meters:
         {%- for meter in source.meters %}
         - "{{ meter }}"
         {%- endfor %}
+      {%- if source.sinks is defined %}
+      sinks:
+        {%- for sink in source.sinks %}
+        - {{ sink }}
+        {%- endfor %}
+      {%- endif %}
 {%- endfor %}
diff --git a/ceilometer/files/queens/polling.yaml b/ceilometer/files/queens/polling.yaml
index 48a51c4..33dd16e 100644
--- a/ceilometer/files/queens/polling.yaml
+++ b/ceilometer/files/queens/polling.yaml
@@ -4,8 +4,20 @@
 {%- for source_name, source in agent.polling.sources.items() %}
     - name: {{ source_name }}
       interval: {{ source.get('interval', 300) }}
+      {%- if source.resources is defined %}
+      resources:
+        {%- for resource in source.resources %}
+        - {{ resource }}
+        {%- endfor %}
+      {%- endif %}
       meters:
         {%- for meter in source.meters %}
         - "{{ meter }}"
         {%- endfor %}
+      {%- if source.sinks is defined %}
+      sinks:
+        {%- for sink in source.sinks %}
+        - {{ sink }}
+        {%- endfor %}
+      {%- endif %}
 {%- endfor %}
diff --git a/ceilometer/map.jinja b/ceilometer/map.jinja
index d749ccb..6b863c9 100644
--- a/ceilometer/map.jinja
+++ b/ceilometer/map.jinja
@@ -50,6 +50,7 @@
         'basic': ['ceilometer-agent-central', 'python-ceilometerclient', 'ceilometer-agent-notification'],
         'api': ['ceilometer-api'],
         'db_drivers': ['python-elasticsearch', 'python-influxdb', 'python-pymongo'],
+        'opendaylight': ['python-networking-odl'],
     },
     'RedHat': {
         'alarm': ['openstack-ceilometer-alarm-evaluator', 'openstack-ceilometer-alarm-notifier'],
@@ -57,6 +58,7 @@
         'api': ['openstack-ceilometer-api'],
         'collector':['openstack-ceilometer-collector'],
         'db_drivers': ['python-elasticsearch', 'python-influxdb', 'python-pymongo'],
+        'opendaylight': ['python-networking-odl'],
     },
 }) %}
 
@@ -106,6 +108,8 @@
 {%-   do server.update({'pkgs': pkgs.basic}) %}
 {%- endif %}
 
+{%- do server.pkgs.extend(pkgs.opendaylight) if salt['pillar.get']('ceilometer:server:opendaylight', False) %}
+
 {%- if salt['pillar.get']('ceilometer:server:version', 'mitaka') in ['liberty', 'juno', 'kilo'] %}
 {%-   do server.update({'services': services.basic + services.collector + services.alarm + services.webserved}) %}
 {%- elif salt['pillar.get']('ceilometer:server:version', 'ocata') == 'mitaka' %}
diff --git a/tests/pillar/agent_single_odl.sls b/tests/pillar/agent_single_odl.sls
new file mode 100644
index 0000000..e127f0d
--- /dev/null
+++ b/tests/pillar/agent_single_odl.sls
@@ -0,0 +1,48 @@
+ceilometer:
+  agent:
+    debug: true
+    #region: RegionOne
+    enabled: true
+    version: pike
+    secret: password
+    publisher:
+      default:
+        enabled: true
+    polling:
+      sources:
+        odl_source:
+          meters:
+            - switch
+            - switch.ports
+            - switch.port.receive.bytes
+          interval: 300
+          resources:
+            - opendaylight.v2://127.0.0.1:8080/controller/statistics?auth=basic&user=admin&password=unsegreto
+          sinks:
+            - meter_sink
+    identity:
+      engine: keystone
+      host: 127.0.0.1
+      port: 35357
+      tenant: service
+      user: ceilometer
+      password: password
+      endpoint_type: internalURL
+    logging:
+      log_appender: false
+      log_handlers:
+        watchedfile:
+          enabled: true
+        fluentd:
+          enabled: false
+        ossyslog:
+          enabled: false
+    message_queue:
+      engine: rabbitmq
+      host: 127.0.0.1
+      port: 5672
+      user: openstack
+      password: password
+      virtual_host: '/openstack'
+      # Workaround for https://bugs.launchpad.net/ceilometer/+bug/1337715
+      rpc_thread_pool_size: 5