Merge pull request #11 from damjanek/master

Add AZ fallback
diff --git a/README.rst b/README.rst
index 2ca9873..971f76c 100644
--- a/README.rst
+++ b/README.rst
@@ -98,6 +98,21 @@
         audit:
           enabled: false
 
+
+Enable CORS parameters
+
+.. code-block:: yaml
+
+    cinder:
+      controller:
+        cors:
+          allowed_origin: https:localhost.local,http:localhost.local
+          expose_headers: X-Auth-Token,X-Openstack-Request-Id,X-Subject-Token
+          allow_methods: GET,PUT,POST,DELETE,PATCH
+          allow_headers: X-Auth-Token,X-Openstack-Request-Id,X-Subject-Token
+          allow_credentials: True
+          max_age: 86400
+
 Client-side RabbitMQ HA setup for controller
 
 .. code-block:: yaml
@@ -409,8 +424,36 @@
             clustername: cluster1
             sf_emulate_512: false
 
+Enable cinder-backup service for ceph
 
+.. code-block:: yaml
 
+    cinder:
+      controller:
+        enabled: true
+        version: mitaka
+        backup:
+          engine: ceph
+          ceph_conf: "/etc/ceph/ceph.conf"
+          ceph_pool: backup
+          ceph_stripe_count: 0
+          ceph_stripe_unit: 0
+          ceph_user: cinder
+          ceph_chunk_size: 134217728
+          restore_discard_excess_bytes: false
+      volume:
+        enabled: true
+        version: mitaka
+        backup:
+          engine: ceph
+          ceph_conf: "/etc/ceph/ceph.conf"
+          ceph_pool: backup
+          ceph_stripe_count: 0
+          ceph_stripe_unit: 0
+          ceph_user: cinder
+          ceph_chunk_size: 134217728
+          restore_discard_excess_bytes: false
+          
 Enable auditing filter, ie: CADF
 
 .. code-block:: yaml
@@ -444,6 +487,21 @@
         default_availability_zone: my-default-zone
         storage_availability_zone: my-custom-zone-name
 
+
+Cinder setup with custom non-admin volume query filters:
+
+.. code-block:: yaml
+
+    cinder:
+      controller:
+        query_volume_filters:
+          - name
+          - status
+          - metadata
+          - availability_zone
+          - bootable
+
+
 public_endpoint and osapi_volume_base_url parameters:
 "public_endpoint" is used for configuring versions endpoint,
 "osapi_volume_base_URL" is used to present Cinder URL to users.
diff --git a/cinder/controller.sls b/cinder/controller.sls
index 805d0a5..a50a3ca 100644
--- a/cinder/controller.sls
+++ b/cinder/controller.sls
@@ -142,4 +142,20 @@
 
 {% endfor %}
 
+{%- if controller.backup.engine != None %}
+
+cinder_backup_packages:
+  pkg.installed:
+  - names: {{ controller.backup.pkgs }}
+
+cinder_backup_services:
+  service.running:
+  - names: {{ controller.backup.services }}
+  - enable: true
+  - watch:
+    - file: /etc/cinder/cinder.conf
+    - file: /etc/cinder/api-paste.ini
+
+{%- endif %}
+
 {%- endif %}
\ No newline at end of file
diff --git a/cinder/files/backup_backend/_ceph.conf b/cinder/files/backup_backend/_ceph.conf
new file mode 100644
index 0000000..34a7465
--- /dev/null
+++ b/cinder/files/backup_backend/_ceph.conf
@@ -0,0 +1,8 @@
+#backup conf
+backup_driver=cinder.backup.drivers.{{ controller.backup.engine }}
+backup_ceph_conf={{ controller.backup.get('ceph_conf', '/etc/ceph/ceph.conf') }}
+backup_ceph_user = {{ controller.backup.get('ceph_user', cinder) }}
+backup_ceph_chunk_size = {{ controller.backup.get('ceph_chunk_size', 134217728 )}}
+backup_ceph_pool = {{ controller.backup.get('ceph_pool', backup) }}
+backup_ceph_stripe_unit = {{ controller.backup.get('ceph_stripe_unit', 0) }}
+backup_ceph_stripe_count = {{ controller.backup.get('ceph_stripe_count', 0) }}
\ No newline at end of file
diff --git a/cinder/files/grafana_dashboards/cinder_influxdb.json b/cinder/files/grafana_dashboards/cinder_influxdb.json
index 322f042..3fcf8f2 100644
--- a/cinder/files/grafana_dashboards/cinder_influxdb.json
+++ b/cinder/files/grafana_dashboards/cinder_influxdb.json
@@ -2569,13 +2569,7 @@
           "title": "Available Volumes",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -2685,13 +2679,7 @@
           "title": "Volumes in use",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -2800,13 +2788,7 @@
           "title": "Volumes in error",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -2856,7 +2838,7 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
@@ -2864,7 +2846,7 @@
               "hide": false,
               "measurement": "openstack_cinder_volumes",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'available' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'available' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -2908,14 +2890,14 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
               ],
               "measurement": "openstack_cinder_volumes",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'in-use' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'in-use' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "B",
               "resultFormat": "time_series",
@@ -2960,7 +2942,7 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
@@ -2968,7 +2950,7 @@
               "hide": false,
               "measurement": "openstack_cinder_volumes",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'error' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'error' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "C",
               "resultFormat": "time_series",
@@ -3139,13 +3121,7 @@
           "title": "",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0 GiB",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -3254,13 +3230,7 @@
           "title": "",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0 GiB",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -3369,13 +3339,7 @@
           "title": "",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0 GiB",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -3424,14 +3388,14 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
               ],
               "measurement": "openstack_cinder_volumes_size",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'available' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'available' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -3476,14 +3440,14 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
               ],
               "measurement": "openstack_cinder_volumes_size",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'in-use' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'in-use' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "B",
               "resultFormat": "time_series",
@@ -3528,14 +3492,14 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
               ],
               "measurement": "openstack_cinder_volumes_size",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'error' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_volumes_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'error' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "C",
               "resultFormat": "time_series",
@@ -3972,7 +3936,7 @@
             "thresholdLabels": false,
             "thresholdMarkers": true
           },
-          "id": 12,
+          "id": 112,
           "interval": "> 60s",
           "links": [],
           "mappingType": 1,
@@ -4057,13 +4021,7 @@
           "title": "Available Snapshots",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -4086,7 +4044,7 @@
             "thresholdLabels": false,
             "thresholdMarkers": true
           },
-          "id": 21,
+          "id": 121,
           "interval": "> 60s",
           "links": [],
           "mappingType": 1,
@@ -4137,7 +4095,7 @@
               ],
               "measurement": "openstack_cinder_snapshots",
               "policy": "default",
-              "query": "SELECT last(\"value\") FROM \"openstack_cinder_snapshots\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'in-use' AND $timeFilter GROUP BY time($interval)",
+              "query": "SELECT last(\"value\") FROM \"openstack_cinder_snapshots\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'creating' AND $timeFilter GROUP BY time($interval)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -4163,22 +4121,16 @@
                 },
                 {
                   "key": "state",
-                  "value": "in-use"
+                  "value": "creating"
                 }
               ]
             }
           ],
           "thresholds": "",
-          "title": "Snapshots in use",
+          "title": "Snapshots in creation",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -4201,7 +4153,7 @@
             "thresholdLabels": false,
             "thresholdMarkers": true
           },
-          "id": 16,
+          "id": 116,
           "interval": "> 60s",
           "links": [],
           "mappingType": 1,
@@ -4287,13 +4239,7 @@
           "title": "Snapshots in error",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -4305,7 +4251,7 @@
           "error": false,
           "fill": 0,
           "grid": {},
-          "id": 54,
+          "id": 154,
           "interval": ">60s",
           "legend": {
             "avg": false,
@@ -4343,7 +4289,7 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
@@ -4351,7 +4297,7 @@
               "hide": false,
               "measurement": "openstack_cinder_snapshots",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'available' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'available' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -4382,7 +4328,7 @@
               ]
             },
             {
-              "alias": "in-use",
+              "alias": "creating",
               "column": "value",
               "dsType": "influxdb",
               "function": "max",
@@ -4395,14 +4341,14 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
               ],
               "measurement": "openstack_cinder_snapshots",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'in-use' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'creating' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "B",
               "resultFormat": "time_series",
@@ -4428,7 +4374,7 @@
                 },
                 {
                   "key": "state",
-                  "value": "in-use"
+                  "value": "creating"
                 }
               ],
               "target": ""
@@ -4447,7 +4393,7 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
@@ -4455,7 +4401,7 @@
               "hide": false,
               "measurement": "openstack_cinder_snapshots",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'error' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'error' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "C",
               "resultFormat": "time_series",
@@ -4541,7 +4487,7 @@
             "thresholdLabels": false,
             "thresholdMarkers": true
           },
-          "id": 23,
+          "id": 123,
           "interval": "> 60s",
           "links": [],
           "mappingType": 1,
@@ -4626,13 +4572,7 @@
           "title": "",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0 GiB",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -4655,7 +4595,7 @@
             "thresholdLabels": false,
             "thresholdMarkers": true
           },
-          "id": 24,
+          "id": 124,
           "interval": "> 60s",
           "links": [],
           "mappingType": 1,
@@ -4706,7 +4646,7 @@
               ],
               "measurement": "openstack_cinder_snapshots_size",
               "policy": "default",
-              "query": "SELECT last(\"value\") FROM \"openstack_cinder_snapshots_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'in-use' AND $timeFilter GROUP BY time($interval)",
+              "query": "SELECT last(\"value\") FROM \"openstack_cinder_snapshots_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'creating' AND $timeFilter GROUP BY time($interval)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -4732,7 +4672,7 @@
                 },
                 {
                   "key": "state",
-                  "value": "in-use"
+                  "value": "creating"
                 }
               ]
             }
@@ -4741,13 +4681,7 @@
           "title": "",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0 GiB",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -4770,7 +4704,7 @@
             "thresholdLabels": false,
             "thresholdMarkers": true
           },
-          "id": 25,
+          "id": 125,
           "interval": "> 60s",
           "links": [],
           "mappingType": 1,
@@ -4856,13 +4790,7 @@
           "title": "",
           "type": "singlestat",
           "valueFontSize": "80%",
-          "valueMaps": [
-            {
-              "op": "=",
-              "text": "0 GiB",
-              "value": "null"
-            }
-          ],
+          "valueMaps": [],
           "valueName": "current"
         },
         {
@@ -4873,7 +4801,7 @@
           "error": false,
           "fill": 0,
           "grid": {},
-          "id": 55,
+          "id": 155,
           "interval": ">60s",
           "legend": {
             "avg": false,
@@ -4911,14 +4839,14 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
               ],
               "measurement": "openstack_cinder_snapshots_size",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'available' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'available' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -4949,7 +4877,7 @@
               ]
             },
             {
-              "alias": "in-use",
+              "alias": "creating",
               "column": "value",
               "dsType": "influxdb",
               "function": "max",
@@ -4962,14 +4890,14 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
               ],
               "measurement": "openstack_cinder_snapshots_size",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'in-use' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'creating' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "B",
               "resultFormat": "time_series",
@@ -4995,7 +4923,7 @@
                 },
                 {
                   "key": "state",
-                  "value": "in-use"
+                  "value": "creating"
                 }
               ]
             },
@@ -5013,14 +4941,14 @@
                 },
                 {
                   "params": [
-                    "0"
+                    "null"
                   ],
                   "type": "fill"
                 }
               ],
               "measurement": "openstack_cinder_snapshots_size",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'error' AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"openstack_cinder_snapshots_size\" WHERE \"environment_label\" =~ /^$environment$/ AND \"state\" = 'error' AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "C",
               "resultFormat": "time_series",
@@ -5184,5 +5112,5 @@
   },
   "timezone": "browser",
   "title": "Cinder",
-  "version": 7
-}
\ No newline at end of file
+  "version": 8
+}
diff --git a/cinder/files/liberty/cinder.conf.controller.Debian b/cinder/files/liberty/cinder.conf.controller.Debian
index 53b1296..460f0b0 100644
--- a/cinder/files/liberty/cinder.conf.controller.Debian
+++ b/cinder/files/liberty/cinder.conf.controller.Debian
@@ -24,6 +24,11 @@
 state_path = /var/lib/cinder
 lock_path = /var/lock/cinder
 
+{%- if controller.query_volume_filters is defined %}
+# Available query filters for non-admin user
+query_volume_filters = {{ controller.query_volume_filters|join(",") }}
+{%- endif %}
+
 use_syslog=False
 
 glance_num_retries=0
@@ -87,7 +92,6 @@
 notification_driver = messagingv2
 {%- endif %}
 
-
 volume_name_template = volume-%s
 
 #volume_group = vg_cinder_volume
diff --git a/cinder/files/mitaka/cinder.conf.controller.Debian b/cinder/files/mitaka/cinder.conf.controller.Debian
index 0e68e26..77f9bac 100644
--- a/cinder/files/mitaka/cinder.conf.controller.Debian
+++ b/cinder/files/mitaka/cinder.conf.controller.Debian
@@ -79,6 +79,15 @@
 verbose=True
 lock_path=/var/lock/cinder
 
+{%- if controller.query_volume_filters is defined %}
+query_volume_filters = {{ controller.query_volume_filters|join(",") }}
+{%- endif %}
+
+{%- if controller.backup.engine != None %}
+{%- set backup_backend_fragment = "cinder/files/backup_backend/_" + controller.backup.engine + ".conf" %}
+{%- include backup_backend_fragment %}
+{%- endif %}
+
 [oslo_messaging_notifications]
 {%- if controller.notification is mapping %}
 driver = {{ controller.notification.get('driver', 'messagingv2') }}
@@ -141,3 +150,50 @@
 {%- endfor %}
 
 {%- endif %}
+
+[cors]
+
+#
+# From oslo.middleware.cors
+#
+
+# Indicate whether this resource may be shared with the domain
+# received in the requests "origin" header. (list value)
+#allowed_origin = <None>
+{%- if controller.cors.allowed_origin is defined %}
+allowed_origin = {{ controller.cors.allowed_origin }}
+{%- endif %}
+
+# Indicate that the actual request can include user credentials
+# (boolean value)
+#allow_credentials = true
+{%- if controller.cors.allow_credentials is defined %}
+allow_credentials = {{ controller.cors.allow_credentials }}
+{%- endif %}
+
+# Indicate which headers are safe to expose to the API. Defaults to
+# HTTP Simple Headers. (list value)
+#expose_headers = X-Image-Meta-Checksum,X-Auth-Token,X-Subject-Token,X-Service-Token,X-OpenStack-Request-ID
+{%- if controller.cors.expose_headers is defined %}
+expose_headers = {{ controller.cors.expose_headers }}
+{%- endif %}
+
+# Maximum cache age of CORS preflight requests. (integer value)
+#max_age = 3600
+{%- if controller.cors.max_age is defined %}
+max_age = {{ controller.cors.max_age }}
+{%- endif %}
+
+# Indicate which methods can be used during the actual request. (list
+# value)
+#allow_methods = GET,PUT,POST,DELETE,PATCH
+{%- if controller.cors.allow_methods is defined %}
+allow_methods = {{ controller.cors.allow_methods }}
+{%- endif %}
+
+# Indicate which header field names may be used during the actual
+# request. (list value)
+#allow_headers = Content-MD5,X-Image-Meta-Checksum,X-Storage-Token,Accept-Encoding,X-Auth-Token,X-Identity-Status,X-Roles,X-Service-Catalog,X-User-Id,X-Tenant-Id,X-OpenStack-Request-ID
+{%- if controller.cors.allow_headers is defined %}
+allow_headers = {{ controller.cors.allow_headers }}
+{%- endif %}
diff --git a/cinder/files/mitaka/cinder.conf.volume.Debian b/cinder/files/mitaka/cinder.conf.volume.Debian
index beb8008..f3633e6 100644
--- a/cinder/files/mitaka/cinder.conf.volume.Debian
+++ b/cinder/files/mitaka/cinder.conf.volume.Debian
@@ -75,6 +75,11 @@
 use_syslog=false
 verbose=True
 
+{%- if volume.backup.engine != None %}
+{%- set backup_backend_fragment = "cinder/files/backup_backend/_" + volume.backup.engine + ".conf" %}
+{%- include backup_backend_fragment %}
+{%- endif %}
+
 [oslo_messaging_notifications]
 {%- if volume.notification is mapping %}
 driver = {{ volume.notification.get('driver', 'messagingv2') }}
diff --git a/cinder/files/newton/cinder.conf.controller.Debian b/cinder/files/newton/cinder.conf.controller.Debian
index d4965f1..528d8a6 100644
--- a/cinder/files/newton/cinder.conf.controller.Debian
+++ b/cinder/files/newton/cinder.conf.controller.Debian
@@ -87,6 +87,10 @@
 verbose=True
 lock_path=/var/lock/cinder
 
+{%- if controller.query_volume_filters is defined %}
+query_volume_filters = {{ controller.query_volume_filters|join(",") }}
+{%- endif %}
+
 nova_catalog_admin_info = compute:nova:adminURL
 nova_catalog_info = compute:nova:{{ controller.identity.get('endpoint_type', 'publicURL') }}
 
@@ -102,6 +106,11 @@
 transport_url = rabbit://{{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ controller.message_queue.host }}:{{ controller.message_queue.port }}/{{ controller.message_queue.virtual_host }}
 {%- endif %}
 
+{%- if controller.backup.engine != None %}
+{%- set backup_backend_fragment = "cinder/files/backup_backend/_" + controller.backup.engine + ".conf" %}
+{%- include backup_backend_fragment %}
+{%- endif %}
+
 [oslo_messaging_notifications]
 {%- if controller.notification is mapping %}
 driver = {{ controller.notification.get('driver', 'messagingv2') }}
@@ -162,3 +171,50 @@
 {%- endfor %}
 
 {%- endif %}
+
+[cors]
+
+#
+# From oslo.middleware.cors
+#
+
+# Indicate whether this resource may be shared with the domain
+# received in the requests "origin" header. (list value)
+#allowed_origin = <None>
+{%- if controller.cors.allowed_origin is defined %}
+allowed_origin = {{ controller.cors.allowed_origin }}
+{%- endif %}
+
+# Indicate that the actual request can include user credentials
+# (boolean value)
+#allow_credentials = true
+{%- if controller.cors.allow_credentials is defined %}
+allow_credentials = {{ controller.cors.allow_credentials }}
+{%- endif %}
+
+# Indicate which headers are safe to expose to the API. Defaults to
+# HTTP Simple Headers. (list value)
+#expose_headers = X-Image-Meta-Checksum,X-Auth-Token,X-Subject-Token,X-Service-Token,X-OpenStack-Request-ID
+{%- if controller.cors.expose_headers is defined %}
+expose_headers = {{ controller.cors.expose_headers }}
+{%- endif %}
+
+# Maximum cache age of CORS preflight requests. (integer value)
+#max_age = 3600
+{%- if controller.cors.max_age is defined %}
+max_age = {{ controller.cors.max_age }}
+{%- endif %}
+
+# Indicate which methods can be used during the actual request. (list
+# value)
+#allow_methods = GET,PUT,POST,DELETE,PATCH
+{%- if controller.cors.allow_methods is defined %}
+allow_methods = {{ controller.cors.allow_methods }}
+{%- endif %}
+
+# Indicate which header field names may be used during the actual
+# request. (list value)
+#allow_headers = Content-MD5,X-Image-Meta-Checksum,X-Storage-Token,Accept-Encoding,X-Auth-Token,X-Identity-Status,X-Roles,X-Service-Catalog,X-User-Id,X-Tenant-Id,X-OpenStack-Request-ID
+{%- if controller.cors.allow_headers is defined %}
+allow_headers = {{ controller.cors.allow_headers }}
+{%- endif %}
diff --git a/cinder/files/newton/cinder.conf.volume.Debian b/cinder/files/newton/cinder.conf.volume.Debian
index 36423ed..1124056 100644
--- a/cinder/files/newton/cinder.conf.volume.Debian
+++ b/cinder/files/newton/cinder.conf.volume.Debian
@@ -95,6 +95,11 @@
 transport_url = rabbit://{{ volume.message_queue.user }}:{{ volume.message_queue.password }}@{{ volume.message_queue.host }}:{{ volume.message_queue.port }}/{{ volume.message_queue.virtual_host }}
 {%- endif %}
 
+{%- if volume.backup.engine != None %}
+{%- set backup_backend_fragment = "cinder/files/backup_backend/_" + volume.backup.engine + ".conf" %}
+{%- include backup_backend_fragment %}
+{%- endif %}
+
 [oslo_messaging_notifications]
 {%- if volume.notification is mapping %}
 driver = {{ volume.notification.get('driver', 'messagingv2') }}
diff --git a/cinder/files/ocata/cinder.conf.controller.Debian b/cinder/files/ocata/cinder.conf.controller.Debian
index d4965f1..528d8a6 100644
--- a/cinder/files/ocata/cinder.conf.controller.Debian
+++ b/cinder/files/ocata/cinder.conf.controller.Debian
@@ -87,6 +87,10 @@
 verbose=True
 lock_path=/var/lock/cinder
 
+{%- if controller.query_volume_filters is defined %}
+query_volume_filters = {{ controller.query_volume_filters|join(",") }}
+{%- endif %}
+
 nova_catalog_admin_info = compute:nova:adminURL
 nova_catalog_info = compute:nova:{{ controller.identity.get('endpoint_type', 'publicURL') }}
 
@@ -102,6 +106,11 @@
 transport_url = rabbit://{{ controller.message_queue.user }}:{{ controller.message_queue.password }}@{{ controller.message_queue.host }}:{{ controller.message_queue.port }}/{{ controller.message_queue.virtual_host }}
 {%- endif %}
 
+{%- if controller.backup.engine != None %}
+{%- set backup_backend_fragment = "cinder/files/backup_backend/_" + controller.backup.engine + ".conf" %}
+{%- include backup_backend_fragment %}
+{%- endif %}
+
 [oslo_messaging_notifications]
 {%- if controller.notification is mapping %}
 driver = {{ controller.notification.get('driver', 'messagingv2') }}
@@ -162,3 +171,50 @@
 {%- endfor %}
 
 {%- endif %}
+
+[cors]
+
+#
+# From oslo.middleware.cors
+#
+
+# Indicate whether this resource may be shared with the domain
+# received in the requests "origin" header. (list value)
+#allowed_origin = <None>
+{%- if controller.cors.allowed_origin is defined %}
+allowed_origin = {{ controller.cors.allowed_origin }}
+{%- endif %}
+
+# Indicate that the actual request can include user credentials
+# (boolean value)
+#allow_credentials = true
+{%- if controller.cors.allow_credentials is defined %}
+allow_credentials = {{ controller.cors.allow_credentials }}
+{%- endif %}
+
+# Indicate which headers are safe to expose to the API. Defaults to
+# HTTP Simple Headers. (list value)
+#expose_headers = X-Image-Meta-Checksum,X-Auth-Token,X-Subject-Token,X-Service-Token,X-OpenStack-Request-ID
+{%- if controller.cors.expose_headers is defined %}
+expose_headers = {{ controller.cors.expose_headers }}
+{%- endif %}
+
+# Maximum cache age of CORS preflight requests. (integer value)
+#max_age = 3600
+{%- if controller.cors.max_age is defined %}
+max_age = {{ controller.cors.max_age }}
+{%- endif %}
+
+# Indicate which methods can be used during the actual request. (list
+# value)
+#allow_methods = GET,PUT,POST,DELETE,PATCH
+{%- if controller.cors.allow_methods is defined %}
+allow_methods = {{ controller.cors.allow_methods }}
+{%- endif %}
+
+# Indicate which header field names may be used during the actual
+# request. (list value)
+#allow_headers = Content-MD5,X-Image-Meta-Checksum,X-Storage-Token,Accept-Encoding,X-Auth-Token,X-Identity-Status,X-Roles,X-Service-Catalog,X-User-Id,X-Tenant-Id,X-OpenStack-Request-ID
+{%- if controller.cors.allow_headers is defined %}
+allow_headers = {{ controller.cors.allow_headers }}
+{%- endif %}
diff --git a/cinder/files/ocata/cinder.conf.volume.Debian b/cinder/files/ocata/cinder.conf.volume.Debian
index 36423ed..1124056 100644
--- a/cinder/files/ocata/cinder.conf.volume.Debian
+++ b/cinder/files/ocata/cinder.conf.volume.Debian
@@ -95,6 +95,11 @@
 transport_url = rabbit://{{ volume.message_queue.user }}:{{ volume.message_queue.password }}@{{ volume.message_queue.host }}:{{ volume.message_queue.port }}/{{ volume.message_queue.virtual_host }}
 {%- endif %}
 
+{%- if volume.backup.engine != None %}
+{%- set backup_backend_fragment = "cinder/files/backup_backend/_" + volume.backup.engine + ".conf" %}
+{%- include backup_backend_fragment %}
+{%- endif %}
+
 [oslo_messaging_notifications]
 {%- if volume.notification is mapping %}
 driver = {{ volume.notification.get('driver', 'messagingv2') }}
diff --git a/cinder/map.jinja b/cinder/map.jinja
index b11a90d..340eb9b 100644
--- a/cinder/map.jinja
+++ b/cinder/map.jinja
@@ -5,8 +5,14 @@
         'services': ['cinder-scheduler'],
         'wipe_method': 'none',
         'notification': False,
+        'cors': {},
         'audit': {
           'enabled': false
+        },
+        'backup': {
+          'pkgs': ['cinder-backup'],
+          'services': ['cinder-backup'],
+          'engine': None
         }
     },
     'RedHat': {
@@ -14,9 +20,16 @@
         'services': ['openstack-cinder-api', 'openstack-cinder-scheduler'],
         'wipe_method': 'none',
         'notification': False,
+        'cors': {},
         'audit': {
           'enabled': false
+        },
+        'backup': {
+          'pkgs': ['cinder-backup'],
+          'services': ['cinder-backup'],
+          'engine': None
         }
+
     },
 }, merge=pillar.cinder.get('controller', {})) %}
 
@@ -28,7 +41,13 @@
         'notification': False,
         'audit': {
           'enabled': false
+        },
+        'backup': {
+          'pkgs': ['cinder-backup'],
+          'services': ['cinder-backup'],
+          'engine': None
         }
+
     },
     'RedHat': {
         'pkgs': ['openstack-cinder', 'python-cinder', 'lvm2', 'sysfsutils', 'sg3_utils', 'device-mapper-multipath', 'device-mapper-multipath-libs', 'python-pycadf'],
@@ -37,6 +56,11 @@
         'notification': False,
         'audit': {
           'enabled': false
+        },
+        'backup': {
+          'pkgs': ['cinder-backup'],
+          'services': ['cinder-backup'],
+          'engine': None
         }
     },
 }, merge=pillar.cinder.get('volume', {})) %}
diff --git a/cinder/volume.sls b/cinder/volume.sls
index 762b665..b4bc0f8 100644
--- a/cinder/volume.sls
+++ b/cinder/volume.sls
@@ -36,6 +36,22 @@
   - require:
     - pkg: cinder_volume_packages
 
+{%- if volume.backup.engine != None %}
+
+cinder_backup_packages:
+  pkg.installed:
+  - names: {{ volume.backup.pkgs }}
+
+cinder_backup_services:
+  service.running:
+  - names: {{ volume.backup.services }}
+  - enable: true
+  - watch:
+    - file: /etc/cinder/cinder.conf
+    - file: /etc/cinder/api-paste.ini
+
+{%- endif %}
+
 {%- endif %}
 
 {%- if not grains.get('noservices', False) %}