Merge "Disable Sensu support by default"
diff --git a/README.rst b/README.rst
index 62b8986..dac4563 100644
--- a/README.rst
+++ b/README.rst
@@ -160,6 +160,30 @@
               user: 2ec7966596504f59acc3a76b3b9d9291:glance-user
               key: someRandomPassword
 
+Another way, which also supports multiple swift backends, can be configured like this:
+
+.. code-block:: yaml
+
+    glance:
+      server:
+        enabled: true
+        version: mitaka
+        storage:
+          engine: swift,http
+          swift:
+            store:
+              endpoint_type: publicURL
+              container: glance
+              create_container_on_put: true
+              retry_get_count: 5
+              references:
+                my_objectstore_reference_1:
+                  auth:
+                    address: http://keystone.example.com:5000/v2.0
+                    version: 2
+                  user: 2ec7966596504f59acc3a76b3b9d9291:glance-user
+                  key: someRandomPassword
+
 Enable CORS parameters
 
 .. code-block:: yaml
@@ -174,6 +198,26 @@
           allow_credentials: True
           max_age: 86400
 
+Enable Viewing Multiple Locations
+---------------------------------
+If you want to expose all locations available (for example when you have
+multiple backends configured), then you can configure this like so:
+
+.. code-block:: yaml
+
+    glance:
+      server:
+        show_multiple_locations: True
+        location_strategy: store_type
+        store_type_preference: rbd,swift,file
+
+Please note: the show_multiple_locations option is deprecated since Newton and is planned
+             to be handled by policy files _only_ starting with the Pike release.
+
+This feature is convenient in a scenario when you have swift and rbd configured and want to
+benefit from rbd enhancements.
+
+
 Client role
 -----------
 
diff --git a/glance/files/_backends/_swift.conf b/glance/files/_backends/_swift.conf
new file mode 100644
index 0000000..2b34391
--- /dev/null
+++ b/glance/files/_backends/_swift.conf
@@ -0,0 +1,46 @@
+{%- from "glance/map.jinja" import server with context %}
+
+{% for reference_key, reference in server.storage.get('swift', {}).get('store', {}).get('references', {}).iteritems() %}
+[{{ reference_key }}]
+# A project_name user_name pair in the project_name:user_name format to authenticate against the Swift authentication service.
+user = {{ reference.user }}
+
+# An authentication key for a user authenticating against the Swift authentication service.
+key = {{ reference.key }}
+
+# An address where the Swift authentication service is located.
+auth_address = {{ reference.auth.address }}
+
+# A version of the authentication service to use. Valid versions are 2 and 3 for Keystone and 1 (deprecated) for Swauth and Rackspace.
+# Optional. Default: 2
+auth_version = {{ reference.auth.get('version', '2') }}
+
+{%- if reference.project_domain_id is defined %}
+# A domain ID of the project which is the requested project-level authorization scope.
+# Optional. Default: None
+# This option can be specified if ``auth_version` is 3 .`
+project_domain_id = {{ reference.project_domain_id }}
+{% endif %}
+
+{%- if reference.project_domain_name is defined %}
+# A domain name of the project which is the requested project-level authorization scope.
+# Optional. Default: None
+# This option can be specified if ``auth_version` is 3 .`
+project_domain_name = {{ reference.project_domain_name }}
+{% endif %}
+
+{%- if reference.user_domain_id is defined %}
+# A domain ID of the user which is the requested domain-level authorization scope.
+# Optional. Default: None
+# This option can be specified if ``auth_version` is 3 .`
+user_domain_id = {{ reference.user_domain_id }}
+{% endif %}
+
+{%- if reference.user_domain_name is defined %}
+# A domain name of the user which is the requested domain-level authorization scope.
+# Optional. Default: None
+# This option can be specified if ``auth_version` is 3. `
+user_domain_name = {{ reference.user_domain_name }}
+{% endif %}
+
+{% endfor %}
diff --git a/glance/files/mitaka/glance-api.conf.Debian b/glance/files/mitaka/glance-api.conf.Debian
index 1fef2e8..3efb9dc 100644
--- a/glance/files/mitaka/glance-api.conf.Debian
+++ b/glance/files/mitaka/glance-api.conf.Debian
@@ -73,6 +73,7 @@
 # security risk, so use this setting with caution! Setting this to
 # true overrides the show_image_direct_url option. (boolean value)
 #show_multiple_locations = false
+show_multiple_locations = {{ server.get('show_multiple_locations', False) | lower }}
 
 # Maximum size of image a user can upload in bytes. Defaults to
 # 1099511627776 bytes (1 TB).WARNING: this value should only be
@@ -130,6 +131,11 @@
 # 'location_order' and 'store_type'. (string value)
 # Allowed values: location_order, store_type
 #location_strategy = location_order
+{% if server.get('location_strategy', 'location_order') == 'location_order' %}
+location_strategy = location_order
+{% else %}
+location_strategy = store_type
+{% endif %}
 
 # The location of the property protection file.This file contains the
 # rules for property protections and the roles/policies associated
@@ -828,7 +834,7 @@
 # If True, swiftclient won't check for a valid SSL certificate when
 # authenticating. (boolean value)
 #swift_store_auth_insecure = false
-swift_store_auth_insecure = {{ server.storage.swift.store.auth.get('insecure', False)|lower }}
+swift_store_auth_insecure = {{ server.storage.swift.store.get('auth', {}).get('insecure', False)|lower }}
 
 # A string giving the CA certificate file to use in SSL connections
 # for verifying certs. (string value)
@@ -962,32 +968,40 @@
 # (deprecated - use "auth_version" in swift_store_config_file) (string
 # value)
 #swift_store_auth_version = 2
+{% if server.storage.swift.store.get('auth', {}).get('version', False) %}
 swift_store_auth_version = {{ server.storage.swift.store.auth.version }}
+{% endif %}
 
 # The address where the Swift authentication service is listening.
 # (deprecated - use "auth_address" in swift_store_config_file) (string
 # value)
 #swift_store_auth_address = <None>
+{% if server.storage.swift.store.get('auth', {}).get('address', False) %}
 swift_store_auth_address = {{ server.storage.swift.store.auth.address }}
+{% endif %}
 
 # The user to authenticate against the Swift authentication service
 # (deprecated - use "user" in swift_store_config_file) (string value)
 #swift_store_user = <None>
+{% if server.storage.swift.store.user is defined %}
 swift_store_user = {{ server.storage.swift.store.user }}
+{% endif %}
 
 # Auth key for the user authenticating against the Swift
 # authentication service. (deprecated - use "key" in
 # swift_store_config_file) (string value)
 #swift_store_key = <None>
+{% if server.storage.swift.store.key is defined %}
 swift_store_key = {{ server.storage.swift.store.key }}
+{% endif %}
 
 # The config file that has the swift account(s)configs. (string value)
 #swift_store_config_file = <None>
-{% if server.storage.swift.store.config_file is defined %}
-swift_store_config_file = {{ server.storage.swift.store.config_file }}
+{% if server.storage.swift.store.references is defined %}
+swift_store_config_file = /etc/glance/swift-stores.conf
+{% endif %}
 {% endif %}
 
-{% endif %}
 
 {%- if 'rbd' in storage_engines %}
 # RADOS images will be chunked into objects of this size (in
@@ -1847,6 +1861,9 @@
 # option as image location strategy defined by the 'location_strategy'
 # config option. (list value)
 #store_type_preference =
+{% if server.get('location_strategy', 'location_order') == 'store_type' and server.store_type_preference is defined %}
+store_type_preference = {{ server.store_type_preference }}
+{% endif %}
 
 
 [task]
diff --git a/glance/files/newton/glance-api.conf.Debian b/glance/files/newton/glance-api.conf.Debian
index 7998526..de83148 100644
--- a/glance/files/newton/glance-api.conf.Debian
+++ b/glance/files/newton/glance-api.conf.Debian
@@ -330,6 +330,7 @@
 # functionality can be achieved with greater granularity by using policies.
 # Please see the Newton release notes for more information.
 #show_multiple_locations = false
+show_multiple_locations = {{ server.get('show_multiple_locations', False) | lower }}
 
 #
 # Maximum size of image a user can upload in bytes.
@@ -602,6 +603,11 @@
 #  (string value)
 # Allowed values: location_order, store_type
 #location_strategy = location_order
+{% if server.get('location_strategy', 'location_order') == 'location_order' %}
+location_strategy = location_order
+{% else %}
+location_strategy = store_type
+{% endif %}
 
 #
 # The location of the property protection file.
@@ -2604,7 +2610,7 @@
 #  (boolean value)
 {%- if 'swift' in storage_engines %}
 #swift_store_auth_insecure = false
-swift_store_auth_insecure = {{ server.storage.swift.store.auth.get('insecure', False)|lower }}
+swift_store_auth_insecure = {{ server.storage.swift.store.get('auth', {}).get('insecure', False)|lower }}
 
 #
 # Path to the CA bundle file.
@@ -3052,7 +3058,9 @@
 # The option 'auth_version' in the Swift back-end configuration file is
 # used instead.
 #swift_store_auth_version = 2
+{% if server.storage.swift.store.get('auth', {}).get('version', False) %}
 swift_store_auth_version = {{ server.storage.swift.store.auth.version }}
+{% endif %}
 
 # DEPRECATED: The address where the Swift authentication service is listening.
 # (string value)
@@ -3062,7 +3070,9 @@
 # The option 'auth_address' in the Swift back-end configuration file is
 # used instead.
 #swift_store_auth_address = <None>
+{% if server.storage.swift.store.get('auth', {}).get('address', False) %}
 swift_store_auth_address = {{ server.storage.swift.store.auth.address }}
+{% endif %}
 
 # DEPRECATED: The user to authenticate against the Swift authentication service.
 # (string value)
@@ -3071,7 +3081,9 @@
 # Reason:
 # The option 'user' in the Swift back-end configuration file is set instead.
 #swift_store_user = <None>
+{% if server.storage.swift.store.user is defined %}
 swift_store_user = {{ server.storage.swift.store.user }}
+{% endif %}
 
 # DEPRECATED: Auth key for the user authenticating against the Swift
 # authentication service. (string value)
@@ -3081,7 +3093,9 @@
 # The option 'key' in the Swift back-end configuration file is used
 # to set the authentication key instead.
 #swift_store_key = <None>
+{% if server.storage.swift.store.key is defined %}
 swift_store_key = {{ server.storage.swift.store.key }}
+{% endif %}
 
 #
 # Absolute path to the file containing the swift account(s)
@@ -3103,8 +3117,8 @@
 #
 #  (string value)
 #swift_store_config_file = <None>
-{% if server.storage.swift.store.config_file is defined %}
-swift_store_config_file = {{ server.storage.swift.store.config_file }}
+{% if server.storage.swift.store.references is defined %}
+swift_store_config_file = /etc/glance/swift-stores.conf
 {% endif %}
 
 {% endif %}
@@ -4270,6 +4284,9 @@
 #
 #  (list value)
 #store_type_preference =
+{% if server.get('location_strategy', 'location_order') == 'store_type' and server.store_type_preference is defined %}
+store_type_preference = {{ server.store_type_preference }}
+{% endif %}
 
 
 [task]
diff --git a/glance/files/ocata/glance-api.conf.Debian b/glance/files/ocata/glance-api.conf.Debian
index c7ed5c9..8b3f40d 100644
--- a/glance/files/ocata/glance-api.conf.Debian
+++ b/glance/files/ocata/glance-api.conf.Debian
@@ -330,6 +330,7 @@
 # functionality can be achieved with greater granularity by using policies.
 # Please see the Newton release notes for more information.
 #show_multiple_locations = false
+show_multiple_locations = {{ server.get('show_multiple_locations', False) | lower }}
 
 #
 # Maximum size of image a user can upload in bytes.
@@ -602,6 +603,11 @@
 #  (string value)
 # Allowed values: location_order, store_type
 #location_strategy = location_order
+{% if server.get('location_strategy', 'location_order') == 'location_order' %}
+location_strategy = location_order
+{% else %}
+location_strategy = store_type
+{% endif %}
 
 #
 # The location of the property protection file.
@@ -2670,7 +2676,7 @@
 #  (boolean value)
 {%- if 'swift' in storage_engines %}
 #swift_store_auth_insecure = false
-swift_store_auth_insecure = {{ server.storage.swift.store.auth.get('insecure', False)|lower }}
+swift_store_auth_insecure = {{ server.storage.swift.store.get('auth', {}).get('insecure', False)|lower }}
 
 #
 # Path to the CA bundle file.
@@ -3118,7 +3124,9 @@
 # The option 'auth_version' in the Swift back-end configuration file is
 # used instead.
 #swift_store_auth_version = 2
+{% if server.storage.swift.store.get('auth', {}).get('version', False) %}
 swift_store_auth_version = {{ server.storage.swift.store.auth.version }}
+{% endif %}
 
 # DEPRECATED: The address where the Swift authentication service is listening.
 # (string value)
@@ -3128,7 +3136,9 @@
 # The option 'auth_address' in the Swift back-end configuration file is
 # used instead.
 #swift_store_auth_address = <None>
+{% if server.storage.swift.store.get('auth', {}).get('address', False) %}
 swift_store_auth_address = {{ server.storage.swift.store.auth.address }}
+{% endif %}
 
 # DEPRECATED: The user to authenticate against the Swift authentication service.
 # (string value)
@@ -3137,7 +3147,9 @@
 # Reason:
 # The option 'user' in the Swift back-end configuration file is set instead.
 #swift_store_user = <None>
+{% if server.storage.swift.store.user is defined %}
 swift_store_user = {{ server.storage.swift.store.user }}
+{% endif %}
 
 # DEPRECATED: Auth key for the user authenticating against the Swift
 # authentication service. (string value)
@@ -3147,7 +3159,9 @@
 # The option 'key' in the Swift back-end configuration file is used
 # to set the authentication key instead.
 #swift_store_key = <None>
+{% if server.storage.swift.store.key is defined %}
 swift_store_key = {{ server.storage.swift.store.key }}
+{% endif %}
 
 #
 # Absolute path to the file containing the swift account(s)
@@ -3169,8 +3183,8 @@
 #
 #  (string value)
 #swift_store_config_file = <None>
-{% if server.storage.swift.store.config_file is defined %}
-swift_store_config_file = {{ server.storage.swift.store.config_file }}
+{% if server.storage.swift.store.references is defined %}
+swift_store_config_file = /etc/glance/swift-stores.conf
 {% endif %}
 
 {% endif %}
@@ -4336,6 +4350,9 @@
 #
 #  (list value)
 #store_type_preference =
+{% if server.get('location_strategy', 'location_order') == 'store_type' and server.store_type_preference is defined %}
+store_type_preference = {{ server.store_type_preference }}
+{% endif %}
 
 
 [task]
diff --git a/glance/server.sls b/glance/server.sls
index 03408e0..b9f7bc9 100644
--- a/glance/server.sls
+++ b/glance/server.sls
@@ -98,6 +98,17 @@
 {%- endif %}
 {%- endif %}
 
+{% if server.storage.get('swift', {}).get('store', {}).get('references', {}) %}
+/etc/glance/swift-stores.conf:
+  file.managed:
+  - source: salt://glance/files/_backends/_swift.conf
+  - template: jinja
+  - require:
+    - pkg: glance_packages
+  - watch_in:
+    - service: glance_services
+{% endif %}
+
 {%- if not grains.get('noservices', False) %}
 
 glance_services:
diff --git a/tests/pillar/single_multiple_backends.sls b/tests/pillar/single_multiple_backends.sls
new file mode 100644
index 0000000..4a9d6a2
--- /dev/null
+++ b/tests/pillar/single_multiple_backends.sls
@@ -0,0 +1,70 @@
+glance:
+  server:
+    enabled: true
+    version: mitaka
+    workers: 1
+    show_multiple_locations: True
+    location_strategy: store_type
+    store_type_preference: rbd,swift
+    database:
+      engine: mysql
+      host: localhost
+      port: 3306
+      name: glance
+      user: glance
+      password: password
+    registry:
+      host: 127.0.0.1
+      port: 9191
+    bind:
+      address: 127.0.0.1
+      port: 9292
+    identity:
+      engine: keystone
+      host: 127.0.0.1
+      port: 35357
+      user: glance
+      password: password
+      region: RegionOne
+      tenant: service
+      endpoint_type: internalURL
+    message_queue:
+      engine: rabbitmq
+      host: 127.0.0.1
+      port: 5672
+      user: openstack
+      password: password
+      virtual_host: '/openstack'
+    storage:
+      engine: swift,rbd,http
+      # Rbd configuration
+      user: glance
+      pool: glance-images
+      chunk_size: 8
+      client_glance_key: AQAqcXhWk+3UARAAGmV4USB6I7wLJ/W+dVbUWw==
+      # Swift configuration
+      swift:
+        store:
+          # admin_tenants:
+          auth:
+            address: http://127.0.0.1:5000/v2.0
+            insecure: false
+            version: 2
+          cacert: /etc/ssl/certs/ca-certificates.crt
+          # config_file:
+          container: glance
+          create_container_on_put: true
+          endpoint: swift
+          endpoint_type: internalURL
+          expire_soon_interval: 60
+          key: someRandomPassword
+          large_object_size: 5120
+          large_object_chunk_size: 200
+          multi_tenant: false
+          multiple_containers_seed: 0
+          retry_get_count: 5
+          region: RegionOne
+          service_type: object-store
+          ssl_compression: false
+          use_trusts: false
+          user: 2ec7966596504f59acc3a76b3b9d9291:glance-project
diff --git a/tests/pillar/single_swift.sls b/tests/pillar/single_swift.sls
index 97d4fdd..4fb6629 100644
--- a/tests/pillar/single_swift.sls
+++ b/tests/pillar/single_swift.sls
@@ -1,7 +1,7 @@
 glance:
   server:
     enabled: true
-    version: liberty
+    version: mitaka
     workers: 1
     database:
       engine: mysql
diff --git a/tests/pillar/single_swift_references.sls b/tests/pillar/single_swift_references.sls
new file mode 100644
index 0000000..dcb4385
--- /dev/null
+++ b/tests/pillar/single_swift_references.sls
@@ -0,0 +1,69 @@
+glance:
+  server:
+    enabled: true
+    version: mitaka
+    workers: 1
+    database:
+      engine: mysql
+      host: localhost
+      port: 3306
+      name: glance
+      user: glance
+      password: password
+    registry:
+      host: 127.0.0.1
+      port: 9191
+    bind:
+      address: 127.0.0.1
+      port: 9292
+    identity:
+      engine: keystone
+      host: 127.0.0.1
+      port: 35357
+      user: glance
+      password: password
+      region: RegionOne
+      tenant: service
+      endpoint_type: internalURL
+    message_queue:
+      engine: rabbitmq
+      host: 127.0.0.1
+      port: 5672
+      user: openstack
+      password: password
+      virtual_host: '/openstack'
+    storage:
+      engine: swift
+      swift:
+        store:
+          # admin_tenants: 
+          cacert: /etc/ssl/certs/ca-certificates.crt
+          # config_file: 
+          container: glance
+          create_container_on_put: true
+          endpoint: swift
+          endpoint_type: internalURL
+          expire_soon_interval: 60
+          large_object_size: 5120
+          large_object_chunk_size: 200
+          multi_tenant: false
+          multiple_containers_seed: 0
+          retry_get_count: 5
+          region: RegionOne
+          service_type: object-store
+          ssl_compression: false
+          use_trusts: false
+          default_swift_reference: my_swift_server
+          references:
+            my_swift_server:
+              auth:
+                address: http://127.0.0.1:5000/v2.0
+                version: 2
+              user: 2ec7966596504f59acc3a76b3b9d9291:glance-user
+              key: someRandomPassword
+            my_second_swift_server:
+              auth:
+                address: http://127.0.0.2:5000/v2.0
+                version: 2
+              user: 2ec7966596504f59acc3a76b3b9d9291:glance-user
+              key: someRandomPassword