[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#859638: unblock: horizon/10.0.1-1 (CVE-2017-7400)



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Dear release team,
Please unblock package horizon,

The attached debdiff is bigger than usual during the freeze, so let me
explain the motivation behind it.

My last upload is upgrading the package to upstream version 1.0.1, which
contains mostly:
- move of the "developer" panel to the contrib folder, meaning it will be
not activated by default, which I believe is very important for security
reasons.
- A lot of upstream translation updates. I believe the release team is OK
with this type of change at this point of the release (let me know if not).

As the upstream translation files (ie: the .po files) from upstream are
big, I have stripped them out of the attached debdiff, so it's 51KB
instead of more than 400KB. I also thought that changes on .po files
aren't useful to discuss such unblock. Despite the size of the stripped
diff, the changes from upstream are reasonable: fix in some .js files for
the search field and the ssh keypair creation, a quick fix for the
Keystone API v3 (that's the only "big" Python code change, which is a few
lines only), and some Django template changes. It is my view that this
point release is not changing much.

FYI, the upstream release notes are here:
https://docs.openstack.org/releasenotes/horizon/newton.html

If the release team is ok with it, I could also package and upload
version 10.0.3 and get it to Stretch too, though I haven't processed it
yet.

Also, my upload includes:
- CVE-2017-7400 fix (that's nearly a one liner from upstream, though it
fixes a grave XSS problem).
- Italian translation of debconf messages.

The CVE-2017-7400 fix is the main motivation behind this unblock. At
this point, it would be hard to get our Git revert to upstream 10.0.0,
unfortunately (we use Gerrit on OpenStack infra), so I really hope I
wont have to do that to fix this CVE.

Please unblock horizon/10.0.1-1,
Cheers,

Thomas Goirand (zigo)
diff -Nru horizon-10.0.0/debian/changelog horizon-10.0.1/debian/changelog
--- horizon-10.0.0/debian/changelog	2016-10-06 15:51:41.000000000 +0000
+++ horizon-10.0.1/debian/changelog	2017-04-04 21:47:20.000000000 +0000
@@ -1,3 +1,21 @@
+horizon (3:10.0.1-1) unstable; urgency=high
+
+  [ Ivan Udovichenko ]
+  * Sync to the latest version from stable/newton.
+
+  [ Thomas Goirand ]
+  * CVE-2017-7400: XSS in federation mappings UI. Applied upstream patch:
+    Remove dangerous safestring declaration (Closes: #859559).
+  * Updated Italian translation of debconf messages (Closes: #846931).
+
+ -- Thomas Goirand <zigo@debian.org>  Tue, 04 Apr 2017 23:47:20 +0200
+
+horizon (3:10.0.0-2) unstable; urgency=medium
+
+  * Added missing path in debian/openstack-dashboard.triggers.
+
+ -- Thomas Goirand <zigo@debian.org>  Fri, 14 Oct 2016 17:35:09 +0200
+
 horizon (3:10.0.0-1) unstable; urgency=medium
 
   * New upstream release.
diff -Nru horizon-10.0.0/debian/control horizon-10.0.1/debian/control
--- horizon-10.0.0/debian/control	2016-10-06 15:51:41.000000000 +0000
+++ horizon-10.0.1/debian/control	2017-04-04 21:47:20.000000000 +0000
@@ -17,10 +17,10 @@
                      python-babel (>= 2.3.4),
                      python-ceilometerclient (>= 2.2.1),
                      python-cinderclient (>= 1:1.6.0),
-                     python-django-compressor (>= 2.0),
                      python-coverage,
                      python-django (>= 1.8),
                      python-django-babel (>= 0.5.1),
+                     python-django-compressor (>= 2.0),
                      python-django-nose (>= 1.4.3),
                      python-django-openstack-auth (>= 2.4.0),
                      python-django-pyscss (>= 2.0.2),
@@ -96,9 +96,9 @@
 Depends: python-babel (>= 2.3.4),
          python-ceilometerclient (>= 2.2.1),
          python-cinderclient (>= 1:1.6.0),
-         python-django-compressor (>= 2.0),
          python-django (>= 1.8),
          python-django-babel (>= 0.5.1),
+         python-django-compressor (>= 2.0),
          python-django-openstack-auth (>= 2.4.0),
          python-django-pyscss (>= 2.0.2),
          python-glanceclient (>= 1:2.3.0),
diff -Nru horizon-10.0.0/debian/openstack-dashboard.triggers horizon-10.0.1/debian/openstack-dashboard.triggers
--- horizon-10.0.0/debian/openstack-dashboard.triggers	2016-10-06 15:51:41.000000000 +0000
+++ horizon-10.0.1/debian/openstack-dashboard.triggers	2017-04-04 21:47:20.000000000 +0000
@@ -16,3 +16,5 @@
 interest-noawait /usr/share/twitter-bootstrap/files
 interest-noawait /usr/share/javascript/term.js
 interest-noawait /usr/share/javascript/lrDragNDrop
+interest-noawait /usr/share/javascript/tv4
+interest-noawait /usr/share/javascript/objectpath
diff -Nru horizon-10.0.0/debian/patches/CVE-2017-7400_Remove_dangerous_safestring_declaration.patch horizon-10.0.1/debian/patches/CVE-2017-7400_Remove_dangerous_safestring_declaration.patch
--- horizon-10.0.0/debian/patches/CVE-2017-7400_Remove_dangerous_safestring_declaration.patch	1970-01-01 00:00:00.000000000 +0000
+++ horizon-10.0.1/debian/patches/CVE-2017-7400_Remove_dangerous_safestring_declaration.patch	2017-04-04 21:47:20.000000000 +0000
@@ -0,0 +1,34 @@
+Description: CVE-2017-7400: Remove dangerous safestring declaration
+From: Richard Jones <r1chardj0n3s@gmail.com>
+Date: Tue, 7 Mar 2017 05:55:39 +0000 (+1100)
+X-Git-Tag: 10.0.3^2
+X-Git-Url: https://review.openstack.org/gitweb?p=openstack%2Fhorizon.git;a=commitdiff_plain;h=511b325b45b6bd7a88bb6df1a4639b80d0121277
+ This declaration allows XSS content through the JSON and
+ is unnecessary for correct rendering of the content anyway.
+Change-Id: I82355b37108609ae573237424e528aab86a24efc
+Bug-Ubuntu: https://bugs.launchpad.net/horizon/+bug/1667086
+Bug-Debian: https://bugs.debian.org/859559
+Origin: https://review.openstack.org/#/c/442454/
+Last-Update: 2017-04-04
+
+diff --git a/openstack_dashboard/dashboards/identity/mappings/tables.py b/openstack_dashboard/dashboards/identity/mappings/tables.py
+index df6e8f3..9c22285 100644
+--- a/openstack_dashboard/dashboards/identity/mappings/tables.py
++++ b/openstack_dashboard/dashboards/identity/mappings/tables.py
+@@ -14,7 +14,6 @@
+ 
+ import json
+ 
+-from django.utils import safestring
+ from django.utils.translation import ugettext_lazy as _
+ from django.utils.translation import ungettext_lazy
+ 
+@@ -75,7 +74,7 @@ def get_rules_as_json(mapping):
+     rules = getattr(mapping, 'rules', None)
+     if rules:
+         rules = json.dumps(rules, indent=4)
+-    return safestring.mark_safe(rules)
++    return rules
+ 
+ 
+ class MappingsTable(tables.DataTable):
diff -Nru horizon-10.0.0/debian/patches/series horizon-10.0.1/debian/patches/series
--- horizon-10.0.0/debian/patches/series	2016-10-06 15:51:41.000000000 +0000
+++ horizon-10.0.1/debian/patches/series	2017-04-04 21:47:20.000000000 +0000
@@ -2,3 +2,4 @@
 fix-dashboard-manage.patch
 fixed-horizon-MANIFEST.in.patch
 stores-SECRET_KEY-in-tmp-folder-for-tests.patch
+CVE-2017-7400_Remove_dangerous_safestring_declaration.patch
diff -Nru horizon-10.0.0/debian/po/it.po horizon-10.0.1/debian/po/it.po
--- horizon-10.0.0/debian/po/it.po	2016-10-06 15:51:41.000000000 +0000
+++ horizon-10.0.1/debian/po/it.po	2017-04-04 21:47:20.000000000 +0000
@@ -1,13 +1,13 @@
 # Italian translation of horizon's debconf messages.
-# Copyright (C) 2013, horizon package copyright holder
+# Copyright (C) 2016, horizon package copyright holder
 # This file is distributed under the same license as the horizon package.
-# Beatrice Torracca <beatricet@libero.it>, 2013.
+# Beatrice Torracca <beatricet@libero.it>, 2013, 2016.
 msgid ""
 msgstr ""
 "Project-Id-Version: horizon\n"
 "Report-Msgid-Bugs-To: horizon@packages.debian.org\n"
 "POT-Creation-Date: 2015-09-22 13:31+0000\n"
-"PO-Revision-Date: 2013-10-19 18:48+0200\n"
+"PO-Revision-Date: 2016-08-01 17:05+0200\n"
 "Last-Translator: Beatrice Torracca <beatricet@libero.it>\n"
 "Language-Team: Italian <debian-l10n-italian@lists.debian.org>\n"
 "Language: it\n"
@@ -40,6 +40,8 @@
 "If this option is not selected, Horizon will be installed using /horizon "
 "instead of the webroot."
 msgstr ""
+"Se questa opzione non viene selezionata Horizon verrà installato usando /"
+"horizon invece di webroot."
 
 #. Type: boolean
 #. Description
diff -Nru horizon-10.0.0/doc/source/topics/policy.rst horizon-10.0.1/doc/source/topics/policy.rst
--- horizon-10.0.0/doc/source/topics/policy.rst	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/doc/source/topics/policy.rst	2016-11-02 07:50:09.000000000 +0000
@@ -66,7 +66,8 @@
 Default: ``policy.check``
 
 This value should not be changed, although removing it would be a means to
-bypass all policy checks.
+bypass all policy checks. Set it to ``None`` in ``local_settings.py`` to
+do this.
 
 
 How user's roles are determined
diff -Nru horizon-10.0.0/horizon/static/framework/widgets/magic-search/magic-search.controller.js horizon-10.0.1/horizon/static/framework/widgets/magic-search/magic-search.controller.js
--- horizon-10.0.0/horizon/static/framework/widgets/magic-search/magic-search.controller.js	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/horizon/static/framework/widgets/magic-search/magic-search.controller.js	2016-11-02 07:50:09.000000000 +0000
@@ -269,6 +269,12 @@
         ctrl.filteredOptions = ctrl.facetOptions = facet.options;
         setMenuOpen(true);
       }
+      var searchVal = searchInput.val();
+      if (searchVal) {
+        ctrl.currentSearch = ctrl.currentSearch.filter(notTextSearch);
+        ctrl.currentSearch.push(service.getTextFacet(searchVal, $scope.strings.text));
+        ctrl.textSearch = searchVal;
+      }
       setSearchInput('');
       setPrompt('');
       $timeout(function() {
@@ -310,13 +316,12 @@
     }
 
     function clearSearch() {
-      if (ctrl.currentSearch.length > 0) {
-        ctrl.currentSearch = [];
-        ctrl.unusedFacetChoices = ctrl.facetChoices.map(service.getFacetChoice);
-        resetState();
-        $scope.$emit(magicSearchEvents.SEARCH_UPDATED, '');
-        emitTextSearch('');
-      }
+      ctrl.currentSearch = [];
+      delete ctrl.textSearch;
+      ctrl.unusedFacetChoices = ctrl.facetChoices.map(service.getFacetChoice);
+      resetState();
+      $scope.$emit(magicSearchEvents.SEARCH_UPDATED, '');
+      emitTextSearch('');
     }
 
     function resetState() {
diff -Nru horizon-10.0.0/horizon/static/framework/widgets/magic-search/magic-search.controller.spec.js horizon-10.0.1/horizon/static/framework/widgets/magic-search/magic-search.controller.spec.js
--- horizon-10.0.0/horizon/static/framework/widgets/magic-search/magic-search.controller.spec.js	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/horizon/static/framework/widgets/magic-search/magic-search.controller.spec.js	2016-11-02 07:50:09.000000000 +0000
@@ -125,13 +125,6 @@
 
     describe("clearSearch", function() {
 
-      it("does nothing when currentSearch is empty", function() {
-        spyOn(scope, '$emit');
-        ctrl.currentSearch = [];
-        ctrl.clearSearch();
-        expect(scope.$emit).not.toHaveBeenCalled();
-      });
-
       it("clears the currentSearch when currentSearch is not empty", function() {
         spyOn(scope, '$emit');
         ctrl.currentSearch = ['a', 'b', 'c'];
diff -Nru horizon-10.0.0/horizon/static/framework/widgets/magic-search/magic-search.html horizon-10.0.1/horizon/static/framework/widgets/magic-search/magic-search.html
--- horizon-10.0.0/horizon/static/framework/widgets/magic-search/magic-search.html	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/horizon/static/framework/widgets/magic-search/magic-search.html	2016-11-02 07:50:09.000000000 +0000
@@ -45,7 +45,7 @@
         </ul>
       </span>
     </span>
-    <a class="magic-search-clear" ng-click="ctrl.clearSearch()" ng-show="ctrl.currentSearch.length &gt; 0" title="{$ ::strings.cancel $}">
+    <a class="magic-search-clear" ng-click="ctrl.clearSearch()" title="{$ ::strings.cancel $}">
       <span class="fi-x fa fa-times cancel"></span>
     </a>
   </div>
diff -Nru horizon-10.0.0/horizon/static/framework/widgets/table/hz-detail-row.html horizon-10.0.1/horizon/static/framework/widgets/table/hz-detail-row.html
--- horizon-10.0.0/horizon/static/framework/widgets/table/hz-detail-row.html	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/horizon/static/framework/widgets/table/hz-detail-row.html	2016-11-02 07:50:09.000000000 +0000
@@ -11,8 +11,8 @@
 <div class="row">
   <span class="rsp-alt-p2">
     <dl class="col-sm-2" ng-repeat="column in config.columns">
-      <dt translate>{$ column.title $}</dt>
-      <dd translate><hz-cell table="table" column="column" item="item"></hz-cell></dd>
+      <dt>{$ column.title $}</dt>
+      <dd><hz-cell table="table" column="column" item="item"></hz-cell></dd>
     </dl>
   </span>
 </div>
diff -Nru horizon-10.0.0/horizon/templates/horizon/common/_form_errors.html horizon-10.0.1/horizon/templates/horizon/common/_form_errors.html
--- horizon-10.0.0/horizon/templates/horizon/common/_form_errors.html	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/horizon/templates/horizon/common/_form_errors.html	2016-11-02 07:50:09.000000000 +0000
@@ -8,6 +8,8 @@
 {% endif %}
 {% if form.non_field_errors %}
   <div class="alert alert-danger">
-    {{ form.non_field_errors }}
+    {% for err in form.non_field_errors %}
+      <p>{{ err }}</p>
+    {% endfor %}
   </div>
 {% endif %}
diff -Nru horizon-10.0.0/horizon/templates/horizon/common/_usage_summary.html horizon-10.0.1/horizon/templates/horizon/common/_usage_summary.html
--- horizon-10.0.0/horizon/templates/horizon/common/_usage_summary.html	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/horizon/templates/horizon/common/_usage_summary.html	2016-11-02 07:50:09.000000000 +0000
@@ -14,7 +14,7 @@
       <label>To:</label>{{ end }}{% endblocktrans %}
     </div>
     <button class="btn btn-primary" type="submit">{% trans "Submit" %}</button>
-    <small>{% trans "The date should be in YYYY-mm-dd format." %}</small>
+    <small>{% trans "The date should be in YYYY-MM-DD format." %}</small>
   </form>
   <p id="activity">
     <span><strong>{% trans "Active Instances:" %}</strong> {{ usage.summary.instances|default:'0' }}</span>
diff -Nru horizon-10.0.0/horizon/templates/horizon/common/_workflow_step_update_members.html horizon-10.0.1/horizon/templates/horizon/common/_workflow_step_update_members.html
--- horizon-10.0.0/horizon/templates/horizon/common/_workflow_step_update_members.html	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/horizon/templates/horizon/common/_workflow_step_update_members.html	2016-11-02 07:50:09.000000000 +0000
@@ -32,14 +32,14 @@
     <div class="col-xs-6 filterable {{ step.slug }}_filterable">
       <div class="fake_table fake_{{ step.slug }}_table" id="available_{{ step.slug }}">
         <ul class="available_members available_{{ step.slug }}"></ul>
-        <ul class="no_results" id="no_available_{{ step.slug }}"><li>{{ step.no_available_text }}</li></ul>
+        <ul class="no_results nav nav-pills" id="no_available_{{ step.slug }}"><li>{{ step.no_available_text }}</li></ul>
       </div>
     </div>
 
     <div class="col-xs-6 filterable {{ step.slug }}_filterable">
       <div class="fake_table fake_{{ step.slug }}_table" id="{{ step.slug }}_members">
         <ul class="members {{ step.slug }}_members"></ul>
-        <ul class="no_results" id="no_{{ step.slug }}_members"><li>{{ step.no_members_text }}</li></ul>
+        <ul class="no_results nav nav-pills" id="no_{{ step.slug }}_members"><li>{{ step.no_members_text }}</li></ul>
       </div>
     </div>
   </div>
diff -Nru horizon-10.0.0/openstack_dashboard/api/rest/swift.py horizon-10.0.1/openstack_dashboard/api/rest/swift.py
--- horizon-10.0.0/openstack_dashboard/api/rest/swift.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/api/rest/swift.py	2016-11-02 07:50:09.000000000 +0000
@@ -17,6 +17,7 @@
 
 from django import forms
 from django.http import StreamingHttpResponse
+from django.utils.http import urlunquote
 from django.views.decorators.csrf import csrf_exempt
 from django.views import generic
 import six
@@ -120,6 +121,8 @@
         :return:
         """
         path = request.GET.get('path')
+        if path is not None:
+            path = urlunquote(path)
 
         objects = api.swift.swift_get_objects(
             request,
diff -Nru horizon-10.0.0/openstack_dashboard/contrib/developer/dashboard.py horizon-10.0.1/openstack_dashboard/contrib/developer/dashboard.py
--- horizon-10.0.0/openstack_dashboard/contrib/developer/dashboard.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/contrib/developer/dashboard.py	2016-11-02 07:50:09.000000000 +0000
@@ -12,6 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from django.conf import settings
 from django.utils.translation import ugettext_lazy as _
 
 import horizon
@@ -23,4 +24,5 @@
     default_panel = "theme_preview"
 
 
-horizon.register(Developer)
+if getattr(settings, 'DEBUG', False):
+    horizon.register(Developer)
diff -Nru horizon-10.0.0/openstack_dashboard/contrib/developer/enabled/_9001_developer.py horizon-10.0.1/openstack_dashboard/contrib/developer/enabled/_9001_developer.py
--- horizon-10.0.0/openstack_dashboard/contrib/developer/enabled/_9001_developer.py	1970-01-01 00:00:00.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/contrib/developer/enabled/_9001_developer.py	2016-11-02 07:50:09.000000000 +0000
@@ -0,0 +1,29 @@
+# Copyright 2015 Cisco Systems, Inc.
+#
+# 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.
+
+DASHBOARD = 'developer'
+
+ADD_ANGULAR_MODULES = [
+    'horizon.dashboard.developer'
+]
+
+ADD_INSTALLED_APPS = [
+    'openstack_dashboard.contrib.developer'
+]
+
+ADD_SCSS_FILES = [
+    'dashboard/developer/developer.scss',
+]
+
+AUTO_DISCOVER_STATIC_FILES = True
diff -Nru horizon-10.0.0/openstack_dashboard/contrib/developer/enabled/_9010_preview.py horizon-10.0.1/openstack_dashboard/contrib/developer/enabled/_9010_preview.py
--- horizon-10.0.0/openstack_dashboard/contrib/developer/enabled/_9010_preview.py	1970-01-01 00:00:00.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/contrib/developer/enabled/_9010_preview.py	2016-11-02 07:50:09.000000000 +0000
@@ -0,0 +1,21 @@
+# Copyright 2015 Cisco Systems, Inc.
+#
+# 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.
+
+
+PANEL = 'theme_preview'
+PANEL_GROUP = 'default'
+PANEL_DASHBOARD = 'developer'
+
+ADD_PANEL = \
+    'openstack_dashboard.contrib.developer.theme_preview.panel.Preview'
diff -Nru horizon-10.0.0/openstack_dashboard/contrib/developer/enabled/_9020_resource_browser.py horizon-10.0.1/openstack_dashboard/contrib/developer/enabled/_9020_resource_browser.py
--- horizon-10.0.0/openstack_dashboard/contrib/developer/enabled/_9020_resource_browser.py	1970-01-01 00:00:00.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/contrib/developer/enabled/_9020_resource_browser.py	2016-11-02 07:50:09.000000000 +0000
@@ -0,0 +1,20 @@
+# (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
+#
+# 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.
+
+
+PANEL = 'resource_browser'
+PANEL_GROUP = 'default'
+PANEL_DASHBOARD = 'developer'
+
+ADD_PANEL = 'openstack_dashboard.contrib.developer.resource_browser.panel.ResourceBrowser'  # noqa
diff -Nru horizon-10.0.0/openstack_dashboard/contrib/developer/static/dashboard/developer/resource-browser/resource-browser-item.controller.js horizon-10.0.1/openstack_dashboard/contrib/developer/static/dashboard/developer/resource-browser/resource-browser-item.controller.js
--- horizon-10.0.0/openstack_dashboard/contrib/developer/static/dashboard/developer/resource-browser/resource-browser-item.controller.js	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/contrib/developer/static/dashboard/developer/resource-browser/resource-browser-item.controller.js	2016-11-02 07:50:09.000000000 +0000
@@ -214,7 +214,8 @@
       }
 
       function loadFailed(reason) {
-        toastService.add('error', gettext("resource load failed: " + reason));
+        var msg = interpolate(gettext("resource load failed: %s"), [reason]);
+        toastService.add('error', msg);
       }
     }
   }
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/admin/images/panel.py horizon-10.0.1/openstack_dashboard/dashboards/admin/images/panel.py
--- horizon-10.0.0/openstack_dashboard/dashboards/admin/images/panel.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/admin/images/panel.py	2016-11-02 07:50:09.000000000 +0000
@@ -25,3 +25,4 @@
     name = _("Images")
     slug = 'images'
     permissions = ('openstack.services.image',)
+    policy_rules = (("image", "get_images"),)
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/identity/projects/tables.py horizon-10.0.1/openstack_dashboard/dashboards/identity/projects/tables.py
--- horizon-10.0.0/openstack_dashboard/dashboards/identity/projects/tables.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/identity/projects/tables.py	2016-11-02 07:50:09.000000000 +0000
@@ -226,22 +226,17 @@
                                     widget=forms.Textarea(attrs={'rows': 4}),
                                     required=False))
     id = tables.Column('id', verbose_name=_('Project ID'))
+
+    if api.keystone.VERSIONS.active >= 3:
+        domain_name = tables.Column(
+            'domain_name', verbose_name=_('Domain Name'))
+
     enabled = tables.Column('enabled', verbose_name=_('Enabled'), status=True,
                             filters=(filters.yesno, filters.capfirst),
                             form_field=forms.BooleanField(
                                 label=_('Enabled'),
                                 required=False))
 
-    if api.keystone.VERSIONS.active >= 3:
-        domain_name = tables.Column(
-            'domain_name', verbose_name=_('Domain Name'))
-        enabled = tables.Column('enabled', verbose_name=_('Enabled'),
-                                status=True,
-                                filters=(filters.yesno, filters.capfirst),
-                                form_field=forms.BooleanField(
-                                    label=_('Enabled'),
-                                    required=False))
-
     def get_project_detail_link(self, project):
         # this method is an ugly monkey patch, needed because
         # the column link method does not provide access to the request
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/openrc_v2.sh.template horizon-10.0.1/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/openrc_v2.sh.template
--- horizon-10.0.0/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/openrc_v2.sh.template	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/openrc_v2.sh.template	2016-11-02 07:50:09.000000000 +0000
@@ -22,6 +22,7 @@
 unset OS_PROJECT_ID
 unset OS_PROJECT_NAME
 unset OS_USER_DOMAIN_NAME
+unset OS_INTERFACE
 
 # In addition to the owning entity (tenant), OpenStack stores the entity
 # performing the action as the **user**.
@@ -39,5 +40,4 @@
 if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
 
 export OS_ENDPOINT_TYPE={{ os_endpoint_type }}
-export OS_INTERFACE={{ interface }}
 export OS_IDENTITY_API_VERSION={{ os_identity_api_version }}
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/images/panel.py horizon-10.0.1/openstack_dashboard/dashboards/project/images/panel.py
--- horizon-10.0.0/openstack_dashboard/dashboards/project/images/panel.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/images/panel.py	2016-11-02 07:50:09.000000000 +0000
@@ -22,3 +22,4 @@
     name = _("Images")
     slug = 'images'
     permissions = ('openstack.services.image',)
+    policy_rules = (('image', 'get_images'),)
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/instances/templates/instances/serial_console.html horizon-10.0.1/openstack_dashboard/dashboards/project/instances/templates/instances/serial_console.html
--- horizon-10.0.0/openstack_dashboard/dashboards/project/instances/templates/instances/serial_console.html	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/instances/templates/instances/serial_console.html	2016-11-02 07:50:09.000000000 +0000
@@ -7,7 +7,7 @@
   <title>{{instance_name}} ({{instance_id}})</title>
   <link rel="stylesheet" href="{{ STATIC_URL }}dashboard/scss/serial_console.css" type="text/css" media="screen">
   <script src="{% url 'horizon:jsi18n' 'horizon' %}"></script>
-  <script src='{{ STATIC_URL }}horizon/lib/term.js'></script>
+  <script src='{{ STATIC_URL }}horizon/lib/termjs/term.js'></script>
   <script src="{{ STATIC_URL }}horizon/lib/jquery/jquery.js"></script>
   <script src="{{ STATIC_URL }}horizon/lib/angular/angular.js"></script>
   <script src="{{ STATIC_URL }}horizon/js/angular/directives/serialConsole.js"></script>
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/loadbalancers/tables.py horizon-10.0.1/openstack_dashboard/dashboards/project/loadbalancers/tables.py
--- horizon-10.0.0/openstack_dashboard/dashboards/project/loadbalancers/tables.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/loadbalancers/tables.py	2016-11-02 07:50:09.000000000 +0000
@@ -366,7 +366,7 @@
                                                      vip_fips[0].id)
                 messages.success(request,
                                  _("Successfully disassociated "
-                                   "floating IP: %s") % fip.ip)
+                                   "floating IP: %s") % vip_fips[0].ip)
         except Exception:
             exceptions.handle(request,
                               _("Unable to disassociate floating IP."))
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/_detail_overview.html horizon-10.0.1/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/_detail_overview.html
--- horizon-10.0.0/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/_detail_overview.html	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/_detail_overview.html	2016-11-02 07:50:09.000000000 +0000
@@ -10,17 +10,17 @@
     <dd>{{ subnet.network_name|default:_("None") }}</dd>
     <dt title="{% trans 'Network ID' %}">{% trans "Network ID" %}</dt>
     <dd><a href="{{ subnet.network_url }}">{{ subnet.network_id|default:_("None") }}</a></dd>
-    <dt title="{% trans 'Subnetpool' %}">{% trans "Subnetpool" %}</dt>
+    <dt title="{% trans 'Subnet Pool' %}">{% trans "Subnet Pool" %}</dt>
     {% if subnet.subnetpool_id %}
       <dd>{{ subnet.subnetpool_name }} ({{ subnet.subnetpool_id }})</dd>
     {% else %}
       <dd>{% trans "None" %}</dd>
     {% endif %}
-    <dt title="{% trans 'IP version' %}">{% trans "IP version" %}</dt>
+    <dt title="{% trans 'IP Version' %}">{% trans "IP Version" %}</dt>
     <dd>{{ subnet.ipver_str|default:_("-") }}</dd>
     <dt title="{% trans 'CIDR' %}">{% trans "CIDR" %}</dt>
     <dd>{{ subnet.cidr|default:_("None") }}</dd>
-    <dt title="{% trans 'IP allocation pool' %}">{% trans "IP allocation pool" %}</dt>
+    <dt title="{% trans 'IP Allocation Pools' %}">{% trans "IP Allocation Pools" %}</dt>
     <dd>
       {% for pool in subnet.allocation_pools %}
         {% trans "Start" %}  {{ pool.start }}
@@ -29,10 +29,10 @@
     </dd>
     <dt title="{% trans 'Gateway IP' %}">{% trans "Gateway IP" %}</dt>
     <dd>{{ subnet.gateway_ip|default:_("-") }}</dd>
-    <dt title="{% trans 'DHCP Enable' %}">{% trans "DHCP Enable" %}<dt>
+    <dt title="{% trans 'DHCP Enabled' %}">{% trans "DHCP Enabled" %}</dt>
     <dd>{{ subnet.enable_dhcp|yesno|capfirst }}</dd>
     {% if subnet.ip_version == 6 %}
-      <dt title="{% trans 'IPv6 Address Configuration Mode' %}">{% trans "IPv6 Address Configuration Mode" %}<dt>
+      <dt title="{% trans 'IPv6 Address Configuration Mode' %}">{% trans "IPv6 Address Configuration Mode" %}</dt>
       {% if subnet.ipv6_modes_desc %}
         <dd>{{ subnet.ipv6_modes_desc }}</dd>
       {% else %}
@@ -41,7 +41,7 @@
         {% endblocktrans %}</dd>
       {% endif %}
     {% endif %}
-    <dt title="{% trans 'Additional routes' %}">{% trans "Additional routes" %}</dt>
+    <dt title="{% trans 'Additional Routes' %}">{% trans "Additional Routes" %}</dt>
     <dd>
       {% for route in subnet.host_routes %}
         {% trans "Destination" %} {{ route.destination }}
@@ -50,7 +50,7 @@
         {% trans "None" %}
       {% endfor %}
     </dd>
-    <dt title="{% trans 'DNS name server' %}">{% trans "DNS name server" %}</dt>
+    <dt title="{% trans 'DNS Name Servers' %}">{% trans "DNS Name Servers" %}</dt>
     <dd>
       {% for dns in subnet.dns_nameservers %}
         {{ dns }}
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/network_topology/tests.py horizon-10.0.1/openstack_dashboard/dashboards/project/network_topology/tests.py
--- horizon-10.0.0/openstack_dashboard/dashboards/project/network_topology/tests.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/network_topology/tests.py	2016-11-02 07:50:09.000000000 +0000
@@ -161,6 +161,9 @@
                 del exp_net['url']
         self.assertEqual(expect_net_urls, data['networks'])
 
+        valid_network_ids = [net.id for net in tenant_networks]
+        if router_enable:
+            valid_network_ids = [net.id for net in self.networks.list()]
         # ports
         expect_port_urls = [
             {'id': port.id,
@@ -171,7 +174,8 @@
              'status': port.status.title(),
              'original_status': port.status,
              'url': '/project/networks/ports/%s/detail' % port.id}
-            for port in self.ports.list()]
+            for port in self.ports.list()
+            if port.network_id in valid_network_ids]
         if router_enable:
             # fake port for router1 gateway (router1 on ext_net)
             router1 = routers[0]
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/network_topology/views.py horizon-10.0.1/openstack_dashboard/dashboards/project/network_topology/views.py
--- horizon-10.0.0/openstack_dashboard/dashboards/project/network_topology/views.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/network_topology/views.py	2016-11-02 07:50:09.000000000 +0000
@@ -328,12 +328,15 @@
         self.add_resource_url('horizon:project:routers:detail', routers)
         return routers
 
-    def _get_ports(self, request):
+    def _get_ports(self, request, networks):
         try:
             neutron_ports = api.neutron.port_list(request)
         except Exception:
             neutron_ports = []
 
+        # we should filter out ports connected to non tenant networks
+        # which they have no visibility to
+        tenant_network_ids = [network['id'] for network in networks]
         ports = [{'id': port.id,
                   'network_id': port.network_id,
                   'device_id': port.device_id,
@@ -342,7 +345,8 @@
                   'status': self.trans.port[port.status],
                   'original_status': port.status}
                  for port in neutron_ports
-                 if port.device_owner != 'network:router_ha_interface']
+                 if port.device_owner != 'network:router_ha_interface'
+                 and port.network_id in tenant_network_ids]
         self.add_resource_url('horizon:project:networks:ports:detail',
                               ports)
         return ports
@@ -369,9 +373,10 @@
             ports.append(fake_port)
 
     def get(self, request, *args, **kwargs):
+        networks = self._get_networks(request)
         data = {'servers': self._get_servers(request),
-                'networks': self._get_networks(request),
-                'ports': self._get_ports(request),
+                'networks': networks,
+                'ports': self._get_ports(request, networks),
                 'routers': self._get_routers(request)}
         self._prepare_gateway_ports(data['routers'], data['ports'])
         json_string = json.dumps(data, cls=LazyTranslationEncoder,
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers.html horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers.html
--- horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers.html	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers.html	2016-11-02 07:50:09.000000000 +0000
@@ -35,7 +35,7 @@
                 <div class="progress-bar"></div>
               </div>
             </div>
-            <ul ng-if="container.is_fetched" class="hz-object-detail">
+            <ul ng-if="container.is_fetched" class="hz-object-detail list-unstyled">
               <li class="hz-object-count row">
                 <span class="hz-object-label col-lg-7 col-md-12" translate>Object Count</span>
                 <span class="hz-object-val col-lg-5 col-md-12">{$container.count$}</span>
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers-model.service.js horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers-model.service.js
--- horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers-model.service.js	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers-model.service.js	2016-11-02 07:50:09.000000000 +0000
@@ -121,7 +121,7 @@
         delimiter: model.DELIMETER
       };
       if (folder) {
-        spec.path = folder + model.DELIMETER;
+        spec.path = encodeURIComponent(folder) + model.DELIMETER;
       }
 
       return swiftAPI.getObjects(name, spec).then(function onObjects(response) {
@@ -279,7 +279,7 @@
           state.counted.folders++;
           var spec = {
             delimiter: model.DELIMETER,
-            path: item.path + model.DELIMETER
+            path: encodeURIComponent(item.path).replace(/%2F/g, '/')
           };
           return swiftAPI.getObjects(model.container.name, spec)
             .then(function objects(response) {
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers-model.service.spec.js horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers-model.service.spec.js
--- horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers-model.service.spec.js	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers-model.service.spec.js	2016-11-02 07:50:09.000000000 +0000
@@ -244,7 +244,7 @@
       beforeEach(function before() {
         spyOn(swiftAPI, 'getObjects').and.callFake(function fake(container, spec) {
           var deferred = $q.defer();
-          var items = fakeSwift[spec.path];
+          var items = fakeSwift[spec.path + '/'];
           expect(items).toBeDefined();    // sanity check
           deferred.resolve({data: {items: items}});
           return deferred.promise;
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/create-folder-modal.html horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/create-folder-modal.html
--- horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/create-folder-modal.html	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/create-folder-modal.html	2016-11-02 07:50:09.000000000 +0000
@@ -8,7 +8,7 @@
   </div>
 </div>
 
-<div ng-form="uploadForm"
+<div ng-form="uploadForm">
   <div class="modal-body">
     <div class="row">
       <div class="col-sm-6">
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/objects.controller.js horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/objects.controller.js
--- horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/containers/objects.controller.js	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/containers/objects.controller.js	2016-11-02 07:50:09.000000000 +0000
@@ -34,6 +34,7 @@
     'horizon.dashboard.project.containers.containerRoute',
     'horizon.dashboard.project.containers.objects-batch-actions',
     'horizon.dashboard.project.containers.objects-row-actions',
+    'horizon.framework.widgets.table.events',
     '$q',
     '$routeParams',
     '$scope'
@@ -43,6 +44,7 @@
                              containerRoute,
                              batchActions,
                              rowActions,
+                             hzTableEvents,
                              $q,
                              $routeParams,
                              $scope) {
@@ -129,7 +131,7 @@
         return;
       }
       if (result.deleted.length > 0) {
-        $scope.$broadcast('hzTable:clearSelected');
+        $scope.$broadcast(hzTableEvents.CLEAR_SELECTIONS);
         ctrl.model.updateContainer();
         ctrl.model.selectContainer(
           ctrl.model.container.name,
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/create-keypair.controller.js horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/create-keypair.controller.js
--- horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/create-keypair.controller.js	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/create-keypair.controller.js	2016-11-02 07:50:09.000000000 +0000
@@ -90,8 +90,8 @@
           $modalInstance.close(createdKeypair);
         },
         function error() {
-          var errorMessage = gettext('Unable to generate') + ' "' + ctrl.keypair + '". ' +
-            gettext('Please try again.');
+          var errorMessage = interpolate(gettext('Unable to generate "%s". Please try again.'),
+                                         [ctrl.keypair]);
           toastService.add('error', errorMessage);
         }
       );
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js
--- horizon-10.0.0/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js	2016-11-02 07:50:09.000000000 +0000
@@ -144,7 +144,9 @@
      * @returns {undefined} No return value
      */
     function notifyUserAndAssign(newKeypair) {
-      toastService.add('success', gettext('Created keypair: ' + newKeypair.name));
+      toastService.add('success',
+                       interpolate(gettext('Created keypair: %s'),
+                                   [newKeypair.name]));
       assignKeypair(newKeypair);
       ctrl.createdKeypair = newKeypair;
       ctrl.isKeypairCreated = true;
diff -Nru horizon-10.0.0/openstack_dashboard/dashboards/project/volumes/backups/forms.py horizon-10.0.1/openstack_dashboard/dashboards/project/volumes/backups/forms.py
--- horizon-10.0.0/openstack_dashboard/dashboards/project/volumes/backups/forms.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/dashboards/project/volumes/backups/forms.py	2016-11-02 07:50:09.000000000 +0000
@@ -42,9 +42,6 @@
     volume_id = forms.CharField(widget=forms.HiddenInput())
 
     def handle(self, request, data):
-        # Create a container for the user if no input is given
-        if not data['container_name']:
-            data['container_name'] = 'volumebackups'
 
         try:
             backup = api.cinder.volume_backup_create(request,
diff -Nru horizon-10.0.0/openstack_dashboard/enabled/_9001_developer.py horizon-10.0.1/openstack_dashboard/enabled/_9001_developer.py
--- horizon-10.0.0/openstack_dashboard/enabled/_9001_developer.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/enabled/_9001_developer.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-# Copyright 2015 Cisco Systems, Inc.
-#
-# 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.
-
-from django.conf import settings
-
-DASHBOARD = 'developer'
-
-ADD_ANGULAR_MODULES = [
-    'horizon.dashboard.developer'
-]
-
-ADD_INSTALLED_APPS = [
-    'openstack_dashboard.contrib.developer'
-]
-
-ADD_SCSS_FILES = [
-    'dashboard/developer/developer.scss',
-]
-
-AUTO_DISCOVER_STATIC_FILES = True
-
-DISABLED = True
-
-if getattr(settings, 'DEBUG', False):
-    DISABLED = False
diff -Nru horizon-10.0.0/openstack_dashboard/enabled/_9010_preview.py horizon-10.0.1/openstack_dashboard/enabled/_9010_preview.py
--- horizon-10.0.0/openstack_dashboard/enabled/_9010_preview.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/enabled/_9010_preview.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,21 +0,0 @@
-# Copyright 2015 Cisco Systems, Inc.
-#
-# 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.
-
-
-PANEL = 'theme_preview'
-PANEL_GROUP = 'default'
-PANEL_DASHBOARD = 'developer'
-
-ADD_PANEL = \
-    'openstack_dashboard.contrib.developer.theme_preview.panel.Preview'
diff -Nru horizon-10.0.0/openstack_dashboard/enabled/_9020_resource_browser.py horizon-10.0.1/openstack_dashboard/enabled/_9020_resource_browser.py
--- horizon-10.0.0/openstack_dashboard/enabled/_9020_resource_browser.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/enabled/_9020_resource_browser.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,20 +0,0 @@
-# (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
-#
-# 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.
-
-
-PANEL = 'resource_browser'
-PANEL_GROUP = 'default'
-PANEL_DASHBOARD = 'developer'
-
-ADD_PANEL = 'openstack_dashboard.contrib.developer.resource_browser.panel.ResourceBrowser'  # noqa
diff -Nru horizon-10.0.0/openstack_dashboard/settings.py horizon-10.0.1/openstack_dashboard/settings.py
--- horizon-10.0.0/openstack_dashboard/settings.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/settings.py	2016-11-02 07:50:09.000000000 +0000
@@ -211,6 +211,7 @@
     ('en-gb', 'British English'),
     ('es', 'Spanish'),
     ('fr', 'French'),
+    ('id', 'Indonesian'),
     ('it', 'Italian'),
     ('ja', 'Japanese'),
     ('ko', 'Korean (Korea)'),
@@ -295,7 +296,14 @@
 # Theme Cookie Name
 THEME_COOKIE_NAME = 'theme'
 
-POLICY_CHECK_FUNCTION = None
+
+def check(actions, request, target=None):
+    # Note(Itxaka): This is to prevent circular dependencies and apps not ready
+    # If you do django imports in your settings, you are gonna have a bad time
+    from openstack_auth import policy
+    return policy.check(actions, request, target)
+
+POLICY_CHECK_FUNCTION = check
 
 CSRF_COOKIE_AGE = None
 
@@ -425,16 +433,6 @@
 )
 INSTALLED_APPS[0:0] = ADD_INSTALLED_APPS
 
-
-def check(actions, request, target=None):
-    # Note(Itxaka): This is to prevent circular dependencies and apps not ready
-    # If you do django imports in your settings, you are gonna have a bad time
-    from openstack_auth import policy
-    return policy.check(actions, request, target)
-
-if POLICY_CHECK_FUNCTION is None:
-    POLICY_CHECK_FUNCTION = check
-
 NG_TEMPLATE_CACHE_AGE = NG_TEMPLATE_CACHE_AGE if not DEBUG else 0
 
 # This base context objects gets added to the offline context generator
diff -Nru horizon-10.0.0/openstack_dashboard/static/app/core/images/images.module.js horizon-10.0.1/openstack_dashboard/static/app/core/images/images.module.js
--- horizon-10.0.0/openstack_dashboard/static/app/core/images/images.module.js	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/static/app/core/images/images.module.js	2016-11-02 07:50:09.000000000 +0000
@@ -143,9 +143,9 @@
         isServer: false,
         singleton: true,
         options: [
-          {label: gettext('Public'), key: gettext('Public')},
-          {label: gettext('Private'), key: gettext('Private')},
-          {label: gettext('Shared With Project'), key: gettext('Shared With Project')},
+          {label: gettext('Public'), key: 'public'},
+          {label: gettext('Private'), key: 'private'},
+          {label: gettext('Shared With Project'), key: 'shared'},
           {label: gettext('Unknown'), key: 'unknown'}
         ]
       })
diff -Nru horizon-10.0.0/openstack_dashboard/test/settings.py horizon-10.0.1/openstack_dashboard/test/settings.py
--- horizon-10.0.0/openstack_dashboard/test/settings.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/test/settings.py	2016-11-02 07:50:09.000000000 +0000
@@ -106,6 +106,7 @@
 )
 
 # Load the pluggable dashboard settings
+import openstack_dashboard.contrib.developer.enabled
 import openstack_dashboard.enabled
 import openstack_dashboard.local.enabled
 
@@ -113,7 +114,8 @@
 settings_utils.update_dashboards(
     [
         openstack_dashboard.enabled,
-        openstack_dashboard.local.enabled
+        openstack_dashboard.local.enabled,
+        openstack_dashboard.contrib.developer.enabled
     ],
     HORIZON_CONFIG,
     INSTALLED_APPS,
diff -Nru horizon-10.0.0/openstack_dashboard/usage/tables.py horizon-10.0.1/openstack_dashboard/usage/tables.py
--- horizon-10.0.0/openstack_dashboard/usage/tables.py	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/openstack_dashboard/usage/tables.py	2016-11-02 07:50:09.000000000 +0000
@@ -32,7 +32,8 @@
 class BaseUsageTable(tables.DataTable):
     vcpus = tables.Column('vcpus', verbose_name=_("VCPUs"))
     disk = tables.Column('local_gb', verbose_name=_("Disk"),
-                         filters=(sizeformat.diskgbformat,))
+                         filters=(sizeformat.diskgbformat,),
+                         attrs={"data-type": "size"})
     memory = tables.Column('memory_mb',
                            verbose_name=_("RAM"),
                            filters=(sizeformat.mb_float_format,),
diff -Nru horizon-10.0.0/releasenotes/notes/glance-v2-ba86ba34611f95ce.yaml horizon-10.0.1/releasenotes/notes/glance-v2-ba86ba34611f95ce.yaml
--- horizon-10.0.0/releasenotes/notes/glance-v2-ba86ba34611f95ce.yaml	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/releasenotes/notes/glance-v2-ba86ba34611f95ce.yaml	2016-11-02 07:50:09.000000000 +0000
@@ -7,6 +7,9 @@
     to set locations when creating or updating images. Depending on the Glance
     version, the ability to set locations is controlled by policies and/or
     configuration values.
+upgrade:
+  - The OPENSTACK_IMAGE_FORMATS variable must be added to the
+    REST_API_REQUIRED_SETTINGS setting in local_settings.py
 issues:
   - If you set 'images_panel' to False for the ANGULAR_FEATURES option (which
     is not the default) and configure Horizon to use Glance v2, Ramdisk ID and
diff -Nru horizon-10.0.0/releasenotes/notes/launch-instance-defaults-c6ab65b7ab822162.yaml horizon-10.0.1/releasenotes/notes/launch-instance-defaults-c6ab65b7ab822162.yaml
--- horizon-10.0.0/releasenotes/notes/launch-instance-defaults-c6ab65b7ab822162.yaml	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/releasenotes/notes/launch-instance-defaults-c6ab65b7ab822162.yaml	2016-11-02 07:50:09.000000000 +0000
@@ -2,4 +2,7 @@
 features:
   - Added the LAUNCH_INSTANCE_DEFAULTS setting which allows specifying default
     values for the Launch Instance workflow. Initially only the Configuration
-    Drive property is supported.
\ No newline at end of file
+    Drive property is supported.
+upgrade:
+  - The LAUNCH_INSTANCE_DEFAULTS variable must be added to the
+    REST_API_REQUIRED_SETTINGS setting in local_settings.py
diff -Nru horizon-10.0.0/releasenotes/notes/move-developer-enabled-files-b1ad2265cd79b11e.yaml horizon-10.0.1/releasenotes/notes/move-developer-enabled-files-b1ad2265cd79b11e.yaml
--- horizon-10.0.0/releasenotes/notes/move-developer-enabled-files-b1ad2265cd79b11e.yaml	1970-01-01 00:00:00.000000000 +0000
+++ horizon-10.0.1/releasenotes/notes/move-developer-enabled-files-b1ad2265cd79b11e.yaml	2016-11-02 07:50:09.000000000 +0000
@@ -0,0 +1,9 @@
+---
+upgrade:
+  - The developer enabled files have been moved from
+    ``openstack_dashboard/enabled`` to
+    ``openstack_dashboard/contrib/developer/enabled``. To enable them, copy
+    into ``openstack_dashboard/local/enabled`` and set ``DEBUG = True``.
+fixes:
+  - There will no longer be any ``WARNING`` messages regarding
+    the developer panels in logs.
diff -Nru horizon-10.0.0/tox.ini horizon-10.0.1/tox.ini
--- horizon-10.0.0/tox.ini	2016-09-30 07:49:41.000000000 +0000
+++ horizon-10.0.1/tox.ini	2016-11-02 07:50:09.000000000 +0000
@@ -103,8 +103,7 @@
 commands =
   coverage erase
   coverage run {toxinidir}/manage.py test horizon --settings=horizon.test.settings {posargs}
-  coverage run {toxinidir}/manage.py test openstack_dashboard --settings=openstack_dashboard.test.settings --exclude-dir=openstack_dashboard/test/integration_tests {posargs}
-  coverage combine
+  coverage run -a {toxinidir}/manage.py test openstack_dashboard --settings=openstack_dashboard.test.settings --exclude-dir=openstack_dashboard/test/integration_tests {posargs}
   coverage xml
   coverage html
 

Reply to: