git am 操作

git am 操作

  • 我们在做git操作的时候,为了保留git log的记录,我们在做patch的时候会使用git format patch的命令来生成一个patch,在应用patch的时候会选择git am来打上patch。我们打上的patch一般会包含N个文件的补丁,假设这N个文件中有一个文件发生了conflict,那么am的过程就会停止,这时候需要我们手动去解决conflict,然后才能继续。

patch文件

  • 生成patch文件的操作如下:
$ git format-patch HEAD^		#生成最近的1次commit的patch
$ git format-patch HEAD^^		#生成最近的2次commit的patch
$ git format-patch HEAD^^^	# 生成最近的3次commit的patch
$ git format-patch HEAD^^^^	# 生成最近的4次commit的patch
$ git format-patch <r1>..<r2>	# 生成两个commit间的修改的patch(包含两个commit。<r1>和<r2>都是具体的commit号)
$ git format-patch <r1>			# 生成某commit以来的修改patch(不包含该commit)
$ git format-patch --root <r1>	# 生成从根到r1提交的所有patch
  • Example
  • 查看日志记录如下:
jackdan@jackdan-ThinkPad-T430:~/work/fp10/horizon$ git log
commit 8fecdb43e8226524325809fcd91d70fe98d4517c
Author: chao.ma <chao.ma@easystack.cn>
Date:   Tue Sep 4 16:00:56 2018 +0800

    ESFIX: Fix exited horizon when created alarm sometimes
    
    It needs to get alarm notify list when created alarm,
    while getting notify list should call keystone api to
    get user information. It needs to judge request.user
    whether is superuser which is used to initialize
    keystoneclient and use policy to judge privileges if
    the user is superuser. The reason is that the logic of
    judging whether the user is superuser sometimes use the
    project role of this user, while using policy to judge
    privileges use the domain role of this user. So if this
    user has admin project role and member domain role which
    may result in this problem. This is due to incorrect usage
    about using is_superuser api to judge whether this user is
    cloud admin. So it needs to edit code that uses
    api.keystone.is_cloud_admin to judge whether this user is
    cloud admin which can keep same logic during all the process
    of code.
    
    Change-Id: I0236f327182914f97ced1cf4f9d56d7f9540543c
    Closes-bug:#EAS-18847

commit 74059bda8452794ddb08e0861675f1ca9cf4945d
Author: muyanli <yanli.mou@easystack.cn>
Date:   Thu Aug 9 16:13:57 2018 +0800

    fix bug error of export billing
    
    Change-Id: I53ede97a487641b1937df8503a06f0b720e99b81
    Close-bug: #EAS-17641

commit a31114a7acdd794723303f12791ef69c34abed6f
Author: Yongtao Yang <yongtao.yang@easystack.cn>
Date:   Thu Sep 27 17:08:03 2018 +0800

    Modify regular expression validation for custom container image links
    
    Add colon verification and modify the line-through validation
    
    Change-Id: Iaa30bddad5442bbb37f140597811d4a91b338016
    Closes-bug: #EAS-18845

commit 6dd9b02a4301bd5233f51d3826e09290c0f0f7bc
Author: Yongtao Yang <yongtao.yang@easystack.cn>
Date:   Thu Sep 20 19:05:55 2018 +0800

    Front-end input test prompt error
    
    Modify the regular expression input value can not be test.
    And modify the tooltip text.
    
    Change-Id: I875305aa575d5f224fb8543b64d3f228cafa9f6a
    Close-sub-task: #EAS-18774

commit 4c695733211e038364e308e62ebc508eac19e956
Author: JackieYuan <jing.yuan@easystack.cn>
Date:   Thu Sep 6 11:05:36 2018 +0800
  • 生成patch文件
jackdan@jackdan-ThinkPad-T430:~/work/fp10/horizon$ git format-patch HEAD^
0001-ESFIX-Fix-exited-horizon-when-created-alarm-sometime.patch
jackdan@jackdan-ThinkPad-T430:~/work/fp10/horizon$ cat 0001-ESFIX-Fix-exited-horizon-when-created-alarm-sometime.patch 
From 8fecdb43e8226524325809fcd91d70fe98d4517c Mon Sep 17 00:00:00 2001
From: "chao.ma" <chao.ma@easystack.cn>
Date: Tue, 4 Sep 2018 16:00:56 +0800
Subject: [PATCH] ESFIX: Fix exited horizon when created alarm sometimes

It needs to get alarm notify list when created alarm,
while getting notify list should call keystone api to
get user information. It needs to judge request.user
whether is superuser which is used to initialize
keystoneclient and use policy to judge privileges if
the user is superuser. The reason is that the logic of
judging whether the user is superuser sometimes use the
project role of this user, while using policy to judge
privileges use the domain role of this user. So if this
user has admin project role and member domain role which
may result in this problem. This is due to incorrect usage
about using is_superuser api to judge whether this user is
cloud admin. So it needs to edit code that uses
api.keystone.is_cloud_admin to judge whether this user is
cloud admin which can keep same logic during all the process
of code.

Change-Id: I0236f327182914f97ced1cf4f9d56d7f9540543c
Closes-bug:#EAS-18847
---
 easystack_dashboard/api/rest/keystone.py           | 602 +++++++++++++--------
 .../test/api_tests/keystone_rest_tests.py          | 115 ++++
 tox.ini                                            |   2 +-
 3 files changed, 493 insertions(+), 226 deletions(-)

diff --git a/easystack_dashboard/api/rest/keystone.py b/easystack_dashboard/api/rest/keystone.py
index a693e80..dcd536c 100644
--- a/easystack_dashboard/api/rest/keystone.py
+++ b/easystack_dashboard/api/rest/keystone.py
@@ -15,20 +15,20 @@
 """
 
 import copy
+
+from django.conf import settings
+from django.core.urlresolvers import reverse
 import django.http
-from django.utils.translation import ugettext_lazy as _
+from django.utils.datastructures import SortedDict
 from django.utils.translation import gettext as trans
+from django.utils.translation import ugettext_lazy as _
 from django.views import generic
-from django.conf import settings
-from horizon import exceptions
 from easystack_dashboard import api
 from easystack_dashboard.api import base
-from easystack_dashboard.api import signup
-from easystack_dashboard.api.rest import usage
-from easystack_dashboard.api.rest import utils as rest_utils
 from easystack_dashboard.api.rest import urls
-from django.utils.datastructures import SortedDict
-from django.core.urlresolvers import reverse
+from easystack_dashboard.api.rest import utils as rest_utils
+from easystack_dashboard.api import signup
+from horizon import exceptions
 import six.moves.urllib.parse as urlparse
 
 OPENSTACK_USER = ("nova",
@@ -57,7 +57,9 @@ OPENSTACK_USER = ("nova",
                   "esstorage",
                   "aodh")
 
-OPENSTACK_DOMAIN = ('heat_domain', 'magnum', 'ironic', 'trove', 'magnum_domain_admin')
+OPENSTACK_DOMAIN = (
+    'heat_domain', 'magnum', 'ironic',
+    'trove', 'magnum_domain_admin')
 OPENSTACK_PROJECT = ('services',)
 OPENSTACK_ROLE = ('ResellerAdmin', 'heat_stack_user', 'SwiftOperator')
 
@@ -126,8 +128,8 @@ class Users(generic.View):
         project_role_id = request.DATA.get('project_role_id')
         domain_role_id = request.DATA.get('domain_role_id')
 
-        if not (domain_id and project_id and
-                    project_role_id and domain_role_id):
+        if (not (domain_id and project_id and
+                 project_role_id and domain_role_id)):
             msg = 'project_id and role_id for \
             project and domain must be not null'
             return django.http.HttpResponseBadRequest(msg)
@@ -171,9 +173,9 @@ class Users(generic.View):
         if request.DATA.get('all_projects'):
             projects = api.keystone.tenant_list(request, domain=domain_id)
             for project in projects[0]:
-                if project.id != project_id and \
+                if (project.id != project_id and
                         not (domain_id == 'default' and
-                                     project.name == 'services'):
+                             project.name == 'services')):
                     api.keystone.add_tenant_user_role(
                         request,
                         project=project.id,
@@ -210,8 +212,12 @@ class OrgUsers(generic.View):
     """API for keystone users.
     """
     url_regex = r'keystone/organizations/users/$'
-    domain_user_keywords = ('name', 'email', 'password', 'domain_id', 'domain_role_id')
-    project_user_keywords = ('name', 'email', 'password', 'domain_id', 'project_id', 'project_role_id')
+    domain_user_keywords = (
+        'name', 'email', 'password',
+        'domain_id', 'domain_role_id')
+    project_user_keywords = (
+        'name', 'email', 'password', 'domain_id',
+        'project_id', 'project_role_id')
 
     @rest_utils.ajax(data_required=True)
     def post(self, request):
@@ -252,7 +258,8 @@ class OrgUsers(generic.View):
             domain=params['domain_id']
         )
         # assign domain role to user
-        # domain_role_id = self.ensure_domain_role_id(request, params['domain_id'])
+        # domain_role_id =
+        # self.ensure_domain_role_id(request, params['domain_id'])
         api.keystone.add_tenant_user_role(
             request,
             domain=params['domain_id'],
@@ -360,7 +367,7 @@ class User(generic.View):
 
         elif 'enabled' in keys:
             enabled = request.DATA['enabled']
-            if user.user_role == 'domain_admin' and enabled == True:
+            if user.user_role == 'domain_admin' and enabled:
                 try:
                     api.signup.admin_active_user(request, user.id)
                 except Exception as e:
@@ -384,7 +391,7 @@ class UserEmail(generic.View):
     @rest_utils.ajax()
     def get(self, request, email):
         user = signup.verify_email(request, email)
-        if user == None or len(user) == 0:
+        if user is None or len(user) == 0:
             return {"result": True}
         return {"result": False}
 
@@ -392,15 +399,18 @@ class UserEmail(generic.View):
 @urls.register
 class NotifyList(generic.View):
     """API for create and update notify list
+
     which belongs to current user.
-    The notify list is used for alarms."""
+    The notify list is used for alarms.
+
+    """
     url_regex = r'keystone/notifylist/$'
 
     @rest_utils.ajax()
     def get(self, request):
         """Get notify list of current user"""
         user_id = request.user.id
-        admin = request.user.is_superuser
+        admin = api.keystone.is_cloud_admin(request)
         user = api.keystone.user_get(request, user_id, admin)
         data = user.to_dict()
         items = []
@@ -414,11 +424,12 @@ class NotifyList(generic.View):
                 if name == data.get('name'):
                     include_myself = True
         if not include_myself:
-            items.append({'name': data.get('name'),
-                          'description': 'Send notification to registered email and mobile',
-                          'email': [{'value': email, 'tag': ''}],
-                          'sms': [{'value': mobile, 'tag': ''}]
-                          })
+            items.append({
+                'name': data.get('name'),
+                'description':
+                    'Send notification to registered email and mobile',
+                'email': [{'value': email, 'tag': ''}],
+                'sms': [{'value': mobile, 'tag': ''}]})
             if getattr(settings, "LDAP_EDITABLE", True):
                 new_data = {'notify_list': items}
                 api.keystone.user_update(request, user, admin, **new_data)
@@ -428,11 +439,11 @@ class NotifyList(generic.View):
     def post(self, request):
         """Create notify list, update current user"""
         user_id = request.user.id
-        admin = request.user.is_superuser
+        admin = api.keystone.is_cloud_admin(request)
         user = api.keystone.user_get(request, user_id, admin)
         dic = user.to_dict()
         notify_list = dic.get('notify_list')
-        if notify_list == None:
+        if notify_list is None:
             notify_list = []
         notify_list.append(request.DATA)
         data = {'notify_list': notify_list}
@@ -446,7 +457,7 @@ class NotifyList(generic.View):
     def put(self, request):
         """Update notify list of current user"""
         user_id = request.user.id
-        admin = request.user.is_superuser
+        admin = api.keystone.is_cloud_admin(request)
         user = api.keystone.user_get(request, user_id, admin)
         dic = user.to_dict()
         name = request.DATA.get('name')
@@ -584,7 +595,7 @@ class Password(generic.View):
             return True
         except Exception as e:
             if e.http_status == 401:
-                return dict(status="403", msg="Old Password is Wrong");
+                return dict(status="403", msg="Old Password is Wrong")
             raise e
 
 
@@ -596,10 +607,12 @@ class Domains(generic.View):
 
     def _ensure_domain_level_info(self, request, domains):
         for domain in domains:
-            parent_domain_names = api.keystone.get_domain_parent_names(request, domain['id'])
+            parent_domain_names = api.keystone.get_domain_parent_names(
+                request, domain['id'])
             parent_domain_names.reverse()
             domain['org_structure'] = '/' + ' / '.join(parent_domain_names)
-            domain['is_top_domain'] = True if not parent_domain_names else False
+            domain['is_top_domain'] = True \
+                if not parent_domain_names else False
 
     @rest_utils.ajax()
     def get(self, request):
@@ -610,10 +623,11 @@ class Domains(generic.View):
         The listing result is an object with property "items".
         """
         items = [d.to_dict() for d in api.keystone.domain_list(request)]
-        items = [domain for domain in items if domain.get('name') not in OPENSTACK_DOMAIN]
-        if rest_utils.str_to_bool(request.GET.get('domain_panel'))\
-           and getattr(settings, 'IDENTITY_MULTI_LEVEL', False):
-           self._ensure_domain_level_info(request, items)
+        items = [domain for domain in items if
+                 domain.get('name') not in OPENSTACK_DOMAIN]
+        if rest_utils.str_to_bool(request.GET.get('domain_panel')) and \
+                getattr(settings, 'IDENTITY_MULTI_LEVEL', False):
+            self._ensure_domain_level_info(request, items)
         return {'items': items}
 
     @rest_utils.ajax(data_required=True)
@@ -686,9 +700,11 @@ class Domain(generic.View):
                 resource_id = unicode(account[0].to_dict().get('id'))
                 query = [{"field": "meter", "op": "eq", "value": 'account'}]
                 account_alarms = api.ceilometer.alarm_list(request, query)
-                alarm_dict = SortedDict([(d.resourceid, d) for d in account_alarms])
+                alarm_dict = SortedDict(
+                    [(d.resourceid, d) for d in account_alarms])
                 if alarm_dict.get(resource_id):
-                    api.ceilometer.alarm_delete(request, alarm_dict.get(resource_id).id)
+                    api.ceilometer.alarm_delete(
+                        request, alarm_dict.get(resource_id).id)
             else:
                 pass
 
@@ -713,19 +729,23 @@ class Domain(generic.View):
         if alarm_id:
             if request.DATA.get('alarm'):
                 try:
-                    alarmData = rest_utils.create_account_alarm(request, request.DATA.get('resource_id'))
+                    alarmData = rest_utils.create_account_alarm(
+                        request, request.DATA.get('resource_id'))
                     if not request.DATA.get('enabled_account_alarm'):
                         alarmData['enabled'] = True
                         alarmData['state'] = 'insufficient data'
-                    api.ceilometer.alarm_update(request, alarm_id, ceilometer_usage=None, **alarmData)
-                except:
+                    api.ceilometer.alarm_update(
+                        request, alarm_id, ceilometer_usage=None, **alarmData)
+                except Exception:
                     pass
             else:
                 try:
-                    alarmData = rest_utils.create_account_alarm(request, request.DATA.get('resource_id'))
+                    alarmData = rest_utils.create_account_alarm(
+                        request, request.DATA.get('resource_id'))
                     alarmData['enabled'] = False
-                    api.ceilometer.alarm_update(request, alarm_id, ceilometer_usage=None, **alarmData)
-                except:
+                    api.ceilometer.alarm_update(
+                        request, alarm_id, ceilometer_usage=None, **alarmData)
+                except Exception:
                     pass
         elif request.DATA.get('alarm'):
             query = [
@@ -733,10 +753,12 @@ class Domain(generic.View):
             account = api.chakra.account_list(request, query, **request.GET)
             resource_id = account[0].to_dict().get('id')
             if resource_id:
-                alarmData = rest_utils.create_account_alarm(request, unicode(resource_id))
+                alarmData = rest_utils.create_account_alarm(
+                    request, unicode(resource_id))
                 try:
-                    api.ceilometer.alarm_create(request, ceilometer_usage=None, **alarmData)
-                except:
+                    api.ceilometer.alarm_create(
+                        request, ceilometer_usage=None, **alarmData)
+                except Exception:
                     pass
 
 
@@ -756,7 +778,8 @@ def str_to_bool(str):
 def ensure_domain_name(request, result_dict, with_domain=True):
     for item in result_dict:
         try:
-            domain = api.keystone.domain_get(request, item['domain_id']).to_dict()
+            domain = api.keystone.domain_get(
+                request, item['domain_id']).to_dict()
             item['domain_name'] = domain['name']
             if with_domain:
                 item['domain'] = domain
@@ -892,7 +915,7 @@ class Projects(generic.View):
             **kwargs
         )
 
-        new_project_dict_list = [new_project.to_dict()];
+        new_project_dict_list = [new_project.to_dict()]
         ensure_domain_name(request, new_project_dict_list)
         return rest_utils.CreatedResponse(
             '/api/keystone/projects/%s' % new_project.id,
@@ -924,21 +947,29 @@ class Project(generic.View):
 
     def set_project_quotas_to_zero(self, request, tenant_id):
 
-        nova_quotas = [(field_name, 0) for field_name in rest_utils.NOVA_PROJECT_QUOTA_FIELDS]
+        nova_quotas = [(field_name, 0) for field_name in
+                       rest_utils.NOVA_PROJECT_QUOTA_FIELDS]
         api.nova.tenant_quota_update(request, tenant_id, **dict(nova_quotas))
 
-        cinder_quotas = [(field_name, 0) for field_name in rest_utils.CINDER_PROJECT_QUOTA_FIELDS]
-        api.cinder.tenant_quota_update(request, tenant_id, **dict(cinder_quotas))
+        cinder_quotas = [(field_name, 0) for field_name in
+                         rest_utils.CINDER_PROJECT_QUOTA_FIELDS]
+        api.cinder.tenant_quota_update(
+            request, tenant_id, **dict(cinder_quotas))
 
         neutron_fields = rest_utils.NEUTRON_PROJECT_QUOTA_FIELDS
-        if getattr(settings, "OPENSTACK_NEUTRON_NETWORK", {}).get('enable_lb', False):
+        if getattr(
+                settings,
+                "OPENSTACK_NEUTRON_NETWORK", {}).get('enable_lb', False):
             neutron_fields += rest_utils.LOADBALANCER_PROJECT_QUOTA_FIELDS
         neutron_quotas = [(field_name, 0) for field_name in neutron_fields]
-        api.neutron.tenant_quota_update(request, tenant_id, **dict(neutron_quotas))
+        api.neutron.tenant_quota_update(
+            request, tenant_id, **dict(neutron_quotas))
 
         if getattr(settings, 'MANILA_ENABLED', False):
-            manila_quotas = [(field_name, 0) for field_name in rest_utils.MANILA_PROJECT_QUOTA_FIELDS]
-            api.manila.tenant_quota_update(request, tenant_id, **dict(manila_quotas))
+            manila_quotas = [(field_name, 0) for field_name in
+                             rest_utils.MANILA_PROJECT_QUOTA_FIELDS]
+            api.manila.tenant_quota_update(
+                request, tenant_id, **dict(manila_quotas))
 
     @rest_utils.ajax()
     def get(self, request, id):
@@ -1028,8 +1059,8 @@ class AuthorizedProjectsTree(generic.View):
     @rest_utils.ajax()
     def get(self, request, id):
         for tenant in request.user.authorized_tenants:
-            if id==tenant.id:
-                    return {'id':id, 'name': tenant.name}
+            if id == tenant.id:
+                    return {'id': id, 'name': tenant.name}
         return api.keystone.tenant_get(request, id).to_dict()
 
 
@@ -1039,7 +1070,8 @@ class ProjectUsers(generic.View):
 
     def _ensure_users_is_project_admin(self, request, users):
         for user in users:
-            if user['roles'] and api.keystone.has_admin_role(request, user['roles']):
+            if user['roles'] and api.keystone.has_admin_role(
+                    request, user['roles']):
                 user['is_project_admin'] = True
             else:
                 user['is_project_admin'] = False
@@ -1050,7 +1082,8 @@ class ProjectUsers(generic.View):
         """
         target = api.keystone.TenantRolesManager(project_id)
         users = target.get_target_users_with_roles(request)
-        users = [user for user in users if user.get('name') not in OPENSTACK_USER]
+        users = [user for user in users if user.get(
+            'name') not in OPENSTACK_USER]
         self._ensure_users_is_project_admin(request, users)
         return {'items': users}
 
@@ -1080,16 +1113,19 @@ class DomainUsers(generic.View):
 
     def _ensure_users_is_domain_admin(self, request, users):
         for user in users:
-            if user.get('roles') and api.keystone.has_admin_role(request, user['roles']):
+            if user.get('roles') and api.keystone.has_admin_role(
+                    request, user['roles']):
                 user['is_domain_admin'] = True
             else:
                 user['is_domain_admin'] = False
 
     def _check_user_projects_in_domain(self, request, users, domain_id):
-        project_list, has_more = api.keystone.project_list(request, domain=domain_id)
+        project_list, has_more = api.keystone.project_list(
+            request, domain=domain_id)
         user_ids = set()
         for project in project_list:
-            users_roles = api.keystone.get_project_users_roles(request, project.id)
+            users_roles = api.keystone.get_project_users_roles(
+                request, project.id)
             user_ids = user_ids | set(users_roles.keys())
 
         for user in users:
@@ -1098,7 +1134,6 @@ class DomainUsers(generic.View):
             else:
                 user['has_project_in_domain'] = False
 
-
     @rest_utils.ajax()
     def get(self, request, domain_id):
         """List all users of the domain.
@@ -1108,9 +1143,10 @@ class DomainUsers(generic.View):
 
         if rest_utils.str_to_bool(request.GET.get('with_user_without_role')):
             users_ids = [user['id'] for user in users]
-            users += [user.to_dict() for user in api.keystone.user_list(request, domain=domain_id)
-                      if user.id not in users_ids]
-        users = [user for user in users if user.get('name') not in OPENSTACK_USER]
+            users += [user.to_dict() for user in api.keystone.user_list(
+                request, domain=domain_id) if user.id not in users_ids]
+        users = [user for user in users if
+                 user.get('name') not in OPENSTACK_USER]
         self._ensure_users_is_domain_admin(request, users)
 
         if rest_utils.str_to_bool(request.GET.get('check_user_project')):
@@ -1287,7 +1323,8 @@ class LDAP(generic.View):
     def get(self, request):
         ldap_enable = getattr(settings, 'LDAP_ENABLE', False)
         ldap_editable = getattr(settings, 'LDAP_EDITABLE', True)
-        return rest_utils.JSONResponse({"enable": ldap_enable, "editable": ldap_editable}, 200)
+        return rest_utils.JSONResponse(
+            {"enable": ldap_enable, "editable": ldap_editable}, 200)
 
 
 @urls.register
@@ -1301,10 +1338,10 @@ class CheckProjectAdmin(generic.View):
             user_id = request.user.id
         project_id = request.DATA.get('project_id')
 
-        result = api.keystone.user_is_project_admin(request,
-                                                    user_id, project_id) \
-                 or api.keystone.is_cloud_admin(request) \
-                 or api.keystone.is_domain_admin(request)
+        result = (
+            api.keystone.user_is_project_admin(request, user_id, project_id) or
+            api.keystone.is_cloud_admin(request) or
+            api.keystone.is_domain_admin(request))
         return rest_utils.JSONResponse(result, 200)
 
 
@@ -1332,7 +1369,8 @@ class UserIsCurProjectDomainAdmin(generic.View):
         """
         proj = api.keystone.get_cur_project(request)
         domain_id = getattr(proj, 'domain_id')
-        return api.keystone.user_is_project_domain_admin(request, user_id, domain_id)
+        return api.keystone.user_is_project_domain_admin(
+            request, user_id, domain_id)
 
 
 @urls.register
@@ -1345,7 +1383,8 @@ class CurUserIsCurProjectDomainAdmin(generic.View):
         """
         proj = api.keystone.get_cur_project(request)
         domain_id = getattr(proj, 'domain_id')
-        return api.keystone.user_is_project_domain_admin(request, request.user.id, domain_id)
+        return api.keystone.user_is_project_domain_admin(
+            request, request.user.id, domain_id)
 
 
 @urls.register
@@ -1376,31 +1415,39 @@ class UserIsProjectChief(generic.View):
         project_id = request.GET['project_id']
         domain_id = ''
 
-        is_domain_admin = api.keystone.user_is_domain_admin(request, user_id, request.user.user_domain_id)
+        is_domain_admin = api.keystone.user_is_domain_admin(
+            request, user_id, request.user.user_domain_id)
         if is_domain_admin:
-            # if domain admin , first judge if this project is user currrent domain admin project
-            # if so, just reassign
-            projects, has_more = api.keystone.project_list(request, domain = request.user.user_domain_id)
+            # if domain admin , first judge if this project is user
+            # currrent domain admin project if so, just reassign
+            projects, has_more = api.keystone.project_list(
+                request, domain=request.user.user_domain_id)
             for project in projects:
                 if project_id == getattr(project, 'id'):
                     return True
-            domains = api.keystone.get_subsets(request, request.user.user_domain_id, False, False)
+            domains = api.keystone.get_subsets(
+                request, request.user.user_domain_id, False, False)
             for domain in domains:
-                projects, has_more = api.keystone.project_list(request, domain = getattr(domain, 'id'))
+                projects, has_more = api.keystone.project_list(
+                    request, domain=getattr(domain, 'id'))
                 for project in projects:
                     if project_id == getattr(project, 'id'):
                         return True
         else:
-            domain_admins = api.keystone.get_user_admin_role_domains(request, request.user)
-            if(len(domain_admins)!=0):
+            domain_admins = api.keystone.get_user_admin_role_domains(
+                request, request.user)
+            if(len(domain_admins) != 0):
                 for domain_admin in domain_admins:
-                    projects, has_more = api.keystone.project_list(request, domain=domain_admin['id'])
+                    projects, has_more = api.keystone.project_list(
+                        request, domain=domain_admin['id'])
                     for project in projects:
                         if project_id == getattr(project, 'id'):
                             return True
-                    domains = api.keystone.get_subsets(request, domain_admin['id'], False, False)
+                    domains = api.keystone.get_subsets(
+                        request, domain_admin['id'], False, False)
                     for domain in domains:
-                        projects, has_more = api.keystone.project_list(request, domain=getattr(domain, 'id'))
+                        projects, has_more = api.keystone.project_list(
+                            request, domain=getattr(domain, 'id'))
                         for project in projects:
                             if project_id == getattr(project, 'id'):
                                 return True
@@ -1408,14 +1455,18 @@ class UserIsProjectChief(generic.View):
                 for tenant in request.user.authorized_tenants:
                     if getattr(tenant, 'id') == project_id:
                         domain_id = getattr(tenant, 'domain_id')
-                        if api.keystone.user_is_domain_admin(request, user_id, domain_id):
+                        if api.keystone.user_is_domain_admin(
+                                request, user_id, domain_id):
                             return True
                         else:
-                            parent_domain = api.keystone.get_parents(request, domain_id, False, False)
-                            domains = api.keystone.get_user_admin_role_domains(request, user_id)
+                            parent_domain = api.keystone.get_parents(
+                                request, domain_id, False, False)
+                            domains = api.keystone.get_user_admin_role_domains(
+                                request, user_id)
                             for p_domain in parent_domain:
                                 for domain in domains:
-                                    if getattr(p_domain, 'id') == getattr(domain, 'id'):
+                                    if getattr(p_domain, 'id') == getattr(
+                                            domain, 'id'):
                                         return True
         return False
 
@@ -1450,44 +1501,62 @@ class AllotUser(generic.View):
         project_id = request.GET['project_id']
         users_list = []
 
-        is_domain_admin = api.keystone.user_is_domain_admin(request, request.user.id, request.user.user_domain_id)
+        is_domain_admin = api.keystone.user_is_domain_admin(
+            request, request.user.id, request.user.user_domain_id)
         if is_domain_admin:
-            cur_level_proj, has_more = api.keystone.project_list(request, domain=request.user.user_domain_id)
+            cur_level_proj, has_more = api.keystone.project_list(
+                request, domain=request.user.user_domain_id)
             for proj in cur_level_proj:
                 if project_id == getattr(proj, 'id'):
-                    users_list = api.keystone.get_cur_domain_admin_users(request, request.user.user_domain_id)
+                    users_list = api.keystone.get_cur_domain_admin_users(
+                        request, request.user.user_domain_id)
                     return {'items': users_list}
-            sub_domains = api.keystone.get_subsets(request, request.user.user_domain_id, False, False)
+            sub_domains = api.keystone.get_subsets(
+                request, request.user.user_domain_id, False, False)
             for sub_domain in sub_domains:
-                projects, has_more = api.keystone.project_list(request, domain=getattr(sub_domain, 'id'))
+                projects, has_more = api.keystone.project_list(
+                    request, domain=getattr(sub_domain, 'id'))
                 for project in projects:
                     if project_id == getattr(project, 'id'):
-                        users_list = api.keystone.get_cur_domain_admin_users(request, getattr(sub_domain, 'id'))
+                        users_list = api.keystone.get_cur_domain_admin_users(
+                            request, getattr(sub_domain, 'id'))
                         for _user in users_list:
                             if _user['id'] == request.user.id:
                                 return {'items': users_list}
-                        users_list.append({'id': request.user.id, 'name': request.user.username})
+                        users_list.append(
+                            {'id': request.user.id,
+                             'name': request.user.username})
                         return {'items': users_list}
         else:
-            domain_admins = api.keystone.get_user_admin_role_domains(request, request.user)
+            domain_admins = api.keystone.get_user_admin_role_domains(
+                request, request.user)
             if (len(domain_admins) != 0):
                 for domain_admin in domain_admins:
-                    projects, has_more = api.keystone.project_list(request, domain=domain_admin['id'])
+                    projects, has_more = api.keystone.project_list(
+                        request, domain=domain_admin['id'])
                     for project in projects:
                         if project_id == getattr(project, 'id'):
-                            users_list = api.keystone.get_cur_domain_admin_users(request, domain_admin['id'])
+                            users_list = \
+                                api.keystone.get_cur_domain_admin_users(
+                                    request, domain_admin['id'])
                             return {'items': users_list}
-                    domains = api.keystone.get_subsets(request, domain_admin['id'], False, False)
+                    domains = api.keystone.get_subsets(
+                        request, domain_admin['id'], False, False)
                     for domain in domains:
-                        projects, has_more = api.keystone.project_list(request, domain=getattr(domain, 'id'))
+                        projects, has_more = api.keystone.project_list(
+                            request, domain=getattr(domain, 'id'))
                         for project in projects:
                             if project_id == getattr(project, 'id'):
-                                users_list = api.keystone.get_cur_domain_admin_users(request,
-                                                                                     getattr(domain, 'id'))
+                                users_list = \
+                                    api.keystone.get_cur_domain_admin_users(
+                                        request,
+                                        getattr(domain, 'id'))
                                 for _user in users_list:
                                     if _user['id'] == request.user.id:
                                         return {'items': users_list}
-                                users_list.append({'id': request.user.id, 'name': request.user.username})
+                                users_list.append(
+                                    {'id': request.user.id,
+                                     'name': request.user.username})
                                 return {'items': users_list}
         return {'items': users_list}
 
@@ -1504,7 +1573,8 @@ class AllotDomainQuotaUser(generic.View):
         users_list = []
 
         # parent = api.keystone.get_parents(request, domain_id, True, False)
-        users_list = api.keystone.get_cur_domain_admin_users(request, domain_id)
+        users_list = api.keystone.get_cur_domain_admin_users(
+            request, domain_id)
         is_cloud_admin = api.keystone.is_cloud_admin(request)
         if is_cloud_admin:
             users_cloud_admin_list = []
@@ -1527,28 +1597,34 @@ class DomainQuotaFormJson(generic.View):
 
         cur_proj = api.keystone.get_cur_project(request)
         cur_proj_domain_id = getattr(cur_proj, 'domain_id')
-        parents = api.keystone.get_parents(request,
-                                            domain_id=cur_proj_domain_id,
-                                            single_level=False,
-                                            admin=False)
-        if len(parents)==0:
-            if api.keystone.user_is_domain_admin(request, user=request.user.id , domain=cur_proj_domain_id ):
+        parents = api.keystone.get_parents(
+            request,
+            domain_id=cur_proj_domain_id,
+            single_level=False,
+            admin=False)
+        if len(parents) == 0:
+            if api.keystone.user_is_domain_admin(
+                    request, user=request.user.id,
+                    domain=cur_proj_domain_id):
                 return {'items': {
                     'display_domain_list': False,
                     'requester_domain_id': cur_proj_domain_id
                 }}
             else:
-                departs = api.keystone.get_subsets(request,
-                                         domain_id=cur_proj_domain_id,
-                                         single_level=True,
-                                         admin=False)
+                departs = api.keystone.get_subsets(
+                    request,
+                    domain_id=cur_proj_domain_id,
+                    single_level=True,
+                    admin=False)
                 requester_depart_list = []
                 for depart in departs:
-                    if_depart_admin = api.keystone.user_is_domain_admin(request, request.user.id,
-                                                      getattr(depart, 'id'))
+                    if_depart_admin = \
+                        api.keystone.user_is_domain_admin(
+                            request, request.user.id,
+                            getattr(depart, 'id'))
                     if if_depart_admin:
                         requester_depart_list.append(depart.to_dict())
-                if len(requester_depart_list)>1:
+                if len(requester_depart_list) > 1:
                     return {
                         'items': {
                             'display_domain_list': True,
@@ -1559,27 +1635,29 @@ class DomainQuotaFormJson(generic.View):
                     return {
                         'items': {
                             'display_domain_list': False,
-                            'requester_domain_id': requester_depart_list[0]['id'] if len(requester_depart_list)>0 else False
+                            'requester_domain_id':
+                                requester_depart_list[0]['id'] if
+                                len(requester_depart_list) > 0 else False
                         }
                     }
         else:
             for i in range(len(parents)):
-                parent = parents[len(parents)-1 - i]
+                parent = parents[len(parents) - 1 - i]
                 if_parent_domain_admin = api.keystone.\
                     user_is_domain_admin(request,
                                          request.user.id,
                                          getattr(parent, 'id'))
                 if if_parent_domain_admin:
-                    if i==0:
+                    if i == 0:
                         return {'items': {
                             'display_domain_list': False,
                             'requester_domain_id': getattr(parent, 'id')
                         }}
                     else:
                         preDomain = parents[len(parents) - i]
-                        brotherDomains = api.keystone.get_subsets(request,
-                                                 domain_id=getattr(preDomain, 'id'),
-                                                 single_level=True, admin=False)
+                        brotherDomains = api.keystone.get_subsets(
+                            request, domain_id=getattr(preDomain, 'id'),
+                            single_level=True, admin=False)
                         requester_domain_list = []
                         for brother in brotherDomains:
                             if_brother_domain_admin = api.keystone. \
@@ -1590,11 +1668,12 @@ class DomainQuotaFormJson(generic.View):
                                 requester_domain_list.append(brother.to_dict())
                             else:
                                 continue
-                        if len(requester_domain_list)>1:
+                        if len(requester_domain_list) > 1:
                             return {
                                 'items': {
                                     'display_domain_list': True,
-                                    'requester_domain_list': requester_domain_list
+                                    'requester_domain_list':
+                                        requester_domain_list
                                 }
                             }
                         else:
@@ -1603,9 +1682,10 @@ class DomainQuotaFormJson(generic.View):
                                 'requester_domain_id': getattr(parent, 'id')
                             }}
                 else:
-                    brotherDomains = api.keystone.get_subsets(request,
-                                                              domain_id=getattr(parent, 'id'),
-                                                              single_level=True, admin=False)
+                    brotherDomains = api.keystone.get_subsets(
+                        request,
+                        domain_id=getattr(parent, 'id'),
+                        single_level=True, admin=False)
                     requester_domain_list = []
                     for brother in brotherDomains:
                         if_brother_domain_admin = api.keystone. \
@@ -1626,7 +1706,8 @@ class DomainQuotaFormJson(generic.View):
                     else:
                         return {'items': {
                             'display_domain_list': False,
-                            'requester_domain_id': requester_domain_list[0]['id']
+                            'requester_domain_id': requester_domain_list[0][
+                                'id']
                         }}
             return {'items': {
                 'display_domain_list': False,
@@ -1662,10 +1743,12 @@ class IsLastLevelAdmin(generic.View):
         if is_cloud_admin:
             return False
         else:
-            admin_role_domains = api.keystone.get_user_admin_role_domains(request, request.user.id)
+            admin_role_domains = api.keystone.get_user_admin_role_domains(
+                request, request.user.id)
             for domain in admin_role_domains:
-                subsets = api.keystone.get_subsets(request, domain['id'], single_level=False, admin=False)
-                if len(subsets)!=0:
+                subsets = api.keystone.get_subsets(
+                    request, domain['id'], single_level=False, admin=False)
+                if len(subsets) != 0:
                     return False
             return True
 
@@ -1688,17 +1771,18 @@ class OrgArch(generic.View):
     def get(self, request, domain_id):
         result = api.keystone.get_parents(request, domain_id)
         try:
-            subsets = api.keystone.get_subsets(request, result[0].id, True, False)
+            subsets = api.keystone.get_subsets(
+                request, result[0].id, True, False)
             for subset in subsets:
                 if domain_id == subset.id:
                     current_domain = subset
                     result.insert(0, current_domain)
                     return {'items': [r.to_dict() for r in result]}
-        except:
+        except Exception:
             domains = []
             if result:
                 domains.append(result[0].to_dict())
-            domains.append({'name' : request.user.user_domain_name})
+            domains.append({'name': request.user.user_domain_name})
             return {'items': [r for r in domains]}
 
 
@@ -1711,8 +1795,8 @@ class OrgParents(generic.View):
     @rest_utils.ajax()
     def post(self, request):
         postData = request.DATA
-        items = api.keystone.get_parents(request, postData['id'], postData['single_level'])
-        orgs = []
+        items = api.keystone.get_parents(
+            request, postData['id'], postData['single_level'])
         itemDict = [i.to_dict() for i in items]
 
         if len(itemDict) != 0:
@@ -1722,14 +1806,19 @@ class OrgParents(generic.View):
                 if i == 0:
                     if api.keystone.is_domain_admin(request)[1]:
                         itemDict[i] = dict(itemDict[i], **{'nodes': [
-                            {'id': request.user.user_domain_id, 'name': request.user.user_domain_name,
+                            {'id': request.user.user_domain_id,
+                             'name': request.user.user_domain_name,
                              'nodes': [{'id': ' ', 'name': ' '}]}]})
                     else:
                         itemDict[i] = dict(itemDict[i], **{'nodes': [
-                            {'id': request.user.user_domain_id, 'name': request.user.user_domain_name,
-                             'forbidden': True, 'collapsed': False, 'nodes': [{'id': ' ', 'name': ' '}]}]})
+                            {'id': request.user.user_domain_id,
+                             'name': request.user.user_domain_name,
+                             'forbidden': True,
+                             'collapsed': False,
+                             'nodes': [{'id': ' ', 'name': ' '}]}]})
                 if i > 0:
-                    itemDict[i] = dict(itemDict[i], **{'nodes': [itemDict[i - 1]]})
+                    itemDict[i] = dict(
+                        itemDict[i], **{'nodes': [itemDict[i - 1]]})
 
             return {
                 'items': itemDict[len(itemDict) - 1],
@@ -1751,13 +1840,15 @@ class OrgSubsets(generic.View):
     @rest_utils.ajax()
     def post(self, request):
         id = request.DATA['id'] if 'id' in request.DATA else ''
-        single_level = bool(request.DATA['single_level']) if 'single_level' in request.DATA else False
+        single_level = bool(request.DATA['single_level']) if \
+            'single_level' in request.DATA else False
         subdomains = api.keystone.get_subsets(request, id, single_level)
         subprojs = api.keystone.tenant_list(request, domain=id)[0]
         orgs = []
         for d in subdomains:
             setattr(d, 'nodes', [{'id': ' ', 'name': ' '}])
-            orgs.append(dict(d.to_dict(), **{'nodes': [{'id': ' ', 'name': ' '}]}))
+            orgs.append(
+                dict(d.to_dict(), **{'nodes': [{'id': ' ', 'name': ' '}]}))
         for p in subprojs:
             if id == getattr(p, 'domain_id'):
                 orgs.append(p.to_dict())
@@ -1773,12 +1864,14 @@ class OrgSubDomains(generic.View):
     @rest_utils.ajax()
     def post(self, request):
         id = request.DATA['id'] if 'id' in request.DATA else ''
-        single_level = bool(request.DATA['single_level']) if 'single_level' in request.DATA else False
+        single_level = bool(request.DATA['single_level']) if \
+            'single_level' in request.DATA else False
         subdomains = api.keystone.get_subsets(request, id, single_level)
         orgs = []
         for d in subdomains:
             setattr(d, 'nodes', [{'id': ' ', 'name': ' '}])
-            orgs.append(dict(d.to_dict(), **{'nodes': [{'id': ' ', 'name': ' '}]}))
+            orgs.append(
+                dict(d.to_dict(), **{'nodes': [{'id': ' ', 'name': ' '}]}))
         return {'items': orgs}
 
 
@@ -1812,6 +1905,7 @@ class RootAccDomains(generic.View):
                 'root': trans('Cloud Platform')
                 }
 
+
 @urls.register
 class OrgNavSubsets(generic.View):
     """API over a single domains.
@@ -1821,7 +1915,9 @@ class OrgNavSubsets(generic.View):
     @rest_utils.ajax()
     def post(self, request):
         id = request.DATA['id'] if 'id' in request.DATA else ''
-        single_level = bool(request.DATA['single_level']) if 'single_level' in request.DATA else False
+        single_level = bool(
+            request.DATA['single_level']) if 'single_level' \
+                                             in request.DATA else False
         subdomains = api.keystone.get_subsets(request, id, single_level)
         subprojs = api.keystone.tenant_list(request, domain=id)[0]
         orgs = []
@@ -1832,11 +1928,16 @@ class OrgNavSubsets(generic.View):
 
         for p in subprojs:
             if id == getattr(p, 'domain_id'):
-                t_dict = dict(p.to_dict(), **{'node_type': 'project',
-                                              'url': reverse('switch_tenants', kwargs={'tenant_id': p.id}), })
+                t_dict = dict(
+                    p.to_dict(),
+                    **{'node_type': 'project',
+                       'url': reverse(
+                           'switch_tenants',
+                           kwargs={'tenant_id': p.id}), })
                 orgs.append(t_dict)
         return {'items': orgs}
 
+
 @urls.register
 class RootDomains(generic.View):
     """API over all domains.
@@ -1876,13 +1977,15 @@ class navOrgs(generic.View):
         def treeRecursion(srcNode, tarNode):
             if 'nodes' in srcNode:
                 if 'nodes' in tarNode:
-                    k=0
+                    k = 0
                     for i in range(len(srcNode['nodes'])):
                         for j in range(len(tarNode['nodes'])):
-                            if srcNode['nodes'][i]['id'] == tarNode['nodes'][j]['id']:
-                                treeRecursion(srcNode['nodes'][i], tarNode['nodes'][j])
+                            if srcNode['nodes'][i]['id'] == \
+                                    tarNode['nodes'][j]['id']:
+                                treeRecursion(
+                                    srcNode['nodes'][i], tarNode['nodes'][j])
                                 break
-                            k = k+1
+                            k = k + 1
                         if k >= len(tarNode['nodes']):
                             tarNode['nodes'].append(srcNode['nodes'][i])
                 else:
@@ -1890,43 +1993,57 @@ class navOrgs(generic.View):
                     tarNode['nodes'].append(srcNode)
 
         def generateTreeList(request, admin=True):
-            tenants, has_more = api.keystone.project_list(request, user=request.user, admin=admin)
+            tenants, has_more = api.keystone.project_list(
+                request, user=request.user, admin=admin)
             parentDomainIdList = []
             treeDictList = []
             tar_tree = {}
             parentListList = []
             for tenant in tenants:
                 tenant_dict = tenant.to_dict()
-                project_node = dict(tenant_dict, **{'node_type': 'project',
-                                                    'url': reverse('switch_tenants',
-                                                                   kwargs={'tenant_id': tenant_dict['id']})})
+                project_node = dict(
+                    tenant_dict,
+                    **{'node_type': 'project',
+                       'url': reverse('switch_tenants',
+                                      kwargs={'tenant_id': tenant_dict['id']})
+                       })
                 parentDomainIdList.append(tenant_dict['domain_id'])
-                parentList = api.keystone.get_parents(request, tenant_dict['domain_id'], single_level=False,
-                                                      admin=admin)
+                parentList = api.keystone.get_parents(
+                    request, tenant_dict['domain_id'],
+                    single_level=False, admin=admin)
                 parentListList.append(parentList)
                 next_level_node = project_node
                 # the root domain project situation:
                 if len(parentList) == 0:
-                    next_level_node = dict({'id': request.user.user_domain_id,
-                                            'name': request.user.user_domain_name,
-                                            'collapsed': False,
-                                            'forbidden': True, }, **{'nodes': [next_level_node]})
+                    next_level_node = dict(
+                        {'id': request.user.user_domain_id,
+                         'name': request.user.user_domain_name,
+                         'collapsed': False,
+                         'forbidden': True, },
+                        **{'nodes': [next_level_node]})
                 # the department project situation
                 else:
                     tenant_domain_name = ''
-                    subsets = api.keystone.get_subsets(request, parentList[0].id, single_level=False, admin=admin)
+                    subsets = api.keystone.get_subsets(
+                        request, parentList[0].id,
+                        single_level=False, admin=admin)
                     for subset in subsets:
                         if tenant_dict['domain_id'] == getattr(subset, 'id'):
                             tenant_domain_name = getattr(subset, 'name')
                             break
-                    next_level_node = dict({'id': tenant_dict['domain_id'],
-                                            'name': tenant_domain_name,
-                                            'collapsed': False,
-                                            'forbidden': True, }, **{'nodes': [next_level_node]})
+                    next_level_node = dict(
+                        {'id': tenant_dict['domain_id'],
+                         'name': tenant_domain_name,
+                         'collapsed': False,
+                         'forbidden': True, },
+                        **{'nodes': [next_level_node]})
                     for parent in parentList:
                         parent_dict = parent.to_dict()
-                        next_level_node = dict(dict(parent_dict, **{'collapsed': False, 'forbidden': True}),
-                                               **{'nodes': [next_level_node]})
+                        next_level_node = dict(
+                            dict(parent_dict,
+                                 **{'collapsed': False,
+                                    'forbidden': True}),
+                            **{'nodes': [next_level_node]})
                 treeDict = next_level_node
                 treeDictList.append(treeDict)
 
@@ -1973,15 +2090,14 @@ class OrgTree(generic.View):
         root = {'id': 'cloud_platform',
                 'name': trans('Cloud Platform'),
                 'forbidden': True,
-                'nodes': []
-               }
+                'nodes': []}
         org_tree_manager = OrgTreeManager()
         if api.keystone.is_cloud_admin(request):
             root = org_tree_manager.get_cloud_admin_init_tree(request)
         elif api.keystone.is_org_admin(request):
             root = org_tree_manager.get_org_admin_init_tree(request)
 
-        return {'items' : root}
+        return {'items': root}
 
 
 @urls.register
@@ -2003,24 +2119,26 @@ class BillOrgTree(generic.View):
                 'name': trans('Cloud Platform'),
                 'forbidden': True,
                 'collapsed': False,
-                'nodes': []
-               }
+                'nodes': []}
         org_tree_manager = OrgTreeManager()
         if api.keystone.is_cloud_admin(request):
             root = org_tree_manager.get_cloud_admin_init_tree(request)
         elif api.keystone.is_org_admin(request):
             root = org_tree_manager.get_bill_org_admin_init_tree(request)
             user_domain_id = request.user.user_domain_id
-            if_domain_admin = api.keystone.user_is_domain_admin(request, request.user.id, user_domain_id)
+            if_domain_admin = api.keystone.user_is_domain_admin(
+                request, request.user.id, user_domain_id)
             deafaultNodeId = user_domain_id
             if not if_domain_admin:
-                subsets = api.keystone.get_subsets(request, user_domain_id, True, False)
+                subsets = api.keystone.get_subsets(
+                    request, user_domain_id, True, False)
                 for subset in subsets:
-                    if_subset_admin = api.keystone.user_is_domain_admin(request, request.user.id, getattr(subset, 'id'))
+                    if_subset_admin = api.keystone.user_is_domain_admin(
+                        request, request.user.id, getattr(subset, 'id'))
                     if if_subset_admin:
                         deafaultNodeId = getattr(subset, 'id')
                         break
-        return {'items' : root,
+        return {'items': root,
                 'deafaultNodeId': deafaultNodeId}
 
 
@@ -2034,19 +2152,22 @@ class OrgTreeNextLevel(generic.View):
     @rest_utils.ajax()
     def get(self, request, domain_id):
         org_tree_manager = OrgTreeManager()
-        subdomains = api.keystone.get_subsets(request, domain_id, True, admin=False)
-        projects = api.keystone.tenant_list(request, domain=domain_id, admin=False)[0]
-        projects = [project for project in projects if project.name not in OPENSTACK_PROJECT]
+        subdomains = api.keystone.get_subsets(
+            request, domain_id, True, admin=False)
+        projects = api.keystone.tenant_list(
+            request, domain=domain_id, admin=False)[0]
+        projects = [project for project in projects if
+                    project.name not in OPENSTACK_PROJECT]
         domain_nodes = org_tree_manager.getDomainNodes(subdomains)
         project_nodes = org_tree_manager.getProjectNodes(projects)
 
         return {'items': {
-            'domain_nodes' : domain_nodes,
-            'project_nodes' : project_nodes
+            'domain_nodes': domain_nodes,
+            'project_nodes': project_nodes
         }}
 
 
-class OrgTreeManager():
+class OrgTreeManager(object):
 
     def get_cloud_admin_init_tree(self, request):
         nodes = []
@@ -2054,11 +2175,11 @@ class OrgTreeManager():
                 'name': trans('Cloud Platform'),
                 'node_type': 'cloud_platform',
                 'forbidden': True,
-                'nodes': []
-               }
+                'nodes': []}
         user_domain_id = request.user.user_domain_id
         root_domains = api.keystone.root_domain_list(request)
-        root_domains = [domain for domain in root_domains if domain.name not in OPENSTACK_DOMAIN]
+        root_domains = [domain for domain in root_domains if
+                        domain.name not in OPENSTACK_DOMAIN]
         default_domain_node = None
         for domain in root_domains:
             node = {'id': domain.id,
@@ -2083,7 +2204,8 @@ class OrgTreeManager():
         admin_domains = api.keystone.get_user_admin_role_domains(request, user)
         subdomains = api.keystone.get_subsets(request, user_domain_id)
         if api.keystone.user_is_domain_admin(request, user.id, user_domain_id):
-            default_doman = api.keystone.domain_get(request,user_domain_id, admin=False)
+            default_doman = api.keystone.domain_get(
+                request, user_domain_id, admin=False)
             subdomains.append(default_doman)
 
         id_domain_map = {}
@@ -2093,8 +2215,7 @@ class OrgTreeManager():
         root = {'id': 'cloud_platform',
                 'name': trans('Cloud Platform'),
                 'forbidden': True,
-                'nodes': []
-               }
+                'nodes': []}
         for domain in admin_domains:
             domain_node = self.get_domain_node_from_tree(root, domain['id'])
             if domain_node:
@@ -2102,7 +2223,8 @@ class OrgTreeManager():
                 domain_node['nodes'] = []
                 domain_node['is_admin_node'] = True
             else:
-                path_nodes = self.get_tree_path_nodes(request, id_domain_map[domain['id']])
+                path_nodes = self.get_tree_path_nodes(
+                    request, id_domain_map[domain['id']])
                 self.merge_path_nodes_to_tree_node(root, path_nodes)
 
         return root
@@ -2113,7 +2235,8 @@ class OrgTreeManager():
         admin_domains = api.keystone.get_user_admin_role_domains(request, user)
         subdomains = api.keystone.get_subsets(request, user_domain_id)
         if api.keystone.user_is_domain_admin(request, user.id, user_domain_id):
-            default_doman = api.keystone.domain_get(request,user_domain_id, admin=False)
+            default_doman = api.keystone.domain_get(
+                request, user_domain_id, admin=False)
             subdomains.append(default_doman)
 
         id_domain_map = {}
@@ -2124,17 +2247,18 @@ class OrgTreeManager():
                 'name': trans('Cloud Platform'),
                 'forbidden': True,
                 'collapsed': False,
-                'nodes': []
-               }
+                'nodes': []}
         for domain in admin_domains:
-            domain_node = self.get_bill_domain_node_from_tree(root, domain['id'])
+            domain_node = self.get_bill_domain_node_from_tree(
+                root, domain['id'])
             if domain_node:
                 domain_node['forbidden'] = False
                 domain_node['collapsed'] = True
                 domain_node['nodes'] = [{'id': ' ', 'name': ' '}]
                 domain_node['is_admin_node'] = True
             else:
-                path_nodes = self.get_bill_tree_path_nodes(request, id_domain_map[domain['id']])
+                path_nodes = self.get_bill_tree_path_nodes(
+                    request, id_domain_map[domain['id']])
                 self.merge_bill_path_nodes_to_tree_node(root, path_nodes)
 
         return root
@@ -2148,7 +2272,8 @@ class OrgTreeManager():
 
         if matched_node:
             if matched_node['nodes'] and path_nodes['nodes']:
-                self.merge_path_nodes_to_tree_node(matched_node, path_nodes['nodes'][0])
+                self.merge_path_nodes_to_tree_node(
+                    matched_node, path_nodes['nodes'][0])
             else:
                 matched_node['forbidden'] = False
                 matched_node['nodes'] = []
@@ -2161,17 +2286,19 @@ class OrgTreeManager():
     def merge_bill_path_nodes_to_tree_node(self, node, path_nodes):
         matched_node = None
         for child_node in node['nodes']:
-            if child_node['id']!= ' ' and child_node['id'] == path_nodes['id']:
+            if child_node['id'] != ' ' and \
+                    child_node['id'] == path_nodes['id']:
                 matched_node = child_node
                 break
 
         if matched_node:
-            if matched_node['nodes'] and path_nodes['nodes'] :
+            if matched_node['nodes'] and path_nodes['nodes']:
                 if not (len(matched_node['nodes']) == 1
                         and len(path_nodes['nodes']) == 1
                         and (matched_node['nodes'][0]['id'] == ' '
                         or path_nodes['nodes'][0]['id'] == ' ')):
-                    self.merge_bill_path_nodes_to_tree_node(matched_node, path_nodes['nodes'][0])
+                    self.merge_bill_path_nodes_to_tree_node(
+                        matched_node, path_nodes['nodes'][0])
             else:
                 matched_node['forbidden'] = False
                 matched_node['collapsed'] = True
@@ -2180,26 +2307,28 @@ class OrgTreeManager():
         else:
             node['nodes'].append(path_nodes)
 
-    def get_domain_node_from_tree (self, node, domain_id):
+    def get_domain_node_from_tree(self, node, domain_id):
         domain_node = None
         if node['id'] == domain_id:
             domain_node = node
         else:
             for child_node in node['nodes']:
-                domain_node = self.get_domain_node_from_tree(child_node, domain_id)
+                domain_node = self.get_domain_node_from_tree(
+                    child_node, domain_id)
                 if domain_node:
                     break
 
         return domain_node
 
-    def get_bill_domain_node_from_tree (self, node, domain_id):
+    def get_bill_domain_node_from_tree(self, node, domain_id):
         domain_node = None
         if node['id'] != ' ':
             if node['id'] == domain_id:
                 domain_node = node
             else:
                 for child_node in node['nodes']:
-                    domain_node = self.get_bill_domain_node_from_tree(child_node, domain_id)
+                    domain_node = self.get_bill_domain_node_from_tree(
+                        child_node, domain_id)
                     if domain_node:
                         break
 
@@ -2285,7 +2414,9 @@ class OrgTreeManager():
 
 @urls.register
 class OrgAllProjects(generic.View):
-    """API over projects belonging to a org admin, when IDENTITY_MULTI_LEVEL is True.
+    """API over projects belonging to a org admin,
+
+    when IDENTITY_MULTI_LEVEL is True.
 
     """
     url_regex = r'keystone/orgallprojects/$'
@@ -2293,18 +2424,21 @@ class OrgAllProjects(generic.View):
     def _get_org_admin_all_projects(self, request):
         ret_projects = []
         domain_id_name_dict = {}
-        admin_role_domains = api.keystone.get_user_admin_role_domains(request, request.user)
+        admin_role_domains = api.keystone.get_user_admin_role_domains(
+            request, request.user)
         for domain in admin_role_domains:
             domain_id_name_dict[domain.get('id')] = domain.get('name')
-            sub_domains = api.keystone.get_subsets(request, domain.get('id'), admin=False)
+            sub_domains = api.keystone.get_subsets(
+                request, domain.get('id'), admin=False)
             for sub_domain in sub_domains:
                 domain_id_name_dict[sub_domain.id] = sub_domain.name
 
-        for domain_id,domain_name in domain_id_name_dict.iteritems():
+        for domain_id, domain_name in domain_id_name_dict.iteritems():
             if not domain_name:
                 domain = api.keystone.domain_get(request, domain_id, False)
                 domain_name = domain.name
-            projects = api.keystone.tenant_list(request, domain= domain_id, admin=False)[0]
+            projects = api.keystone.tenant_list(
+                request, domain=domain_id, admin=False)[0]
             for project in projects:
                 project_dict = project.to_dict()
                 project_dict['domain_name'] = domain_name
@@ -2318,16 +2452,20 @@ class OrgAllProjects(generic.View):
             domain_id = project.get('domain_id')
             if domain_id not in org_structure_dict:
                 domain_name = project.get('domain_name')
-                domain_names = [domain_name] + api.keystone.get_domain_parent_names(request, project.get('domain_id'))
+                domain_names = ([domain_name] +
+                                api.keystone.get_domain_parent_names(
+                                    request, project.get('domain_id')))
                 domain_names.reverse()
-                org_structure_dict[domain_id] = '/%s' % ' / '.join(domain_names)
+                org_structure_dict[domain_id] = '/%s' % ' / '.join(
+                    domain_names)
 
             project['org_structure'] = org_structure_dict.get(domain_id)
         return projects
 
     def filter_system_projects(self, projects):
         system_project_structures = ['/%s' % name for name in OPENSTACK_DOMAIN]
-        projects = [project for project in projects if project.get('org_structure') not in system_project_structures]
+        projects = [project for project in projects if project.get(
+            'org_structure') not in system_project_structures]
         return projects
 
     @rest_utils.ajax()
@@ -2336,7 +2474,8 @@ class OrgAllProjects(generic.View):
             return []
 
         if api.keystone.is_cloud_admin(request):
-            projects = [project.to_dict() for project in api.keystone.tenant_list(request)[0]
+            projects = [project.to_dict() for project in
+                        api.keystone.tenant_list(request)[0]
                         if project.name not in OPENSTACK_PROJECT]
             ensure_domain_name(request, projects, with_domain=False)
         elif api.keystone.is_org_admin(request):
@@ -2347,11 +2486,14 @@ class OrgAllProjects(generic.View):
         self._ensure_project_org_structure(request, projects)
         projects = self.filter_system_projects(projects)
 
-        return {'items' : projects}
+        return {'items': projects}
+
 
 @urls.register
 class OrgAllUsers(generic.View):
-    """API over users belonging to a org admin,cloudamdin, when IDENTITY_MULTI_LEVEL is True.
+    """API over users belonging to a org admin,
+
+    cloudamdin, when IDENTITY_MULTI_LEVEL is True.
 
     """
     url_regex = r'keystone/orgallusers/$'
@@ -2359,10 +2501,12 @@ class OrgAllUsers(generic.View):
     def _get_org_admin_all_users(self, request):
         users = []
         domain_ids = set()
-        admin_role_domains = api.keystone.get_user_admin_role_domains(request, request.user)
+        admin_role_domains = api.keystone.get_user_admin_role_domains(
+            request, request.user)
         for domain in admin_role_domains:
             domain_ids.add(domain.get('id'))
-            sub_domains = api.keystone.get_subsets(request, domain.get('id'), admin=False)
+            sub_domains = api.keystone.get_subsets(
+                request, domain.get('id'), admin=False)
             for sub_domain in sub_domains:
                 domain_ids.add(sub_domain.id)
 
@@ -2374,9 +2518,10 @@ class OrgAllUsers(generic.View):
 
     def _get_org_cloud_admin_all_users(self, request):
         users = []
-        domains = [domain for domain in api.keystone.domain_list(request) if domain.name not in OPENSTACK_DOMAIN]
+        domains = [domain for domain in api.keystone.domain_list(
+            request) if domain.name not in OPENSTACK_DOMAIN]
         for domain in domains:
-            users.extend(api.keystone.user_list(request, domain= domain.id))
+            users.extend(api.keystone.user_list(request, domain=domain.id))
         users = [user.to_dict() for user in users]
 
         return users
@@ -2386,10 +2531,14 @@ class OrgAllUsers(generic.View):
         for user in users:
             domain_id = user.get('domain_id')
             if domain_id not in org_structure_dict:
-                domain = api.keystone.domain_get(request, domain_id, admin=False)
-                domain_names = [domain.name] + api.keystone.get_domain_parent_names(request, domain_id)
+                domain = api.keystone.domain_get(
+                    request, domain_id, admin=False)
+                domain_names = ([domain.name] +
+                                api.keystone.get_domain_parent_names(
+                                    request, domain_id))
                 domain_names.reverse()
-                org_structure_dict[domain_id] = '/%s' % ' / '.join(domain_names)
+                org_structure_dict[domain_id] = '/%s' % ' / '.join(
+                    domain_names)
 
             user['org_structure'] = org_structure_dict.get(domain_id)
         return users
@@ -2405,10 +2554,12 @@ class OrgAllUsers(generic.View):
             users = self._get_org_admin_all_users(request)
         else:
             users = []
-        users = [user for user in users if user.get('name') not in OPENSTACK_USER]
+        users = [user for user in users if user.get(
+            'name') not in OPENSTACK_USER]
         self._ensure_user_org_structure(request, users)
 
-        return {'items' : users}
+        return {'items': users}
+
 
 @urls.register
 class GetAllotTicketUsers(generic.View):
@@ -2422,7 +2573,8 @@ class GetAllotTicketUsers(generic.View):
 
         allot_users = []
         for user in users:
-            isAdmin = user.get('roles') and api.keystone.has_admin_role(request, user['roles'])
+            isAdmin = user.get('roles') and api.keystone.has_admin_role(
+                request, user['roles'])
             not_openstack_user = user.get('name') not in OPENSTACK_USER
             if isAdmin and not_openstack_user:
                 allot_users.append(user)
diff --git a/easystack_dashboard/test/api_tests/keystone_rest_tests.py b/easystack_dashboard/test/api_tests/keystone_rest_tests.py
index 5e7a765..ca02e0a 100644
--- a/easystack_dashboard/test/api_tests/keystone_rest_tests.py
+++ b/easystack_dashboard/test/api_tests/keystone_rest_tests.py
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import json
+
 from django.conf import settings
 import mock
 from oslo_serialization import jsonutils
@@ -691,3 +693,116 @@ class KeystoneRestTestCase(test.TestCase):
         response = keystone.Services().get(request)
         self.assertStatusCode(response, 200)
         kc.Service.assert_called_once_with(mock_service, "some region")
+
+    #
+    # NotifyList
+    #
+    @mock.patch.object(keystone.api, 'keystone')
+    def test_notify_list_get_with_not_include_self(self, kc):
+        request = self.mock_rest_request()
+        request.user = mock.Mock(roles=[{
+            u'id': u'36cad7469ba04df68eeeb227dc2dc8f5',
+            u'name': u'admin'
+        }])
+        name = 'chen'
+        email = '1277@qq.com'
+        kc.is_cloud_admin.return_value = True
+        kc.user_get.return_value.to_dict.return_value = {
+            'name': name,
+            'email': email
+        }
+        kc.user_update.return_value = None
+        response = keystone.NotifyList().get(request)
+        result = json.loads(response.content.decode('utf-8'))
+        items = [{'email': [{'tag': '', 'value': '1277@qq.com'}],
+                  'sms': [{'tag': '', 'value': None}],
+                  'name': 'chen',
+                  'description':
+                      'Send notification to registered email and mobile'}]
+        expectedResult = {'items': items}
+        self.assertEqual(result, expectedResult)
+
+    @mock.patch.object(keystone.api, 'keystone')
+    def test_notify_list_get_with_include_self(self, kc):
+        request = self.mock_rest_request()
+        request.user = mock.Mock(roles=[{
+            u'id': u'36cad7469ba04df68eeeb227dc2dc8f5',
+            u'name': u'admin'
+        }])
+        name = 'chen'
+        email = '1277@qq.com'
+        kc.is_cloud_admin.return_value = True
+        kc.user_get.return_value.to_dict.return_value = {
+            'name': name,
+            'email': email,
+            'notify_list': [{
+                'email': [{'tag': '', 'value': '1277@qq.com'}],
+                'sms': [{'tag': '', 'value': None}],
+                'name': 'chen',
+                'description':
+                    'Send notification to registered email and mobile'}]
+        }
+        kc.user_update.return_value = None
+        response = keystone.NotifyList().get(request)
+        result = json.loads(response.content.decode('utf-8'))
+        items = [{'email': [{'tag': '', 'value': '1277@qq.com'}],
+                  'sms': [{'tag': '', 'value': None}],
+                  'name': 'chen',
+                  'description':
+                      'Send notification to registered email and mobile'}]
+        expectedResult = {'items': items}
+        self.assertEqual(result, expectedResult)
+
+    @mock.patch.object(keystone.api, 'keystone')
+    def test_notify_list_put_with_data(self, kc):
+        data = {
+            u'email': [{u'tag': u'', u'value': u'1277@qq.com'},
+                       {u'tag': u'', u'value': u'chen@example.org'}],
+            u'sms': [{u'tag': u'', u'value': None}],
+            u'name': u'chen',
+            u'description':
+                u'Send notification to registered email and mobile'}
+        mock_data = json.dumps(data)
+        request = self.mock_rest_request(POST={}, body=mock_data)
+        request.user = mock.Mock(roles=[{
+            u'id': u'36cad7469ba04df68eeeb227dc2dc8f5',
+            u'name': u'admin'
+        }])
+        kc.is_cloud_admin.return_value = True
+        kc.user_get.return_value.to_dict.return_value = {
+            u'notify_list': [
+                {u'sms': [{u'tag': u'', u'value': None}],
+                 u'description':
+                     u'Send notification to registered email and mobile',
+                 u'name': u'chen',
+                 u'email': [{u'tag': u'', u'value': u'1277@qq.com'},
+                            {u'tag': u'', u'value': u'chen@example.org'}]}
+            ]
+        }
+        kc.user_update.return_value = None
+        response = keystone.NotifyList().put(request)
+        self.assertStatusCode(response, 202)
+
+    @mock.patch.object(keystone.api, 'keystone')
+    def test_notify_list_put_without_data(self, kc):
+        data = {}
+        mock_data = json.dumps(data)
+        request = self.mock_rest_request(POST={}, body=mock_data)
+        request.user = mock.Mock(roles=[{
+            u'id': u'36cad7469ba04df68eeeb227dc2dc8f5',
+            u'name': u'admin'
+        }])
+        kc.is_cloud_admin.return_value = True
+        kc.user_get.return_value.to_dict.return_value = {
+            u'notify_list': [
+                {u'sms': [{u'tag': u'', u'value': None}],
+                 u'description':
+                     u'Send notification to registered email and mobile',
+                 u'name': u'chen',
+                 u'email': [{u'tag': u'', u'value': u'1277@qq.com'},
+                            {u'tag': u'', u'value': u'chen@example.org'}]}
+            ]
+        }
+        kc.user_update.return_value = None
+        response = keystone.NotifyList().put(request)
+        self.assertStatusCode(response, 400)
diff --git a/tox.ini b/tox.ini
index cbb9817..d99e0d9 100755
--- a/tox.ini
+++ b/tox.ini
@@ -77,7 +77,7 @@ commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasen
 [flake8]
 exclude = .venv,.git,.tox,dist,*openstack/common*,*lib/python*,*egg,build,panel_template,dash_template,local_settings.py,*/local/*,*/test/test_plugins/*,.ropeproject
 # H405 multi line docstring summary not separated with an empty line
-ignore = H405
+ignore = H405,H701,C901
 max-complexity = 20
 
 [hacking]
-- 
2.7.4

jackdan@jackdan-ThinkPad-T430:~/work/fp10/horizon$ 
  • Example - git format-patch HEAD^^
jackdan@jackdan-ThinkPad-T430:~/work/fp10/horizon$ git format-patch HEAD^^
0001-fix-bug-error-of-export-billing.patch
0002-ESFIX-Fix-exited-horizon-when-created-alarm-sometime.patch
jackdan@jackdan-ThinkPad-T430:~/work/fp10/horizon$ cat 0001-fix-bug-error-of-export-billing.patch 
From 74059bda8452794ddb08e0861675f1ca9cf4945d Mon Sep 17 00:00:00 2001
From: muyanli <yanli.mou@easystack.cn>
Date: Thu, 9 Aug 2018 16:13:57 +0800
Subject: [PATCH 1/2] fix bug error of export billing

Change-Id: I53ede97a487641b1937df8503a06f0b720e99b81
Close-bug: #EAS-17641
---
 .../dashboards/admin/bill_multi_level/views.py     | 201 ++++++++++++++-------
 .../test/test_plugins/bill_views_test.py           |  69 +++++++
 2 files changed, 204 insertions(+), 66 deletions(-)
 create mode 100644 easystack_dashboard/test/test_plugins/bill_views_test.py

diff --git a/easystack_dashboard/dashboards/admin/bill_multi_level/views.py b/easystack_dashboard/dashboards/admin/bill_multi_level/views.py
index 8f46cfa..cc2276f 100755
--- a/easystack_dashboard/dashboards/admin/bill_multi_level/views.py
+++ b/easystack_dashboard/dashboards/admin/bill_multi_level/views.py
@@ -1,20 +1,34 @@
-from django import shortcuts
-from easystack_dashboard.api import keystone
+# Copyright 2017 EasyStack, 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 datetime import datetime
+from datetime import timedelta
+from dateutil.parser import parse
+import pytz
+import time
+
 from django.conf import settings
+from django.http.response import HttpResponse
+from django import shortcuts
+from django.utils.datastructures import SortedDict
+from django.utils.translation import gettext as trans
 from django.utils.translation import ugettext as _
+
 from easystack_dashboard.api import billing
-from easystack_dashboard.api import ceilometer
+from easystack_dashboard.api import keystone
 from easystack_dashboard.api.rest import ceilometer as cei
-from django.utils.datastructures import SortedDict
 from easystack_dashboard.utils.xls_util import XLSWriter
-from django.http.response import HttpResponse
-from datetime import datetime
-from datetime import timedelta
-from django.utils.translation import gettext as trans
 import horizon
-import time
-import pytz
-from dateutil.parser import parse
 
 
 status_dic = {-1: 'deleted',
@@ -22,10 +36,13 @@ status_dic = {-1: 'deleted',
               1: 'active',
               2: 'suspend',
               3: 'stop'}
-xls_products_fields = ('resource_name', 'ptype', 'org_relation', 'cost', 'unit', 'fee', 'runtime', 'update_at', 'create_at')
+xls_products_fields = ('resource_name', 'ptype', 'org_relation',
+                       'cost', 'unit', 'fee', 'runtime',
+                       'update_at', 'create_at')
 xls_overview_fields = ('org_name', 'org_relation', 'cost')
 
-OPENSTACK_DOMAIN = ('heat_domain', 'magnum', 'ironic', 'trove', ' magnum_domain_admin')
+OPENSTACK_DOMAIN = ('heat_domain', 'magnum',
+                    'ironic', 'trove', ' magnum_domain_admin')
 
 
 def logout(request):
@@ -45,42 +62,70 @@ def products_download(request, date_span):
 
     if allow_download:
         params = date_span.split('_')
-        timesuffix = parse(get_local_date(request, parse(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())),
-                                          timezone='Asia/Shanghai')).strftime('%H:%M:%S')
+        timesuffix = \
+            parse(get_local_date(
+                request, parse(time.strftime("%Y-%m-%d %H:%M:%S",
+                                             time.localtime())),
+                timezone='Asia/Shanghai')).strftime('%H:%M:%S')
         if(params[1] == 'all'):
-            start_time = get_local_date(request, parse('1970-01-01' + ' ' + timesuffix), 'Etc/GMT+8')
-            end_index = parse(get_local_date(request, parse(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())),timezone='Asia/Shanghai'))
-            end_time = get_local_date(request, parse(end_index), 'Etc/GMT+8')
+            start_time = \
+                get_local_date(request,
+                               parse('1970-01-01' + ' ' + timesuffix),
+                               'Etc/GMT+8')
+            end_index = \
+                parse(get_local_date(request,
+                                     parse(time.strftime("%Y-%m-%d %H:%M:%S",
+                                                         time.localtime())),
+                                     timezone='Asia/Shanghai'))
+            end_time = get_local_date(request, end_index, 'Etc/GMT+8')
         elif params[1] == 'month':
-            start_index = parse(get_local_date(request, datetime.now() - timedelta(days=30)))
-            end_index = parse(get_local_date(request, parse(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())),
-                                             timezone='Asia/Shanghai'))
+            start_index = \
+                parse(get_local_date(
+                    request, datetime.now() - timedelta(days=30)))
+            end_index = \
+                parse(get_local_date(
+                    request,
+                    parse(time.strftime("%Y-%m-%d %H:%M:%S",
+                                        time.localtime())),
+                    timezone='Asia/Shanghai'))
             start_time = get_local_date(request, start_index, 'Etc/GMT+8')
             end_time = get_local_date(request, end_index, 'Etc/GMT+8')
         else:
-            start_time = get_local_date(request, parse(params[1] + ' ' + '00:00:00'), 'Etc/GMT+8')
-            end_time = get_local_date(request, parse(params[2] + ' ' + '00:00:00')+ timedelta(days=1), 'Etc/GMT+8')
+            start_time = get_local_date(
+                request, parse(params[1] + ' ' + '00:00:00'), 'Etc/GMT+8')
+            end_time = get_local_date(
+                request,
+                parse(params[2] + ' ' + '00:00:00') + timedelta(days=1),
+                'Etc/GMT+8')
 
         overview = _get_overview(request, params[0], start_time, end_time)
         products = _get_products(request, params[0], start_time, end_time)
         overview_data = [_filter_overview_fields(over) for over in overview]
-        product_data = [_filter_product_fields(product) for product in products]
+        product_data = [
+            _filter_product_fields(product) for product in products]
         products.sort(key=_product_comp_fun, reverse=True)
         xls_overview_datas = overview_data
         xls_products_datas = product_data
 
         response = HttpResponse(content_type='application/vnd.ms-excel')
-        response['Content-Disposition'] = 'attachment;filename="{0}"'.format('bills.xls')
+        response['Content-Disposition'] = \
+            'attachment;filename="{0}"'.format('bills.xls')
 
-        xls_overview_header = (_('Org Name'), _('Org relation'), _('Cost(yuan)'))
-        xls_products_header = (_('Resource Name'), _('Resource Types'),_('Org relation'),  _('Cost(yuan)'), _('Billing Type'), _('Price(yuan)'),
-              _('RunTime'), _('Update Time'), _('Create Time'))
+        xls_overview_header = (_('Org Name'),
+                               _('Org relation'), _('Cost(yuan)'))
+        xls_products_header = (_('Resource Name'), _('Resource Types'),
+                               _('Org relation'), _('Cost(yuan)'),
+                               _('Billing Type'), _('Price(yuan)'),
+                               _('RunTime'), _('Update Time'),
+                               _('Create Time'))
 
         xls_writer = XLSWriter(response)
         xls_writer.add_sheet(xls_overview_header, trans('Bill Overview'))
         xls_writer.add_sheet(xls_products_header, trans('Bill Detail'))
-        xls_writer.add_rows(xls_overview_datas, sheet_name=trans('Bill Overview'))
-        xls_writer.add_rows(xls_products_datas, sheet_name=trans('Bill Detail'))
+        xls_writer.add_rows(xls_overview_datas,
+                            sheet_name=trans('Bill Overview'))
+        xls_writer.add_rows(xls_products_datas,
+                            sheet_name=trans('Bill Detail'))
         xls_writer.save()
         return response
     else:
@@ -90,7 +135,8 @@ def products_download(request, date_span):
 
 
 def _get_overview(request, org_id, start_time, end_time):
-    params = ['organization_id=' + org_id, 'start_at=' + start_time.replace('T', ' '),
+    params = ['organization_id=' + org_id,
+              'start_at=' + start_time.replace('T', ' '),
               'end_at=' + end_time.replace('T', ' ')]
     curr_org = org_id
     overviewList = billing.get_bill_overview_by_org(request, params)
@@ -106,7 +152,8 @@ def _get_overview(request, org_id, start_time, end_time):
         if domain_dict.get(org_id, None):
             domain = domain_dict.get(org_id, None)
             org_relation = getattr(domain, 'name')
-            org_relation = get_parents_org_relation_str(domain, domain_dict, org_relation)
+            org_relation = get_parents_org_relation_str(
+                domain, domain_dict, org_relation)
             setattr(o, 'org_relation', org_relation)
             setattr(o, 'org_name', getattr(domain, 'name'))
         else:
@@ -115,7 +162,8 @@ def _get_overview(request, org_id, start_time, end_time):
             domain = domain_dict.get(domain_id, None)
             org_relation = getattr(tenant, 'name')
             org_relation = getattr(domain, 'name') + '/' + org_relation
-            org_relation = get_parents_org_relation_str(domain, domain_dict, org_relation)
+            org_relation = get_parents_org_relation_str(
+                domain, domain_dict, org_relation)
             setattr(o, 'org_relation', org_relation)
             setattr(o, 'org_name', getattr(tenant, 'name'))
         org_dict = o.to_dict()
@@ -132,9 +180,13 @@ def _get_overview(request, org_id, start_time, end_time):
             totalName = trans('Cloud Platform')
         else:
             totalName = getattr(totalDomain, 'name')
-        totalRelation = get_parents_org_relation_str(totalDomain, domain_dict, totalName)
+        totalRelation = get_parents_org_relation_str(
+            totalDomain, domain_dict, totalName)
         items.append(
-            {'organization_id': curr_org, 'org_name': totalName, 'org_relation': totalRelation, 'cost': totalCost})
+            {'organization_id': curr_org,
+             'org_name': totalName,
+             'org_relation': totalRelation,
+             'cost': totalCost})
     return items
 
 
@@ -143,14 +195,20 @@ def get_domain_dict(request):
         domains = keystone.domain_list(request)
         domain_dict = SortedDict([(d.id, d) for d in domains])
     else:
-        domains = keystone.get_subsets(request, request.user.user_domain_id, False)
-        parents = keystone.get_parents(request, request.user.user_domain_id, False)
+        domains = keystone.get_subsets(
+            request, request.user.user_domain_id, False)
+        parents = keystone.get_parents(
+            request, request.user.user_domain_id, False)
         parents_dict = SortedDict([(d.id, d) for d in parents])
-        domain_dict = dict(SortedDict([(d.id, d) for d in domains]), **parents_dict)
+        domain_dict = \
+            dict(SortedDict([(d.id, d) for d in domains]), **parents_dict)
         if (keystone.is_domain_admin(request)[1]):
-            curr = keystone.domain_get(request, request.user.user_domain_id)
-            domain_dict = dict(domain_dict, **SortedDict([(d.id, d) for d in [curr]]))
-            # TODO : if user is only project admin but not domain admin
+            curr = keystone.domain_get(
+                request, request.user.user_domain_id)
+            domain_dict = \
+                dict(domain_dict, **SortedDict([(d.id, d) for d in [curr]]))
+            # TODO(name) : if user is
+            # only project admin but not domain admin
     return domain_dict
 
 
@@ -160,13 +218,16 @@ def get_tenant_dict(request, curr_org):
         tenant_dict = SortedDict([(t.id, t) for t in tenants])
     else:
         if (keystone.is_domain_admin(request)[1]):
-            self_tenants, self_has_more = keystone.tenant_list(request)
+            self_tenants, self_has_more = \
+                keystone.tenant_list(request)
             tenants = []
             try:
-                tenants, has_more = keystone.tenant_list(request, domain=curr_org)
+                tenants, has_more = keystone.tenant_list(
+                    request, domain=curr_org)
 
             except Exception:
-                # if not found , it proved to be a project and just fetch the project name
+                # if not found ,
+                # it proved to be a project and just fetch the project name
                 try:
                     tenant = keystone.tenant_get(request, curr_org)
                     tenants = [tenant]
@@ -185,15 +246,19 @@ def get_tenant_dict(request, curr_org):
 
 def _get_products(request, org_id, start_time, end_time):
     def manage_resource_name(product_dict):
-        resource = cei.get_resource_info(request, product_dict.get('resource_id'))
+        resource = cei.get_resource_info(
+            request, product_dict.get('resource_id'))
         if resource.get('resource_name'):
             product_dict.update(
                 {'resource_name': resource.get('resource_name')})
         else:
-            product_dict.update({'resource_name': product_dict.get('resource_id')})
+            product_dict.update(
+                {'resource_name': product_dict.get('resource_id')})
         return product_dict
 
-    params = ['organization_id=' + org_id, 'start_at=' + start_time, 'end_at=' + end_time, 'predict=False']
+    params = ['organization_id=' + org_id,
+              'start_at=' + start_time, 'end_at=' + end_time,
+              'predict=False']
     detailDict = billing.get_bill_detail_by_org(request, params)
     productList = detailDict.get('products')
 
@@ -211,7 +276,8 @@ def _get_products(request, org_id, start_time, end_time):
         org_relation = getattr(project, 'name')
         if domain:
             org_relation = getattr(domain, 'name') + '/' + org_relation
-            org_relation = get_parents_org_relation_str(domain, domain_dict, org_relation)
+            org_relation = get_parents_org_relation_str(
+                domain, domain_dict, org_relation)
             setattr(p, 'org_relation', org_relation)
             product_dict = p.to_dict()
             product_dict['org_relation'] = getattr(p, 'org_relation')
@@ -253,13 +319,15 @@ def _trans_overview_fields(data):
 def _unit_format(unit):
     return trans(unit)
 
+
 def _runtime_format(seconds):
-    if not isinstance(seconds,int):
+    if not isinstance(seconds, int):
         return ''
-    hours = seconds/3600
-    minutes = seconds%3600/60
-    seconds = seconds%3600%60
-    runtime_str_format = '{0}' + _('Hour') + '{1}' + _('Minutes') + '{2}' + _('seconds')
+    hours = seconds / 3600
+    minutes = seconds % 3600 / 60
+    seconds = seconds % 3600 % 60
+    runtime_str_format = \
+        '{0}' + _('Hour') + '{1}' + _('Minutes') + '{2}' + _('seconds')
     return runtime_str_format.format(hours, minutes, seconds)
 
 
@@ -268,9 +336,10 @@ def _time_format(datetime_str):
     if not datetime_str:
         return ''
     try:
-        new_datetime = datetime.strptime(datetime_str, datetime_format) + timedelta(hours=8)
+        new_datetime = datetime.strptime(
+            datetime_str, datetime_format) + timedelta(hours=8)
         return new_datetime.strftime(datetime_format)
-    except:
+    except Exception:
         return ''
 
 
@@ -279,8 +348,9 @@ def _product_comp_fun(product):
     if create_at is None:
         return -1
     try:
-        second = int(time.mktime(time.strptime(create_at, '%Y-%m-%d %H:%M:%S')))
-    except:
+        second = int(time.mktime(
+            time.strptime(create_at, '%Y-%m-%d %H:%M:%S')))
+    except Exception:
         return -1
     return second
 
@@ -288,9 +358,6 @@ def _product_comp_fun(product):
 def get_local_date(request, time, timezone='Asia/Shanghai'):
     # Todo(gcb) get timezone from django, current it always
     # returns UTC.
-    current_tz = request.session.get(
-        'django_timezone',
-        request.COOKIES.get('django_timezone', 'UTC')),
     dt = parse(time.isoformat() + "+00")
     return dt.astimezone(
         pytz.timezone(timezone)).strftime('%Y-%m-%d %H:%M:%S')
@@ -307,17 +374,18 @@ def _get_resource_info(request, resourceid):
         if hasattr(resource, "type"):
             res_type = resource.type
         else:
-            if resource.metadata.has_key('event_type'):
+            if 'event_type' in resource.metadata.keys():
                 res_type = resource.metadata.get('event_type')
                 res_type = res_type.split('.')[0]
-            if resource.metadata.has_key('floating_ip_address'):
+            if 'floating_ip_address' in resource.metadata.keys():
                 res_type = 'floatingip'
         mac = resource.metadata.get('mac')
         if mac is not None and not name:
             try:
                 name = cei.resource_get(
-                    request, resource.metadata.get('instance_id')).resource_name
-            except Exception as e:
+                    request,
+                    resource.metadata.get('instance_id')).resource_name
+            except Exception:
                 pass
         dic.update({'resource_name': name})
         dic.update({'resource_id': resourceid})
@@ -333,9 +401,10 @@ def get_parents_org_relation_str(domain, domain_dict, org_relation_str):
             for p in parents:
                 p_domain = domain_dict.get(p, None)
                 if p_domain:
-                    org_relation = getattr(p_domain, 'name') + '/' + org_relation
+                    org_relation = \
+                        getattr(p_domain, 'name') + '/' + org_relation
         else:
             org_relation = org_relation_str
     else:
         org_relation = org_relation_str
-    return org_relation
\ No newline at end of file
+    return org_relation
diff --git a/easystack_dashboard/test/test_plugins/bill_views_test.py b/easystack_dashboard/test/test_plugins/bill_views_test.py
new file mode 100644
index 0000000..f9863e6
--- /dev/null
+++ b/easystack_dashboard/test/test_plugins/bill_views_test.py
@@ -0,0 +1,69 @@
+# Copyright 2017 EasyStack, 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.http.response import HttpResponse
+from django.test.utils import override_settings
+import mock
+
+from easystack_dashboard.dashboards.admin.bill_multi_level import views
+from easystack_dashboard.test import helpers as test
+
+
+class ProductLoad(test.APITestCase):
+    @override_settings(ENABLE_BILLING=True)
+    @mock.patch('api.keystone.is_default_domain_admin')
+    @mock.patch('easystack_dashboard.dashboards.admin.bill_multi_level.'
+                'views._get_overview')
+    @mock.patch('easystack_dashboard.dashboards.admin.bill_multi_level.'
+                'views._get_products')
+    def test_download_product(self, mock_get_products,
+                              mock_get_overview,
+                              mock_is_default_doamin_admin):
+        mock_is_default_doamin_admin.return_value = (True, True)
+        mock_get_overview.return_value = \
+            [{u'organization_id': u'01920b61971349a4b02940df34640d61',
+              'org_name': u'test2', u'cost': 0.0,
+              'org_relation': u'test2'},
+             {u'organization_id': u'732b817d4b4b485e893617c7fc4b434b',
+              'org_name': u'test1', u'cost': 0.001667,
+              'org_relation': u'test1'},
+             {'organization_id': u'default',
+              'org_name': '\xe4\xba\x91\xe5\xb9\xb3\xe5\x8f\xb0',
+              'cost': 0.001667,
+              'org_relation': '\xe4\xba\x91\xe5\xb9\xb3\xe5\x8f\xb0'}]
+        mock_get_products.return_value = \
+            [{'resource_id': u'681c718f-c5fb-43e0-9e62-d8975358f4a5',
+              'price_fixing_fee': None, 'ptype': u'router',
+              'cost': 0.001667, 'priceitem_id': 4, 'id': 1,
+              'price_fixing_start': None, 'account_id': 1,
+              'fee': 0.01,
+              'domain_id': u'732b817d4b4b485e893617c7fc4b434b',
+              'version': 2, 'unit': u'H', 'provider': u'openstack',
+              'project_id': u'92c91cb741384783b83da6b5815a29c3',
+              'org_relation': u'test1/prj1', 'status': 1,
+              'event_ms': 607000, 'orginal_unit': None,
+              'event_at': u'2018-09-27 11:18:54', 'orginal_fee': None,
+              'resource_name': u'route1',
+              'price_fixing_priceitem_id': None,
+              'update_at': u'2018-09-27 11:28:54',
+              'create_at': u'2018-09-27 11:18:54',
+              'price_fixing_unit': None,
+              'runtime': 600, 'quantity': 1}]
+        request = self.mock_rest_request()
+        data_span = 'default_all'
+        response = views.products_download(request, data_span)
+        pro_args, _ = mock_get_products.call_args
+        view_qrgs, _ = mock_get_overview.call_args
+        self.assertEqual(pro_args[1], 'default')
+        self.assertEqual(view_qrgs[1], 'default')
+        self.assertIsInstance(response, HttpResponse)
-- 
2.7.4

jackdan@jackdan-ThinkPad-T430:~/work/fp10/horizon$ cat 0002-ESFIX-Fix-exited-horizon-when-created-alarm-sometime.patch 
From 8fecdb43e8226524325809fcd91d70fe98d4517c Mon Sep 17 00:00:00 2001
From: "chao.ma" <chao.ma@easystack.cn>
Date: Tue, 4 Sep 2018 16:00:56 +0800
Subject: [PATCH 2/2] ESFIX: Fix exited horizon when created alarm sometimes

It needs to get alarm notify list when created alarm,
while getting notify list should call keystone api to
get user information. It needs to judge request.user
whether is superuser which is used to initialize
keystoneclient and use policy to judge privileges if
the user is superuser. The reason is that the logic of
judging whether the user is superuser sometimes use the
project role of this user, while using policy to judge
privileges use the domain role of this user. So if this
user has admin project role and member domain role which
may result in this problem. This is due to incorrect usage
about using is_superuser api to judge whether this user is
cloud admin. So it needs to edit code that uses
api.keystone.is_cloud_admin to judge whether this user is
cloud admin which can keep same logic during all the process
of code.

Change-Id: I0236f327182914f97ced1cf4f9d56d7f9540543c
Closes-bug:#EAS-18847
---
 easystack_dashboard/api/rest/keystone.py           | 602 +++++++++++++--------
 .../test/api_tests/keystone_rest_tests.py          | 115 ++++
 tox.ini                                            |   2 +-
 3 files changed, 493 insertions(+), 226 deletions(-)

diff --git a/easystack_dashboard/api/rest/keystone.py b/easystack_dashboard/api/rest/keystone.py
index a693e80..dcd536c 100644
--- a/easystack_dashboard/api/rest/keystone.py
+++ b/easystack_dashboard/api/rest/keystone.py
@@ -15,20 +15,20 @@
 """
 
 import copy
+
+from django.conf import settings
+from django.core.urlresolvers import reverse
 import django.http
-from django.utils.translation import ugettext_lazy as _
+from django.utils.datastructures import SortedDict
 from django.utils.translation import gettext as trans
+from django.utils.translation import ugettext_lazy as _
 from django.views import generic
-from django.conf import settings
-from horizon import exceptions
 from easystack_dashboard import api
 from easystack_dashboard.api import base
-from easystack_dashboard.api import signup
-from easystack_dashboard.api.rest import usage
-from easystack_dashboard.api.rest import utils as rest_utils
 from easystack_dashboard.api.rest import urls
-from django.utils.datastructures import SortedDict
-from django.core.urlresolvers import reverse
+from easystack_dashboard.api.rest import utils as rest_utils
+from easystack_dashboard.api import signup
+from horizon import exceptions
 import six.moves.urllib.parse as urlparse
 
 OPENSTACK_USER = ("nova",
@@ -57,7 +57,9 @@ OPENSTACK_USER = ("nova",
                   "esstorage",
                   "aodh")
 
-OPENSTACK_DOMAIN = ('heat_domain', 'magnum', 'ironic', 'trove', 'magnum_domain_admin')
+OPENSTACK_DOMAIN = (
+    'heat_domain', 'magnum', 'ironic',
+    'trove', 'magnum_domain_admin')
 OPENSTACK_PROJECT = ('services',)
 OPENSTACK_ROLE = ('ResellerAdmin', 'heat_stack_user', 'SwiftOperator')
 
@@ -126,8 +128,8 @@ class Users(generic.View):
         project_role_id = request.DATA.get('project_role_id')
         domain_role_id = request.DATA.get('domain_role_id')
 
-        if not (domain_id and project_id and
-                    project_role_id and domain_role_id):
+        if (not (domain_id and project_id and
+                 project_role_id and domain_role_id)):
             msg = 'project_id and role_id for \
             project and domain must be not null'
             return django.http.HttpResponseBadRequest(msg)
@@ -171,9 +173,9 @@ class Users(generic.View):
         if request.DATA.get('all_projects'):
             projects = api.keystone.tenant_list(request, domain=domain_id)
             for project in projects[0]:
-                if project.id != project_id and \
+                if (project.id != project_id and
                         not (domain_id == 'default' and
-                                     project.name == 'services'):
+                             project.name == 'services')):
                     api.keystone.add_tenant_user_role(
                         request,
                         project=project.id,
@@ -210,8 +212,12 @@ class OrgUsers(generic.View):
     """API for keystone users.
     """
     url_regex = r'keystone/organizations/users/$'
-    domain_user_keywords = ('name', 'email', 'password', 'domain_id', 'domain_role_id')
-    project_user_keywords = ('name', 'email', 'password', 'domain_id', 'project_id', 'project_role_id')
+    domain_user_keywords = (
+        'name', 'email', 'password',
+        'domain_id', 'domain_role_id')
+    project_user_keywords = (
+        'name', 'email', 'password', 'domain_id',
+        'project_id', 'project_role_id')
 
     @rest_utils.ajax(data_required=True)
     def post(self, request):
@@ -252,7 +258,8 @@ class OrgUsers(generic.View):
             domain=params['domain_id']
         )
         # assign domain role to user
-        # domain_role_id = self.ensure_domain_role_id(request, params['domain_id'])
+        # domain_role_id =
+        # self.ensure_domain_role_id(request, params['domain_id'])
         api.keystone.add_tenant_user_role(
             request,
             domain=params['domain_id'],
@@ -360,7 +367,7 @@ class User(generic.View):
 
         elif 'enabled' in keys:
             enabled = request.DATA['enabled']
-            if user.user_role == 'domain_admin' and enabled == True:
+            if user.user_role == 'domain_admin' and enabled:
                 try:
                     api.signup.admin_active_user(request, user.id)
                 except Exception as e:
@@ -384,7 +391,7 @@ class UserEmail(generic.View):
     @rest_utils.ajax()
     def get(self, request, email):
         user = signup.verify_email(request, email)
-        if user == None or len(user) == 0:
+        if user is None or len(user) == 0:
             return {"result": True}
         return {"result": False}
 
@@ -392,15 +399,18 @@ class UserEmail(generic.View):
 @urls.register
 class NotifyList(generic.View):
     """API for create and update notify list
+
     which belongs to current user.
-    The notify list is used for alarms."""
+    The notify list is used for alarms.
+
+    """
     url_regex = r'keystone/notifylist/$'
 
     @rest_utils.ajax()
     def get(self, request):
         """Get notify list of current user"""
         user_id = request.user.id
-        admin = request.user.is_superuser
+        admin = api.keystone.is_cloud_admin(request)
         user = api.keystone.user_get(request, user_id, admin)
         data = user.to_dict()
         items = []
@@ -414,11 +424,12 @@ class NotifyList(generic.View):
                 if name == data.get('name'):
                     include_myself = True
         if not include_myself:
-            items.append({'name': data.get('name'),
-                          'description': 'Send notification to registered email and mobile',
-                          'email': [{'value': email, 'tag': ''}],
-                          'sms': [{'value': mobile, 'tag': ''}]
-                          })
+            items.append({
+                'name': data.get('name'),
+                'description':
+                    'Send notification to registered email and mobile',
+                'email': [{'value': email, 'tag': ''}],
+                'sms': [{'value': mobile, 'tag': ''}]})
             if getattr(settings, "LDAP_EDITABLE", True):
                 new_data = {'notify_list': items}
                 api.keystone.user_update(request, user, admin, **new_data)
@@ -428,11 +439,11 @@ class NotifyList(generic.View):
     def post(self, request):
         """Create notify list, update current user"""
         user_id = request.user.id
-        admin = request.user.is_superuser
+        admin = api.keystone.is_cloud_admin(request)
         user = api.keystone.user_get(request, user_id, admin)
         dic = user.to_dict()
         notify_list = dic.get('notify_list')
-        if notify_list == None:
+        if notify_list is None:
             notify_list = []
         notify_list.append(request.DATA)
         data = {'notify_list': notify_list}
@@ -446,7 +457,7 @@ class NotifyList(generic.View):
     def put(self, request):
         """Update notify list of current user"""
         user_id = request.user.id
-        admin = request.user.is_superuser
+        admin = api.keystone.is_cloud_admin(request)
         user = api.keystone.user_get(request, user_id, admin)
         dic = user.to_dict()
         name = request.DATA.get('name')
@@ -584,7 +595,7 @@ class Password(generic.View):
             return True
         except Exception as e:
             if e.http_status == 401:
-                return dict(status="403", msg="Old Password is Wrong");
+                return dict(status="403", msg="Old Password is Wrong")
             raise e
 
 
@@ -596,10 +607,12 @@ class Domains(generic.View):
 
     def _ensure_domain_level_info(self, request, domains):
         for domain in domains:
-            parent_domain_names = api.keystone.get_domain_parent_names(request, domain['id'])
+            parent_domain_names = api.keystone.get_domain_parent_names(
+                request, domain['id'])
             parent_domain_names.reverse()
             domain['org_structure'] = '/' + ' / '.join(parent_domain_names)
-            domain['is_top_domain'] = True if not parent_domain_names else False
+            domain['is_top_domain'] = True \
+                if not parent_domain_names else False
 
     @rest_utils.ajax()
     def get(self, request):
@@ -610,10 +623,11 @@ class Domains(generic.View):
         The listing result is an object with property "items".
         """
         items = [d.to_dict() for d in api.keystone.domain_list(request)]
-        items = [domain for domain in items if domain.get('name') not in OPENSTACK_DOMAIN]
-        if rest_utils.str_to_bool(request.GET.get('domain_panel'))\
-           and getattr(settings, 'IDENTITY_MULTI_LEVEL', False):
-           self._ensure_domain_level_info(request, items)
+        items = [domain for domain in items if
+                 domain.get('name') not in OPENSTACK_DOMAIN]
+        if rest_utils.str_to_bool(request.GET.get('domain_panel')) and \
+                getattr(settings, 'IDENTITY_MULTI_LEVEL', False):
+            self._ensure_domain_level_info(request, items)
         return {'items': items}
 
     @rest_utils.ajax(data_required=True)
@@ -686,9 +700,11 @@ class Domain(generic.View):
                 resource_id = unicode(account[0].to_dict().get('id'))
                 query = [{"field": "meter", "op": "eq", "value": 'account'}]
                 account_alarms = api.ceilometer.alarm_list(request, query)
-                alarm_dict = SortedDict([(d.resourceid, d) for d in account_alarms])
+                alarm_dict = SortedDict(
+                    [(d.resourceid, d) for d in account_alarms])
                 if alarm_dict.get(resource_id):
-                    api.ceilometer.alarm_delete(request, alarm_dict.get(resource_id).id)
+                    api.ceilometer.alarm_delete(
+                        request, alarm_dict.get(resource_id).id)
             else:
                 pass
 
@@ -713,19 +729,23 @@ class Domain(generic.View):
         if alarm_id:
             if request.DATA.get('alarm'):
                 try:
-                    alarmData = rest_utils.create_account_alarm(request, request.DATA.get('resource_id'))
+                    alarmData = rest_utils.create_account_alarm(
+                        request, request.DATA.get('resource_id'))
                     if not request.DATA.get('enabled_account_alarm'):
                         alarmData['enabled'] = True
                         alarmData['state'] = 'insufficient data'
-                    api.ceilometer.alarm_update(request, alarm_id, ceilometer_usage=None, **alarmData)
-                except:
+                    api.ceilometer.alarm_update(
+                        request, alarm_id, ceilometer_usage=None, **alarmData)
+                except Exception:
                     pass
             else:
                 try:
-                    alarmData = rest_utils.create_account_alarm(request, request.DATA.get('resource_id'))
+                    alarmData = rest_utils.create_account_alarm(
+                        request, request.DATA.get('resource_id'))
                     alarmData['enabled'] = False
-                    api.ceilometer.alarm_update(request, alarm_id, ceilometer_usage=None, **alarmData)
-                except:
+                    api.ceilometer.alarm_update(
+                        request, alarm_id, ceilometer_usage=None, **alarmData)
+                except Exception:
                     pass
         elif request.DATA.get('alarm'):
             query = [
@@ -733,10 +753,12 @@ class Domain(generic.View):
             account = api.chakra.account_list(request, query, **request.GET)
             resource_id = account[0].to_dict().get('id')
             if resource_id:
-                alarmData = rest_utils.create_account_alarm(request, unicode(resource_id))
+                alarmData = rest_utils.create_account_alarm(
+                    request, unicode(resource_id))
                 try:
-                    api.ceilometer.alarm_create(request, ceilometer_usage=None, **alarmData)
-                except:
+                    api.ceilometer.alarm_create(
+                        request, ceilometer_usage=None, **alarmData)
+                except Exception:
                     pass
 
 
@@ -756,7 +778,8 @@ def str_to_bool(str):
 def ensure_domain_name(request, result_dict, with_domain=True):
     for item in result_dict:
         try:
-            domain = api.keystone.domain_get(request, item['domain_id']).to_dict()
+            domain = api.keystone.domain_get(
+                request, item['domain_id']).to_dict()
             item['domain_name'] = domain['name']
             if with_domain:
                 item['domain'] = domain
@@ -892,7 +915,7 @@ class Projects(generic.View):
             **kwargs
         )
 
-        new_project_dict_list = [new_project.to_dict()];
+        new_project_dict_list = [new_project.to_dict()]
         ensure_domain_name(request, new_project_dict_list)
         return rest_utils.CreatedResponse(
             '/api/keystone/projects/%s' % new_project.id,
@@ -924,21 +947,29 @@ class Project(generic.View):
 
     def set_project_quotas_to_zero(self, request, tenant_id):
 
-        nova_quotas = [(field_name, 0) for field_name in rest_utils.NOVA_PROJECT_QUOTA_FIELDS]
+        nova_quotas = [(field_name, 0) for field_name in
+                       rest_utils.NOVA_PROJECT_QUOTA_FIELDS]
         api.nova.tenant_quota_update(request, tenant_id, **dict(nova_quotas))
 
-        cinder_quotas = [(field_name, 0) for field_name in rest_utils.CINDER_PROJECT_QUOTA_FIELDS]
-        api.cinder.tenant_quota_update(request, tenant_id, **dict(cinder_quotas))
+        cinder_quotas = [(field_name, 0) for field_name in
+                         rest_utils.CINDER_PROJECT_QUOTA_FIELDS]
+        api.cinder.tenant_quota_update(
+            request, tenant_id, **dict(cinder_quotas))
 
         neutron_fields = rest_utils.NEUTRON_PROJECT_QUOTA_FIELDS
-        if getattr(settings, "OPENSTACK_NEUTRON_NETWORK", {}).get('enable_lb', False):
+        if getattr(
+                settings,
+                "OPENSTACK_NEUTRON_NETWORK", {}).get('enable_lb', False):
             neutron_fields += rest_utils.LOADBALANCER_PROJECT_QUOTA_FIELDS
         neutron_quotas = [(field_name, 0) for field_name in neutron_fields]
-        api.neutron.tenant_quota_update(request, tenant_id, **dict(neutron_quotas))
+        api.neutron.tenant_quota_update(
+            request, tenant_id, **dict(neutron_quotas))
 
         if getattr(settings, 'MANILA_ENABLED', False):
-            manila_quotas = [(field_name, 0) for field_name in rest_utils.MANILA_PROJECT_QUOTA_FIELDS]
-            api.manila.tenant_quota_update(request, tenant_id, **dict(manila_quotas))
+            manila_quotas = [(field_name, 0) for field_name in
+                             rest_utils.MANILA_PROJECT_QUOTA_FIELDS]
+            api.manila.tenant_quota_update(
+                request, tenant_id, **dict(manila_quotas))
 
     @rest_utils.ajax()
     def get(self, request, id):
@@ -1028,8 +1059,8 @@ class AuthorizedProjectsTree(generic.View):
     @rest_utils.ajax()
     def get(self, request, id):
         for tenant in request.user.authorized_tenants:
-            if id==tenant.id:
-                    return {'id':id, 'name': tenant.name}
+            if id == tenant.id:
+                    return {'id': id, 'name': tenant.name}
         return api.keystone.tenant_get(request, id).to_dict()
 
 
@@ -1039,7 +1070,8 @@ class ProjectUsers(generic.View):
 
     def _ensure_users_is_project_admin(self, request, users):
         for user in users:
-            if user['roles'] and api.keystone.has_admin_role(request, user['roles']):
+            if user['roles'] and api.keystone.has_admin_role(
+                    request, user['roles']):
                 user['is_project_admin'] = True
             else:
                 user['is_project_admin'] = False
@@ -1050,7 +1082,8 @@ class ProjectUsers(generic.View):
         """
         target = api.keystone.TenantRolesManager(project_id)
         users = target.get_target_users_with_roles(request)
-        users = [user for user in users if user.get('name') not in OPENSTACK_USER]
+        users = [user for user in users if user.get(
+            'name') not in OPENSTACK_USER]
         self._ensure_users_is_project_admin(request, users)
         return {'items': users}
 
@@ -1080,16 +1113,19 @@ class DomainUsers(generic.View):
 
     def _ensure_users_is_domain_admin(self, request, users):
         for user in users:
-            if user.get('roles') and api.keystone.has_admin_role(request, user['roles']):
+            if user.get('roles') and api.keystone.has_admin_role(
+                    request, user['roles']):
                 user['is_domain_admin'] = True
             else:
                 user['is_domain_admin'] = False
 
     def _check_user_projects_in_domain(self, request, users, domain_id):
-        project_list, has_more = api.keystone.project_list(request, domain=domain_id)
+        project_list, has_more = api.keystone.project_list(
+            request, domain=domain_id)
         user_ids = set()
         for project in project_list:
-            users_roles = api.keystone.get_project_users_roles(request, project.id)
+            users_roles = api.keystone.get_project_users_roles(
+                request, project.id)
             user_ids = user_ids | set(users_roles.keys())
 
         for user in users:
@@ -1098,7 +1134,6 @@ class DomainUsers(generic.View):
             else:
                 user['has_project_in_domain'] = False
 
-
     @rest_utils.ajax()
     def get(self, request, domain_id):
         """List all users of the domain.
@@ -1108,9 +1143,10 @@ class DomainUsers(generic.View):
 
         if rest_utils.str_to_bool(request.GET.get('with_user_without_role')):
             users_ids = [user['id'] for user in users]
-            users += [user.to_dict() for user in api.keystone.user_list(request, domain=domain_id)
-                      if user.id not in users_ids]
-        users = [user for user in users if user.get('name') not in OPENSTACK_USER]
+            users += [user.to_dict() for user in api.keystone.user_list(
+                request, domain=domain_id) if user.id not in users_ids]
+        users = [user for user in users if
+                 user.get('name') not in OPENSTACK_USER]
         self._ensure_users_is_domain_admin(request, users)
 
         if rest_utils.str_to_bool(request.GET.get('check_user_project')):
@@ -1287,7 +1323,8 @@ class LDAP(generic.View):
     def get(self, request):
         ldap_enable = getattr(settings, 'LDAP_ENABLE', False)
         ldap_editable = getattr(settings, 'LDAP_EDITABLE', True)
-        return rest_utils.JSONResponse({"enable": ldap_enable, "editable": ldap_editable}, 200)
+        return rest_utils.JSONResponse(
+            {"enable": ldap_enable, "editable": ldap_editable}, 200)
 
 
 @urls.register
@@ -1301,10 +1338,10 @@ class CheckProjectAdmin(generic.View):
             user_id = request.user.id
         project_id = request.DATA.get('project_id')
 
-        result = api.keystone.user_is_project_admin(request,
-                                                    user_id, project_id) \
-                 or api.keystone.is_cloud_admin(request) \
-                 or api.keystone.is_domain_admin(request)
+        result = (
+            api.keystone.user_is_project_admin(request, user_id, project_id) or
+            api.keystone.is_cloud_admin(request) or
+            api.keystone.is_domain_admin(request))
         return rest_utils.JSONResponse(result, 200)
 
 
@@ -1332,7 +1369,8 @@ class UserIsCurProjectDomainAdmin(generic.View):
         """
         proj = api.keystone.get_cur_project(request)
         domain_id = getattr(proj, 'domain_id')
-        return api.keystone.user_is_project_domain_admin(request, user_id, domain_id)
+        return api.keystone.user_is_project_domain_admin(
+            request, user_id, domain_id)
 
 
 @urls.register
@@ -1345,7 +1383,8 @@ class CurUserIsCurProjectDomainAdmin(generic.View):
         """
         proj = api.keystone.get_cur_project(request)
         domain_id = getattr(proj, 'domain_id')
-        return api.keystone.user_is_project_domain_admin(request, request.user.id, domain_id)
+        return api.keystone.user_is_project_domain_admin(
+            request, request.user.id, domain_id)
 
 
 @urls.register
@@ -1376,31 +1415,39 @@ class UserIsProjectChief(generic.View):
         project_id = request.GET['project_id']
         domain_id = ''
 
-        is_domain_admin = api.keystone.user_is_domain_admin(request, user_id, request.user.user_domain_id)
+        is_domain_admin = api.keystone.user_is_domain_admin(
+            request, user_id, request.user.user_domain_id)
         if is_domain_admin:
-            # if domain admin , first judge if this project is user currrent domain admin project
-            # if so, just reassign
-            projects, has_more = api.keystone.project_list(request, domain = request.user.user_domain_id)
+            # if domain admin , first judge if this project is user
+            # currrent domain admin project if so, just reassign
+            projects, has_more = api.keystone.project_list(
+                request, domain=request.user.user_domain_id)
             for project in projects:
                 if project_id == getattr(project, 'id'):
                     return True
-            domains = api.keystone.get_subsets(request, request.user.user_domain_id, False, False)
+            domains = api.keystone.get_subsets(
+                request, request.user.user_domain_id, False, False)
             for domain in domains:
-                projects, has_more = api.keystone.project_list(request, domain = getattr(domain, 'id'))
+                projects, has_more = api.keystone.project_list(
+                    request, domain=getattr(domain, 'id'))
                 for project in projects:
                     if project_id == getattr(project, 'id'):
                         return True
         else:
-            domain_admins = api.keystone.get_user_admin_role_domains(request, request.user)
-            if(len(domain_admins)!=0):
+            domain_admins = api.keystone.get_user_admin_role_domains(
+                request, request.user)
+            if(len(domain_admins) != 0):
                 for domain_admin in domain_admins:
-                    projects, has_more = api.keystone.project_list(request, domain=domain_admin['id'])
+                    projects, has_more = api.keystone.project_list(
+                        request, domain=domain_admin['id'])
                     for project in projects:
                         if project_id == getattr(project, 'id'):
                             return True
-                    domains = api.keystone.get_subsets(request, domain_admin['id'], False, False)
+                    domains = api.keystone.get_subsets(
+                        request, domain_admin['id'], False, False)
                     for domain in domains:
-                        projects, has_more = api.keystone.project_list(request, domain=getattr(domain, 'id'))
+                        projects, has_more = api.keystone.project_list(
+                            request, domain=getattr(domain, 'id'))
                         for project in projects:
                             if project_id == getattr(project, 'id'):
                                 return True
@@ -1408,14 +1455,18 @@ class UserIsProjectChief(generic.View):
                 for tenant in request.user.authorized_tenants:
                     if getattr(tenant, 'id') == project_id:
                         domain_id = getattr(tenant, 'domain_id')
-                        if api.keystone.user_is_domain_admin(request, user_id, domain_id):
+                        if api.keystone.user_is_domain_admin(
+                                request, user_id, domain_id):
                             return True
                         else:
-                            parent_domain = api.keystone.get_parents(request, domain_id, False, False)
-                            domains = api.keystone.get_user_admin_role_domains(request, user_id)
+                            parent_domain = api.keystone.get_parents(
+                                request, domain_id, False, False)
+                            domains = api.keystone.get_user_admin_role_domains(
+                                request, user_id)
                             for p_domain in parent_domain:
                                 for domain in domains:
-                                    if getattr(p_domain, 'id') == getattr(domain, 'id'):
+                                    if getattr(p_domain, 'id') == getattr(
+                                            domain, 'id'):
                                         return True
         return False
 
@@ -1450,44 +1501,62 @@ class AllotUser(generic.View):
         project_id = request.GET['project_id']
         users_list = []
 
-        is_domain_admin = api.keystone.user_is_domain_admin(request, request.user.id, request.user.user_domain_id)
+        is_domain_admin = api.keystone.user_is_domain_admin(
+            request, request.user.id, request.user.user_domain_id)
         if is_domain_admin:
-            cur_level_proj, has_more = api.keystone.project_list(request, domain=request.user.user_domain_id)
+            cur_level_proj, has_more = api.keystone.project_list(
+                request, domain=request.user.user_domain_id)
             for proj in cur_level_proj:
                 if project_id == getattr(proj, 'id'):
-                    users_list = api.keystone.get_cur_domain_admin_users(request, request.user.user_domain_id)
+                    users_list = api.keystone.get_cur_domain_admin_users(
+                        request, request.user.user_domain_id)
                     return {'items': users_list}
-            sub_domains = api.keystone.get_subsets(request, request.user.user_domain_id, False, False)
+            sub_domains = api.keystone.get_subsets(
+                request, request.user.user_domain_id, False, False)
             for sub_domain in sub_domains:
-                projects, has_more = api.keystone.project_list(request, domain=getattr(sub_domain, 'id'))
+                projects, has_more = api.keystone.project_list(
+                    request, domain=getattr(sub_domain, 'id'))
                 for project in projects:
                     if project_id == getattr(project, 'id'):
-                        users_list = api.keystone.get_cur_domain_admin_users(request, getattr(sub_domain, 'id'))
+                        users_list = api.keystone.get_cur_domain_admin_users(
+                            request, getattr(sub_domain, 'id'))
                         for _user in users_list:
                             if _user['id'] == request.user.id:
                                 return {'items': users_list}
-                        users_list.append({'id': request.user.id, 'name': request.user.username})
+                        users_list.append(
+                            {'id': request.user.id,
+                             'name': request.user.username})
                         return {'items': users_list}
         else:
-            domain_admins = api.keystone.get_user_admin_role_domains(request, request.user)
+            domain_admins = api.keystone.get_user_admin_role_domains(
+                request, request.user)
             if (len(domain_admins) != 0):
                 for domain_admin in domain_admins:
-                    projects, has_more = api.keystone.project_list(request, domain=domain_admin['id'])
+                    projects, has_more = api.keystone.project_list(
+                        request, domain=domain_admin['id'])
                     for project in projects:
                         if project_id == getattr(project, 'id'):
-                            users_list = api.keystone.get_cur_domain_admin_users(request, domain_admin['id'])
+                            users_list = \
+                                api.keystone.get_cur_domain_admin_users(
+                                    request, domain_admin['id'])
                             return {'items': users_list}
-                    domains = api.keystone.get_subsets(request, domain_admin['id'], False, False)
+                    domains = api.keystone.get_subsets(
+                        request, domain_admin['id'], False, False)
                     for domain in domains:
-                        projects, has_more = api.keystone.project_list(request, domain=getattr(domain, 'id'))
+                        projects, has_more = api.keystone.project_list(
+                            request, domain=getattr(domain, 'id'))
                         for project in projects:
                             if project_id == getattr(project, 'id'):
-                                users_list = api.keystone.get_cur_domain_admin_users(request,
-                                                                                     getattr(domain, 'id'))
+                                users_list = \
+                                    api.keystone.get_cur_domain_admin_users(
+                                        request,
+                                        getattr(domain, 'id'))
                                 for _user in users_list:
                                     if _user['id'] == request.user.id:
                                         return {'items': users_list}
-                                users_list.append({'id': request.user.id, 'name': request.user.username})
+                                users_list.append(
+                                    {'id': request.user.id,
+                                     'name': request.user.username})
                                 return {'items': users_list}
         return {'items': users_list}
 
@@ -1504,7 +1573,8 @@ class AllotDomainQuotaUser(generic.View):
         users_list = []
 
         # parent = api.keystone.get_parents(request, domain_id, True, False)
-        users_list = api.keystone.get_cur_domain_admin_users(request, domain_id)
+        users_list = api.keystone.get_cur_domain_admin_users(
+            request, domain_id)
         is_cloud_admin = api.keystone.is_cloud_admin(request)
         if is_cloud_admin:
             users_cloud_admin_list = []
@@ -1527,28 +1597,34 @@ class DomainQuotaFormJson(generic.View):
 
         cur_proj = api.keystone.get_cur_project(request)
         cur_proj_domain_id = getattr(cur_proj, 'domain_id')
-        parents = api.keystone.get_parents(request,
-                                            domain_id=cur_proj_domain_id,
-                                            single_level=False,
-                                            admin=False)
-        if len(parents)==0:
-            if api.keystone.user_is_domain_admin(request, user=request.user.id , domain=cur_proj_domain_id ):
+        parents = api.keystone.get_parents(
+            request,
+            domain_id=cur_proj_domain_id,
+            single_level=False,
+            admin=False)
+        if len(parents) == 0:
+            if api.keystone.user_is_domain_admin(
+                    request, user=request.user.id,
+                    domain=cur_proj_domain_id):
                 return {'items': {
                     'display_domain_list': False,
                     'requester_domain_id': cur_proj_domain_id
                 }}
             else:
-                departs = api.keystone.get_subsets(request,
-                                         domain_id=cur_proj_domain_id,
-                                         single_level=True,
-                                         admin=False)
+                departs = api.keystone.get_subsets(
+                    request,
+                    domain_id=cur_proj_domain_id,
+                    single_level=True,
+                    admin=False)
                 requester_depart_list = []
                 for depart in departs:
-                    if_depart_admin = api.keystone.user_is_domain_admin(request, request.user.id,
-                                                      getattr(depart, 'id'))
+                    if_depart_admin = \
+                        api.keystone.user_is_domain_admin(
+                            request, request.user.id,
+                            getattr(depart, 'id'))
                     if if_depart_admin:
                         requester_depart_list.append(depart.to_dict())
-                if len(requester_depart_list)>1:
+                if len(requester_depart_list) > 1:
                     return {
                         'items': {
                             'display_domain_list': True,
@@ -1559,27 +1635,29 @@ class DomainQuotaFormJson(generic.View):
                     return {
                         'items': {
                             'display_domain_list': False,
-                            'requester_domain_id': requester_depart_list[0]['id'] if len(requester_depart_list)>0 else False
+                            'requester_domain_id':
+                                requester_depart_list[0]['id'] if
+                                len(requester_depart_list) > 0 else False
                         }
                     }
         else:
             for i in range(len(parents)):
-                parent = parents[len(parents)-1 - i]
+                parent = parents[len(parents) - 1 - i]
                 if_parent_domain_admin = api.keystone.\
                     user_is_domain_admin(request,
                                          request.user.id,
                                          getattr(parent, 'id'))
                 if if_parent_domain_admin:
-                    if i==0:
+                    if i == 0:
                         return {'items': {
                             'display_domain_list': False,
                             'requester_domain_id': getattr(parent, 'id')
                         }}
                     else:
                         preDomain = parents[len(parents) - i]
-                        brotherDomains = api.keystone.get_subsets(request,
-                                                 domain_id=getattr(preDomain, 'id'),
-                                                 single_level=True, admin=False)
+                        brotherDomains = api.keystone.get_subsets(
+                            request, domain_id=getattr(preDomain, 'id'),
+                            single_level=True, admin=False)
                         requester_domain_list = []
                         for brother in brotherDomains:
                             if_brother_domain_admin = api.keystone. \
@@ -1590,11 +1668,12 @@ class DomainQuotaFormJson(generic.View):
                                 requester_domain_list.append(brother.to_dict())
                             else:
                                 continue
-                        if len(requester_domain_list)>1:
+                        if len(requester_domain_list) > 1:
                             return {
                                 'items': {
                                     'display_domain_list': True,
-                                    'requester_domain_list': requester_domain_list
+                                    'requester_domain_list':
+                                        requester_domain_list
                                 }
                             }
                         else:
@@ -1603,9 +1682,10 @@ class DomainQuotaFormJson(generic.View):
                                 'requester_domain_id': getattr(parent, 'id')
                             }}
                 else:
-                    brotherDomains = api.keystone.get_subsets(request,
-                                                              domain_id=getattr(parent, 'id'),
-                                                              single_level=True, admin=False)
+                    brotherDomains = api.keystone.get_subsets(
+                        request,
+                        domain_id=getattr(parent, 'id'),
+                        single_level=True, admin=False)
                     requester_domain_list = []
                     for brother in brotherDomains:
                         if_brother_domain_admin = api.keystone. \
@@ -1626,7 +1706,8 @@ class DomainQuotaFormJson(generic.View):
                     else:
                         return {'items': {
                             'display_domain_list': False,
-                            'requester_domain_id': requester_domain_list[0]['id']
+                            'requester_domain_id': requester_domain_list[0][
+                                'id']
                         }}
             return {'items': {
                 'display_domain_list': False,
@@ -1662,10 +1743,12 @@ class IsLastLevelAdmin(generic.View):
         if is_cloud_admin:
             return False
         else:
-            admin_role_domains = api.keystone.get_user_admin_role_domains(request, request.user.id)
+            admin_role_domains = api.keystone.get_user_admin_role_domains(
+                request, request.user.id)
             for domain in admin_role_domains:
-                subsets = api.keystone.get_subsets(request, domain['id'], single_level=False, admin=False)
-                if len(subsets)!=0:
+                subsets = api.keystone.get_subsets(
+                    request, domain['id'], single_level=False, admin=False)
+                if len(subsets) != 0:
                     return False
             return True
 
@@ -1688,17 +1771,18 @@ class OrgArch(generic.View):
     def get(self, request, domain_id):
         result = api.keystone.get_parents(request, domain_id)
         try:
-            subsets = api.keystone.get_subsets(request, result[0].id, True, False)
+            subsets = api.keystone.get_subsets(
+                request, result[0].id, True, False)
             for subset in subsets:
                 if domain_id == subset.id:
                     current_domain = subset
                     result.insert(0, current_domain)
                     return {'items': [r.to_dict() for r in result]}
-        except:
+        except Exception:
             domains = []
             if result:
                 domains.append(result[0].to_dict())
-            domains.append({'name' : request.user.user_domain_name})
+            domains.append({'name': request.user.user_domain_name})
             return {'items': [r for r in domains]}
 
 
@@ -1711,8 +1795,8 @@ class OrgParents(generic.View):
     @rest_utils.ajax()
     def post(self, request):
         postData = request.DATA
-        items = api.keystone.get_parents(request, postData['id'], postData['single_level'])
-        orgs = []
+        items = api.keystone.get_parents(
+            request, postData['id'], postData['single_level'])
         itemDict = [i.to_dict() for i in items]
 
         if len(itemDict) != 0:
@@ -1722,14 +1806,19 @@ class OrgParents(generic.View):
                 if i == 0:
                     if api.keystone.is_domain_admin(request)[1]:
                         itemDict[i] = dict(itemDict[i], **{'nodes': [
-                            {'id': request.user.user_domain_id, 'name': request.user.user_domain_name,
+                            {'id': request.user.user_domain_id,
+                             'name': request.user.user_domain_name,
                              'nodes': [{'id': ' ', 'name': ' '}]}]})
                     else:
                         itemDict[i] = dict(itemDict[i], **{'nodes': [
-                            {'id': request.user.user_domain_id, 'name': request.user.user_domain_name,
-                             'forbidden': True, 'collapsed': False, 'nodes': [{'id': ' ', 'name': ' '}]}]})
+                            {'id': request.user.user_domain_id,
+                             'name': request.user.user_domain_name,
+                             'forbidden': True,
+                             'collapsed': False,
+                             'nodes': [{'id': ' ', 'name': ' '}]}]})
                 if i > 0:
-                    itemDict[i] = dict(itemDict[i], **{'nodes': [itemDict[i - 1]]})
+                    itemDict[i] = dict(
+                        itemDict[i], **{'nodes': [itemDict[i - 1]]})
 
             return {
                 'items': itemDict[len(itemDict) - 1],
@@ -1751,13 +1840,15 @@ class OrgSubsets(generic.View):
     @rest_utils.ajax()
     def post(self, request):
         id = request.DATA['id'] if 'id' in request.DATA else ''
-        single_level = bool(request.DATA['single_level']) if 'single_level' in request.DATA else False
+        single_level = bool(request.DATA['single_level']) if \
+            'single_level' in request.DATA else False
         subdomains = api.keystone.get_subsets(request, id, single_level)
         subprojs = api.keystone.tenant_list(request, domain=id)[0]
         orgs = []
         for d in subdomains:
             setattr(d, 'nodes', [{'id': ' ', 'name': ' '}])
-            orgs.append(dict(d.to_dict(), **{'nodes': [{'id': ' ', 'name': ' '}]}))
+            orgs.append(
+                dict(d.to_dict(), **{'nodes': [{'id': ' ', 'name': ' '}]}))
         for p in subprojs:
             if id == getattr(p, 'domain_id'):
                 orgs.append(p.to_dict())
@@ -1773,12 +1864,14 @@ class OrgSubDomains(generic.View):
     @rest_utils.ajax()
     def post(self, request):
         id = request.DATA['id'] if 'id' in request.DATA else ''
-        single_level = bool(request.DATA['single_level']) if 'single_level' in request.DATA else False
+        single_level = bool(request.DATA['single_level']) if \
+            'single_level' in request.DATA else False
         subdomains = api.keystone.get_subsets(request, id, single_level)
         orgs = []
         for d in subdomains:
             setattr(d, 'nodes', [{'id': ' ', 'name': ' '}])
-            orgs.append(dict(d.to_dict(), **{'nodes': [{'id': ' ', 'name': ' '}]}))
+            orgs.append(
+                dict(d.to_dict(), **{'nodes': [{'id': ' ', 'name': ' '}]}))
         return {'items': orgs}
 
 
@@ -1812,6 +1905,7 @@ class RootAccDomains(generic.View):
                 'root': trans('Cloud Platform')
                 }
 
+
 @urls.register
 class OrgNavSubsets(generic.View):
     """API over a single domains.
@@ -1821,7 +1915,9 @@ class OrgNavSubsets(generic.View):
     @rest_utils.ajax()
     def post(self, request):
         id = request.DATA['id'] if 'id' in request.DATA else ''
-        single_level = bool(request.DATA['single_level']) if 'single_level' in request.DATA else False
+        single_level = bool(
+            request.DATA['single_level']) if 'single_level' \
+                                             in request.DATA else False
         subdomains = api.keystone.get_subsets(request, id, single_level)
         subprojs = api.keystone.tenant_list(request, domain=id)[0]
         orgs = []
@@ -1832,11 +1928,16 @@ class OrgNavSubsets(generic.View):
 
         for p in subprojs:
             if id == getattr(p, 'domain_id'):
-                t_dict = dict(p.to_dict(), **{'node_type': 'project',
-                                              'url': reverse('switch_tenants', kwargs={'tenant_id': p.id}), })
+                t_dict = dict(
+                    p.to_dict(),
+                    **{'node_type': 'project',
+                       'url': reverse(
+                           'switch_tenants',
+                           kwargs={'tenant_id': p.id}), })
                 orgs.append(t_dict)
         return {'items': orgs}
 
+
 @urls.register
 class RootDomains(generic.View):
     """API over all domains.
@@ -1876,13 +1977,15 @@ class navOrgs(generic.View):
         def treeRecursion(srcNode, tarNode):
             if 'nodes' in srcNode:
                 if 'nodes' in tarNode:
-                    k=0
+                    k = 0
                     for i in range(len(srcNode['nodes'])):
                         for j in range(len(tarNode['nodes'])):
-                            if srcNode['nodes'][i]['id'] == tarNode['nodes'][j]['id']:
-                                treeRecursion(srcNode['nodes'][i], tarNode['nodes'][j])
+                            if srcNode['nodes'][i]['id'] == \
+                                    tarNode['nodes'][j]['id']:
+                                treeRecursion(
+                                    srcNode['nodes'][i], tarNode['nodes'][j])
                                 break
-                            k = k+1
+                            k = k + 1
                         if k >= len(tarNode['nodes']):
                             tarNode['nodes'].append(srcNode['nodes'][i])
                 else:
@@ -1890,43 +1993,57 @@ class navOrgs(generic.View):
                     tarNode['nodes'].append(srcNode)
 
         def generateTreeList(request, admin=True):
-            tenants, has_more = api.keystone.project_list(request, user=request.user, admin=admin)
+            tenants, has_more = api.keystone.project_list(
+                request, user=request.user, admin=admin)
             parentDomainIdList = []
             treeDictList = []
             tar_tree = {}
             parentListList = []
             for tenant in tenants:
                 tenant_dict = tenant.to_dict()
-                project_node = dict(tenant_dict, **{'node_type': 'project',
-                                                    'url': reverse('switch_tenants',
-                                                                   kwargs={'tenant_id': tenant_dict['id']})})
+                project_node = dict(
+                    tenant_dict,
+                    **{'node_type': 'project',
+                       'url': reverse('switch_tenants',
+                                      kwargs={'tenant_id': tenant_dict['id']})
+                       })
                 parentDomainIdList.append(tenant_dict['domain_id'])
-                parentList = api.keystone.get_parents(request, tenant_dict['domain_id'], single_level=False,
-                                                      admin=admin)
+                parentList = api.keystone.get_parents(
+                    request, tenant_dict['domain_id'],
+                    single_level=False, admin=admin)
                 parentListList.append(parentList)
                 next_level_node = project_node
                 # the root domain project situation:
                 if len(parentList) == 0:
-                    next_level_node = dict({'id': request.user.user_domain_id,
-                                            'name': request.user.user_domain_name,
-                                            'collapsed': False,
-                                            'forbidden': True, }, **{'nodes': [next_level_node]})
+                    next_level_node = dict(
+                        {'id': request.user.user_domain_id,
+                         'name': request.user.user_domain_name,
+                         'collapsed': False,
+                         'forbidden': True, },
+                        **{'nodes': [next_level_node]})
                 # the department project situation
                 else:
                     tenant_domain_name = ''
-                    subsets = api.keystone.get_subsets(request, parentList[0].id, single_level=False, admin=admin)
+                    subsets = api.keystone.get_subsets(
+                        request, parentList[0].id,
+                        single_level=False, admin=admin)
                     for subset in subsets:
                         if tenant_dict['domain_id'] == getattr(subset, 'id'):
                             tenant_domain_name = getattr(subset, 'name')
                             break
-                    next_level_node = dict({'id': tenant_dict['domain_id'],
-                                            'name': tenant_domain_name,
-                                            'collapsed': False,
-                                            'forbidden': True, }, **{'nodes': [next_level_node]})
+                    next_level_node = dict(
+                        {'id': tenant_dict['domain_id'],
+                         'name': tenant_domain_name,
+                         'collapsed': False,
+                         'forbidden': True, },
+                        **{'nodes': [next_level_node]})
                     for parent in parentList:
                         parent_dict = parent.to_dict()
-                        next_level_node = dict(dict(parent_dict, **{'collapsed': False, 'forbidden': True}),
-                                               **{'nodes': [next_level_node]})
+                        next_level_node = dict(
+                            dict(parent_dict,
+                                 **{'collapsed': False,
+                                    'forbidden': True}),
+                            **{'nodes': [next_level_node]})
                 treeDict = next_level_node
                 treeDictList.append(treeDict)
 
@@ -1973,15 +2090,14 @@ class OrgTree(generic.View):
         root = {'id': 'cloud_platform',
                 'name': trans('Cloud Platform'),
                 'forbidden': True,
-                'nodes': []
-               }
+                'nodes': []}
         org_tree_manager = OrgTreeManager()
         if api.keystone.is_cloud_admin(request):
             root = org_tree_manager.get_cloud_admin_init_tree(request)
         elif api.keystone.is_org_admin(request):
             root = org_tree_manager.get_org_admin_init_tree(request)
 
-        return {'items' : root}
+        return {'items': root}
 
 
 @urls.register
@@ -2003,24 +2119,26 @@ class BillOrgTree(generic.View):
                 'name': trans('Cloud Platform'),
                 'forbidden': True,
                 'collapsed': False,
-                'nodes': []
-               }
+                'nodes': []}
         org_tree_manager = OrgTreeManager()
         if api.keystone.is_cloud_admin(request):
             root = org_tree_manager.get_cloud_admin_init_tree(request)
         elif api.keystone.is_org_admin(request):
             root = org_tree_manager.get_bill_org_admin_init_tree(request)
             user_domain_id = request.user.user_domain_id
-            if_domain_admin = api.keystone.user_is_domain_admin(request, request.user.id, user_domain_id)
+            if_domain_admin = api.keystone.user_is_domain_admin(
+                request, request.user.id, user_domain_id)
             deafaultNodeId = user_domain_id
             if not if_domain_admin:
-                subsets = api.keystone.get_subsets(request, user_domain_id, True, False)
+                subsets = api.keystone.get_subsets(
+                    request, user_domain_id, True, False)
                 for subset in subsets:
-                    if_subset_admin = api.keystone.user_is_domain_admin(request, request.user.id, getattr(subset, 'id'))
+                    if_subset_admin = api.keystone.user_is_domain_admin(
+                        request, request.user.id, getattr(subset, 'id'))
                     if if_subset_admin:
                         deafaultNodeId = getattr(subset, 'id')
                         break
-        return {'items' : root,
+        return {'items': root,
                 'deafaultNodeId': deafaultNodeId}
 
 
@@ -2034,19 +2152,22 @@ class OrgTreeNextLevel(generic.View):
     @rest_utils.ajax()
     def get(self, request, domain_id):
         org_tree_manager = OrgTreeManager()
-        subdomains = api.keystone.get_subsets(request, domain_id, True, admin=False)
-        projects = api.keystone.tenant_list(request, domain=domain_id, admin=False)[0]
-        projects = [project for project in projects if project.name not in OPENSTACK_PROJECT]
+        subdomains = api.keystone.get_subsets(
+            request, domain_id, True, admin=False)
+        projects = api.keystone.tenant_list(
+            request, domain=domain_id, admin=False)[0]
+        projects = [project for project in projects if
+                    project.name not in OPENSTACK_PROJECT]
         domain_nodes = org_tree_manager.getDomainNodes(subdomains)
         project_nodes = org_tree_manager.getProjectNodes(projects)
 
         return {'items': {
-            'domain_nodes' : domain_nodes,
-            'project_nodes' : project_nodes
+            'domain_nodes': domain_nodes,
+            'project_nodes': project_nodes
         }}
 
 
-class OrgTreeManager():
+class OrgTreeManager(object):
 
     def get_cloud_admin_init_tree(self, request):
         nodes = []
@@ -2054,11 +2175,11 @@ class OrgTreeManager():
                 'name': trans('Cloud Platform'),
                 'node_type': 'cloud_platform',
                 'forbidden': True,
-                'nodes': []
-               }
+                'nodes': []}
         user_domain_id = request.user.user_domain_id
         root_domains = api.keystone.root_domain_list(request)
-        root_domains = [domain for domain in root_domains if domain.name not in OPENSTACK_DOMAIN]
+        root_domains = [domain for domain in root_domains if
+                        domain.name not in OPENSTACK_DOMAIN]
         default_domain_node = None
         for domain in root_domains:
             node = {'id': domain.id,
@@ -2083,7 +2204,8 @@ class OrgTreeManager():
         admin_domains = api.keystone.get_user_admin_role_domains(request, user)
         subdomains = api.keystone.get_subsets(request, user_domain_id)
         if api.keystone.user_is_domain_admin(request, user.id, user_domain_id):
-            default_doman = api.keystone.domain_get(request,user_domain_id, admin=False)
+            default_doman = api.keystone.domain_get(
+                request, user_domain_id, admin=False)
             subdomains.append(default_doman)
 
         id_domain_map = {}
@@ -2093,8 +2215,7 @@ class OrgTreeManager():
         root = {'id': 'cloud_platform',
                 'name': trans('Cloud Platform'),
                 'forbidden': True,
-                'nodes': []
-               }
+                'nodes': []}
         for domain in admin_domains:
             domain_node = self.get_domain_node_from_tree(root, domain['id'])
             if domain_node:
@@ -2102,7 +2223,8 @@ class OrgTreeManager():
                 domain_node['nodes'] = []
                 domain_node['is_admin_node'] = True
             else:
-                path_nodes = self.get_tree_path_nodes(request, id_domain_map[domain['id']])
+                path_nodes = self.get_tree_path_nodes(
+                    request, id_domain_map[domain['id']])
                 self.merge_path_nodes_to_tree_node(root, path_nodes)
 
         return root
@@ -2113,7 +2235,8 @@ class OrgTreeManager():
         admin_domains = api.keystone.get_user_admin_role_domains(request, user)
         subdomains = api.keystone.get_subsets(request, user_domain_id)
         if api.keystone.user_is_domain_admin(request, user.id, user_domain_id):
-            default_doman = api.keystone.domain_get(request,user_domain_id, admin=False)
+            default_doman = api.keystone.domain_get(
+                request, user_domain_id, admin=False)
             subdomains.append(default_doman)
 
         id_domain_map = {}
@@ -2124,17 +2247,18 @@ class OrgTreeManager():
                 'name': trans('Cloud Platform'),
                 'forbidden': True,
                 'collapsed': False,
-                'nodes': []
-               }
+                'nodes': []}
         for domain in admin_domains:
-            domain_node = self.get_bill_domain_node_from_tree(root, domain['id'])
+            domain_node = self.get_bill_domain_node_from_tree(
+                root, domain['id'])
             if domain_node:
                 domain_node['forbidden'] = False
                 domain_node['collapsed'] = True
                 domain_node['nodes'] = [{'id': ' ', 'name': ' '}]
                 domain_node['is_admin_node'] = True
             else:
-                path_nodes = self.get_bill_tree_path_nodes(request, id_domain_map[domain['id']])
+                path_nodes = self.get_bill_tree_path_nodes(
+                    request, id_domain_map[domain['id']])
                 self.merge_bill_path_nodes_to_tree_node(root, path_nodes)
 
         return root
@@ -2148,7 +2272,8 @@ class OrgTreeManager():
 
         if matched_node:
             if matched_node['nodes'] and path_nodes['nodes']:
-                self.merge_path_nodes_to_tree_node(matched_node, path_nodes['nodes'][0])
+                self.merge_path_nodes_to_tree_node(
+                    matched_node, path_nodes['nodes'][0])
             else:
                 matched_node['forbidden'] = False
                 matched_node['nodes'] = []
@@ -2161,17 +2286,19 @@ class OrgTreeManager():
     def merge_bill_path_nodes_to_tree_node(self, node, path_nodes):
         matched_node = None
         for child_node in node['nodes']:
-            if child_node['id']!= ' ' and child_node['id'] == path_nodes['id']:
+            if child_node['id'] != ' ' and \
+                    child_node['id'] == path_nodes['id']:
                 matched_node = child_node
                 break
 
         if matched_node:
-            if matched_node['nodes'] and path_nodes['nodes'] :
+            if matched_node['nodes'] and path_nodes['nodes']:
                 if not (len(matched_node['nodes']) == 1
                         and len(path_nodes['nodes']) == 1
                         and (matched_node['nodes'][0]['id'] == ' '
                         or path_nodes['nodes'][0]['id'] == ' ')):
-                    self.merge_bill_path_nodes_to_tree_node(matched_node, path_nodes['nodes'][0])
+                    self.merge_bill_path_nodes_to_tree_node(
+                        matched_node, path_nodes['nodes'][0])
             else:
                 matched_node['forbidden'] = False
                 matched_node['collapsed'] = True
@@ -2180,26 +2307,28 @@ class OrgTreeManager():
         else:
             node['nodes'].append(path_nodes)
 
-    def get_domain_node_from_tree (self, node, domain_id):
+    def get_domain_node_from_tree(self, node, domain_id):
         domain_node = None
         if node['id'] == domain_id:
             domain_node = node
         else:
             for child_node in node['nodes']:
-                domain_node = self.get_domain_node_from_tree(child_node, domain_id)
+                domain_node = self.get_domain_node_from_tree(
+                    child_node, domain_id)
                 if domain_node:
                     break
 
         return domain_node
 
-    def get_bill_domain_node_from_tree (self, node, domain_id):
+    def get_bill_domain_node_from_tree(self, node, domain_id):
         domain_node = None
         if node['id'] != ' ':
             if node['id'] == domain_id:
                 domain_node = node
             else:
                 for child_node in node['nodes']:
-                    domain_node = self.get_bill_domain_node_from_tree(child_node, domain_id)
+                    domain_node = self.get_bill_domain_node_from_tree(
+                        child_node, domain_id)
                     if domain_node:
                         break
 
@@ -2285,7 +2414,9 @@ class OrgTreeManager():
 
 @urls.register
 class OrgAllProjects(generic.View):
-    """API over projects belonging to a org admin, when IDENTITY_MULTI_LEVEL is True.
+    """API over projects belonging to a org admin,
+
+    when IDENTITY_MULTI_LEVEL is True.
 
     """
     url_regex = r'keystone/orgallprojects/$'
@@ -2293,18 +2424,21 @@ class OrgAllProjects(generic.View):
     def _get_org_admin_all_projects(self, request):
         ret_projects = []
         domain_id_name_dict = {}
-        admin_role_domains = api.keystone.get_user_admin_role_domains(request, request.user)
+        admin_role_domains = api.keystone.get_user_admin_role_domains(
+            request, request.user)
         for domain in admin_role_domains:
             domain_id_name_dict[domain.get('id')] = domain.get('name')
-            sub_domains = api.keystone.get_subsets(request, domain.get('id'), admin=False)
+            sub_domains = api.keystone.get_subsets(
+                request, domain.get('id'), admin=False)
             for sub_domain in sub_domains:
                 domain_id_name_dict[sub_domain.id] = sub_domain.name
 
-        for domain_id,domain_name in domain_id_name_dict.iteritems():
+        for domain_id, domain_name in domain_id_name_dict.iteritems():
             if not domain_name:
                 domain = api.keystone.domain_get(request, domain_id, False)
                 domain_name = domain.name
-            projects = api.keystone.tenant_list(request, domain= domain_id, admin=False)[0]
+            projects = api.keystone.tenant_list(
+                request, domain=domain_id, admin=False)[0]
             for project in projects:
                 project_dict = project.to_dict()
                 project_dict['domain_name'] = domain_name
@@ -2318,16 +2452,20 @@ class OrgAllProjects(generic.View):
             domain_id = project.get('domain_id')
             if domain_id not in org_structure_dict:
                 domain_name = project.get('domain_name')
-                domain_names = [domain_name] + api.keystone.get_domain_parent_names(request, project.get('domain_id'))
+                domain_names = ([domain_name] +
+                                api.keystone.get_domain_parent_names(
+                                    request, project.get('domain_id')))
                 domain_names.reverse()
-                org_structure_dict[domain_id] = '/%s' % ' / '.join(domain_names)
+                org_structure_dict[domain_id] = '/%s' % ' / '.join(
+                    domain_names)
 
             project['org_structure'] = org_structure_dict.get(domain_id)
         return projects
 
     def filter_system_projects(self, projects):
         system_project_structures = ['/%s' % name for name in OPENSTACK_DOMAIN]
-        projects = [project for project in projects if project.get('org_structure') not in system_project_structures]
+        projects = [project for project in projects if project.get(
+            'org_structure') not in system_project_structures]
         return projects
 
     @rest_utils.ajax()
@@ -2336,7 +2474,8 @@ class OrgAllProjects(generic.View):
             return []
 
         if api.keystone.is_cloud_admin(request):
-            projects = [project.to_dict() for project in api.keystone.tenant_list(request)[0]
+            projects = [project.to_dict() for project in
+                        api.keystone.tenant_list(request)[0]
                         if project.name not in OPENSTACK_PROJECT]
             ensure_domain_name(request, projects, with_domain=False)
         elif api.keystone.is_org_admin(request):
@@ -2347,11 +2486,14 @@ class OrgAllProjects(generic.View):
         self._ensure_project_org_structure(request, projects)
         projects = self.filter_system_projects(projects)
 
-        return {'items' : projects}
+        return {'items': projects}
+
 
 @urls.register
 class OrgAllUsers(generic.View):
-    """API over users belonging to a org admin,cloudamdin, when IDENTITY_MULTI_LEVEL is True.
+    """API over users belonging to a org admin,
+
+    cloudamdin, when IDENTITY_MULTI_LEVEL is True.
 
     """
     url_regex = r'keystone/orgallusers/$'
@@ -2359,10 +2501,12 @@ class OrgAllUsers(generic.View):
     def _get_org_admin_all_users(self, request):
         users = []
         domain_ids = set()
-        admin_role_domains = api.keystone.get_user_admin_role_domains(request, request.user)
+        admin_role_domains = api.keystone.get_user_admin_role_domains(
+            request, request.user)
         for domain in admin_role_domains:
             domain_ids.add(domain.get('id'))
-            sub_domains = api.keystone.get_subsets(request, domain.get('id'), admin=False)
+            sub_domains = api.keystone.get_subsets(
+                request, domain.get('id'), admin=False)
             for sub_domain in sub_domains:
                 domain_ids.add(sub_domain.id)
 
@@ -2374,9 +2518,10 @@ class OrgAllUsers(generic.View):
 
     def _get_org_cloud_admin_all_users(self, request):
         users = []
-        domains = [domain for domain in api.keystone.domain_list(request) if domain.name not in OPENSTACK_DOMAIN]
+        domains = [domain for domain in api.keystone.domain_list(
+            request) if domain.name not in OPENSTACK_DOMAIN]
         for domain in domains:
-            users.extend(api.keystone.user_list(request, domain= domain.id))
+            users.extend(api.keystone.user_list(request, domain=domain.id))
         users = [user.to_dict() for user in users]
 
         return users
@@ -2386,10 +2531,14 @@ class OrgAllUsers(generic.View):
         for user in users:
             domain_id = user.get('domain_id')
             if domain_id not in org_structure_dict:
-                domain = api.keystone.domain_get(request, domain_id, admin=False)
-                domain_names = [domain.name] + api.keystone.get_domain_parent_names(request, domain_id)
+                domain = api.keystone.domain_get(
+                    request, domain_id, admin=False)
+                domain_names = ([domain.name] +
+                                api.keystone.get_domain_parent_names(
+                                    request, domain_id))
                 domain_names.reverse()
-                org_structure_dict[domain_id] = '/%s' % ' / '.join(domain_names)
+                org_structure_dict[domain_id] = '/%s' % ' / '.join(
+                    domain_names)
 
             user['org_structure'] = org_structure_dict.get(domain_id)
         return users
@@ -2405,10 +2554,12 @@ class OrgAllUsers(generic.View):
             users = self._get_org_admin_all_users(request)
         else:
             users = []
-        users = [user for user in users if user.get('name') not in OPENSTACK_USER]
+        users = [user for user in users if user.get(
+            'name') not in OPENSTACK_USER]
         self._ensure_user_org_structure(request, users)
 
-        return {'items' : users}
+        return {'items': users}
+
 
 @urls.register
 class GetAllotTicketUsers(generic.View):
@@ -2422,7 +2573,8 @@ class GetAllotTicketUsers(generic.View):
 
         allot_users = []
         for user in users:
-            isAdmin = user.get('roles') and api.keystone.has_admin_role(request, user['roles'])
+            isAdmin = user.get('roles') and api.keystone.has_admin_role(
+                request, user['roles'])
             not_openstack_user = user.get('name') not in OPENSTACK_USER
             if isAdmin and not_openstack_user:
                 allot_users.append(user)
diff --git a/easystack_dashboard/test/api_tests/keystone_rest_tests.py b/easystack_dashboard/test/api_tests/keystone_rest_tests.py
index 5e7a765..ca02e0a 100644
--- a/easystack_dashboard/test/api_tests/keystone_rest_tests.py
+++ b/easystack_dashboard/test/api_tests/keystone_rest_tests.py
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import json
+
 from django.conf import settings
 import mock
 from oslo_serialization import jsonutils
@@ -691,3 +693,116 @@ class KeystoneRestTestCase(test.TestCase):
         response = keystone.Services().get(request)
         self.assertStatusCode(response, 200)
         kc.Service.assert_called_once_with(mock_service, "some region")
+
+    #
+    # NotifyList
+    #
+    @mock.patch.object(keystone.api, 'keystone')
+    def test_notify_list_get_with_not_include_self(self, kc):
+        request = self.mock_rest_request()
+        request.user = mock.Mock(roles=[{
+            u'id': u'36cad7469ba04df68eeeb227dc2dc8f5',
+            u'name': u'admin'
+        }])
+        name = 'chen'
+        email = '1277@qq.com'
+        kc.is_cloud_admin.return_value = True
+        kc.user_get.return_value.to_dict.return_value = {
+            'name': name,
+            'email': email
+        }
+        kc.user_update.return_value = None
+        response = keystone.NotifyList().get(request)
+        result = json.loads(response.content.decode('utf-8'))
+        items = [{'email': [{'tag': '', 'value': '1277@qq.com'}],
+                  'sms': [{'tag': '', 'value': None}],
+                  'name': 'chen',
+                  'description':
+                      'Send notification to registered email and mobile'}]
+        expectedResult = {'items': items}
+        self.assertEqual(result, expectedResult)
+
+    @mock.patch.object(keystone.api, 'keystone')
+    def test_notify_list_get_with_include_self(self, kc):
+        request = self.mock_rest_request()
+        request.user = mock.Mock(roles=[{
+            u'id': u'36cad7469ba04df68eeeb227dc2dc8f5',
+            u'name': u'admin'
+        }])
+        name = 'chen'
+        email = '1277@qq.com'
+        kc.is_cloud_admin.return_value = True
+        kc.user_get.return_value.to_dict.return_value = {
+            'name': name,
+            'email': email,
+            'notify_list': [{
+                'email': [{'tag': '', 'value': '1277@qq.com'}],
+                'sms': [{'tag': '', 'value': None}],
+                'name': 'chen',
+                'description':
+                    'Send notification to registered email and mobile'}]
+        }
+        kc.user_update.return_value = None
+        response = keystone.NotifyList().get(request)
+        result = json.loads(response.content.decode('utf-8'))
+        items = [{'email': [{'tag': '', 'value': '1277@qq.com'}],
+                  'sms': [{'tag': '', 'value': None}],
+                  'name': 'chen',
+                  'description':
+                      'Send notification to registered email and mobile'}]
+        expectedResult = {'items': items}
+        self.assertEqual(result, expectedResult)
+
+    @mock.patch.object(keystone.api, 'keystone')
+    def test_notify_list_put_with_data(self, kc):
+        data = {
+            u'email': [{u'tag': u'', u'value': u'1277@qq.com'},
+                       {u'tag': u'', u'value': u'chen@example.org'}],
+            u'sms': [{u'tag': u'', u'value': None}],
+            u'name': u'chen',
+            u'description':
+                u'Send notification to registered email and mobile'}
+        mock_data = json.dumps(data)
+        request = self.mock_rest_request(POST={}, body=mock_data)
+        request.user = mock.Mock(roles=[{
+            u'id': u'36cad7469ba04df68eeeb227dc2dc8f5',
+            u'name': u'admin'
+        }])
+        kc.is_cloud_admin.return_value = True
+        kc.user_get.return_value.to_dict.return_value = {
+            u'notify_list': [
+                {u'sms': [{u'tag': u'', u'value': None}],
+                 u'description':
+                     u'Send notification to registered email and mobile',
+                 u'name': u'chen',
+                 u'email': [{u'tag': u'', u'value': u'1277@qq.com'},
+                            {u'tag': u'', u'value': u'chen@example.org'}]}
+            ]
+        }
+        kc.user_update.return_value = None
+        response = keystone.NotifyList().put(request)
+        self.assertStatusCode(response, 202)
+
+    @mock.patch.object(keystone.api, 'keystone')
+    def test_notify_list_put_without_data(self, kc):
+        data = {}
+        mock_data = json.dumps(data)
+        request = self.mock_rest_request(POST={}, body=mock_data)
+        request.user = mock.Mock(roles=[{
+            u'id': u'36cad7469ba04df68eeeb227dc2dc8f5',
+            u'name': u'admin'
+        }])
+        kc.is_cloud_admin.return_value = True
+        kc.user_get.return_value.to_dict.return_value = {
+            u'notify_list': [
+                {u'sms': [{u'tag': u'', u'value': None}],
+                 u'description':
+                     u'Send notification to registered email and mobile',
+                 u'name': u'chen',
+                 u'email': [{u'tag': u'', u'value': u'1277@qq.com'},
+                            {u'tag': u'', u'value': u'chen@example.org'}]}
+            ]
+        }
+        kc.user_update.return_value = None
+        response = keystone.NotifyList().put(request)
+        self.assertStatusCode(response, 400)
diff --git a/tox.ini b/tox.ini
index cbb9817..d99e0d9 100755
--- a/tox.ini
+++ b/tox.ini
@@ -77,7 +77,7 @@ commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasen
 [flake8]
 exclude = .venv,.git,.tox,dist,*openstack/common*,*lib/python*,*egg,build,panel_template,dash_template,local_settings.py,*/local/*,*/test/test_plugins/*,.ropeproject
 # H405 multi line docstring summary not separated with an empty line
-ignore = H405
+ignore = H405,H701,C901
 max-complexity = 20
 
 [hacking]
-- 
2.7.4

jackdan@jackdan-ThinkPad-T430:~/work/fp10/horizon$ 
  • 由实例可以看出生成Patch的相应操作。

git am patch文件

  • 当我们生成patch文件之后,我们需要将patch文件合并到相应的分支中。一系列操作如下:
$ git apply --stat 0001-fix-bug-error-of-export-billing.patch		# 查看patch的情况
$ git check --stat 0001-fix-bug-error-of-export-billing.patch	# 检查patch是否能够打上,如果没有任何输出,则说明无冲突,可以打上。
(注意: git apply 是另外一种打patch的命令,其与git am的区别是, git apply 并不会将commit message等打上去,打完patch之后需要重新git add 和 git commit,而git am会直接将patch的所有信息打上去,而且不用重新git add和git commit,author也是patch的author而不是打patch的人)
$ git am 0001-fix-bug-error-of-export-billing.patch					# 将名0001-fix-bug-error-of-export-billing.patch字为0001-fix-bug-error-of-export-billing.patch的patch打上
$ git am --signoff 0001-fix-bug-error-of-export-billing.patch 	# 添加-s或者--signoff,还可以把自己的名字添加为signed off by信息,作用是注明打patch的人是谁,因为有时打patch的人并不是patch的作者。
$ git am ~/patch-set/*.patch													# 将路径~/patch-set/*.patch 按照先后顺序打上
$ git am --abort																		# 当git am失败时,用以将已经在am过程中打上的patch废弃掉(比如有三个patch,打到第三个patch时有冲突,那么这条命令会把打上的前两个patch丢弃掉,返回没有打patch的状态)
$ git am --resolved																	# 	git am失败,解决完冲突后,这条命令会接着打patch			

git am patch文件冲突

  • git am patch文件操作
jackdan@jackdan-ThinkPad-T430:~/work/fp11_nanwang/horizon$ git am /home/jackdan/Documents/work/nanwang/fp10-15/0023-Configuration-for-on-and-off-creat-instance-from-ima.patch
Applying: Configuration for on and off creat instance from image
error: patch failed: easystack_dashboard/settings.py:149
error: easystack_dashboard/settings.py: patch does not apply
Patch failed at 0001 Configuration for on and off creat instance from image
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

解决冲突的方案

方案一: 如果不想打这一系列patch了
jackdan@jackdan-ThinkPad-T430:~/work/fp10/horizon$ git am --abort
方案二

(1) 根据git am失败的信息,找到发生冲突的具体patch文件,然后用命令git apply --reject <patch_name>,强行打这个patch,发生冲突的部分会保存为.rej文件(例如发生冲突的文件是a.txt,那么运行完这个命令后,发生conflict的部分会保存为a.txt.rej),未发生冲突的部分会成功打上patch
(2) 根据.rej文件,通过编辑该patch文件的方式解决冲突。
(3) 废弃上一条am命令已经打了的patch:git am --abort
(4) 重新打patch:git am ~/patch-set/*.patchpatch

方案三

(1) 根据git am失败的信息,找到发生冲突的具体patch文件,然后用命令git apply --reject <patch_name>,强行打这个patch,发生冲突的部分会保存为.rej文件(例如发生冲突的文件是a.txt,那么运行完这个命令后,发生conflict的部分会保存为a.txt.rej),未发生冲突的部分会成功打上patch
(2) 根据.rej文件,通过编辑发生冲突的code文件的方式解决冲突。
(3) 将该patch涉及到的所有文件(不仅仅是发生冲突的文件)通过命令git add <file_name>添加到工作区中
(4) 告诉git冲突已经解决,继续打patch: git am --resolved (git am --resolved)git am --continue是一样的)

方案二和方案三主要区别是解决冲突的方法不一样。
方案二是通过编辑patch文件的方式解决冲突;
方案三是通过编辑冲突code文件的方式解决冲突。
这两种方案区别比较大:经过实验,核心区别在于,方案三无法验证冲突有没有切实的解决。即使你在方案三的第二步乱改一通,也能“打完”发生冲突的patch(并没有检测修改后的code文件跟patch期望的是否相同)。因此,如果采用方案三,那么再解决code文件冲突后,需要人工去确认修改的正确性。

  • 推荐方案二作为解决合并patch冲突的方案

JackDan9 Thinking

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 起步 1 1.1 关于版本控制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1.1 本地版本控制系统 . . . . . . . . . . . . . . . . . . . . . . 1 1.1.2 集中化的版本控制系统 . . . . . . . . . . . . . . . . . . . . 1 1.1.3 分布式版本控制系统 . . . . . . . . . . . . . . . . . . . . . 2 1.2 Git 的历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Git 基础要点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.3.1 直接快照,而非比较差异 . . . . . . . . . . . . . . . . . . . 4 1.3.2 近乎所有操作都可本地执行 . . . . . . . . . . . . . . . . . . 5 1.3.3 时刻保持数据完整性 . . . . . . . . . . . . . . . . . . . . . 5 1.3.4 多数操作仅添加数据 . . . . . . . . . . . . . . . . . . . . . 5 1.3.5 三种状态 . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.4 安装 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.4.1 从源代码安装 . . . . . . . . . . . . . . . . . . . . . . . . 7 1.4.2 在 Linux 上安装 . . . . . . . . . . . . . . . . . . . . . . . 7 1.4.3 在 Mac 上安装 . . . . . . . . . . . . . . . . . . . . . . . . 8 1.4.4 在 Windows 上安装 . . . . . . . . . . . . . . . . . . . . . . 8 1.5 初次运行 Git 前的配置 . . . . . . . . . . . . . . . . . . . . . . . 9 1.5.1 用户信息 . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.5.2 文本编辑器 . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.5.3 差异分析工具 . . . . . . . . . . . . . . . . . . . . . . . . 10 1.5.4 查看配置信息 . . . . . . . . . . . . . . . . . . . . . . . . 10 1.6 获取帮助 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.7 小结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2 Git 基础 13 2.1 取得项目的 Git 仓库 . . . . . . . . . . . . . . . . . . . . . . . . 13 2.1.1 从当前目录初始化 . . . . . . . . . . . . . . . . . . . . . . 13 2.1.2 从现有仓库克隆 . . . . . . . . . . . . . . . . . . . . . . . 14 2.2 记录每次更新到仓库 . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.2.1 检查当前文件状态 . . . . . . . . . . . . . . . . . . . . . . 14 2.2.2 跟踪新文件 . . . . . . . . . . . . . . . . . . . . . . . . . 15 2.2.3 暂存已修改文件 . . . . . . . . . . . . . . . . . . . . . . . 16 2.2.4 忽略某些文件 . . . . . . . . . . . . . . . . . . . . . . . . 17 2.2.5 查看已暂存和未暂存的更新 . . . . . . . . . . . . . . . . . . 18 2.2.6 提交更新 . . . . . . . . . . . . . . . . . . . . . . . . . . 20 iii 2.2.7 跳过使用暂存区域 . . . . . . . . . . . . . . . . . . . . . . 21 2.2.8 移除文件 . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.2.9 移动文件 . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.3 查看提交历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.3.1 限制输出长度 . . . . . . . . . . . . . . . . . . . . . . . . 28 2.3.2 使用图形化工具查阅提交历史 . . . . . . . . . . . . . . . . . 29 2.4 撤消操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 2.4.1 修改最后一次提交 . . . . . . . . . . . . . . . . . . . . . . 29 2.4.2 取消已经暂存的文件 . . . . . . . . . . . . . . . . . . . . . 30 2.4.3 取消对文件的修改 . . . . . . . . . . . . . . . . . . . . . . 31 2.5 远程仓库的使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.5.1 查看当前的远程库 . . . . . . . . . . . . . . . . . . . . . . 32 2.5.2 添加远程仓库 . . . . . . . . . . . . . . . . . . . . . . . . 32 2.5.3 从远程仓库抓取数据 . . . . . . . . . . . . . . . . . . . . . 33 2.5.4 推送数据到远程仓库 . . . . . . . . . . . . . . . . . . . . . 33 2.5.5 查看远程仓库信息 . . . . . . . . . . . . . . . . . . . . . . 34 2.5.6 远程仓库的删除和重命名 . . . . . . . . . . . . . . . . . . . 35 2.6 打标签 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 2.6.1 列显已有的标签 . . . . . . . . . . . . . . . . . . . . . . . 35 2.6.2 新建标签 . . . . . . . . . . . . . . . . . . . . . . . . . . 36 2.6.3 含附注的标签 . . . . . . . . . . . . . . . . . . . . . . . . 36 2.6.4 签署标签 . . . . . . . . . . . . . . . . . . . . . . . . . . 37 2.6.5 轻量级标签 . . . . . . . . . . . . . . . . . . . . . . . . . 37 2.6.6 验证标签 . . . . . . . . . . . . . . . . . . . . . . . . . . 38 2.6.7 后期加注标签 . . . . . . . . . . . . . . . . . . . . . . . . 38 2.6.8 分享标签 . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.7 技巧和窍门 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 2.7.1 自动完成 . . . . . . . . . . . . . . . . . . . . . . . . . . 40 2.7.2 Git 命令别名 . . . . . . . . . . . . . . . . . . . . . . . . 41 2.8 小结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3 Git 分支 43 3.1 何谓分支 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3.2 基本的分支与合并 . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.2.1 基本分支 . . . . . . . . . . . . . . . . . . . . . . . . . . 48 3.2.2 基本合并 . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3.2.3 冲突的合并 . . . . . . . . . . . . . . . . . . . . . . . . . 52 3.3 分支管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 3.4 分支式工作流程 . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 3.4.1 长期分支 . . . . . . . . . . . . . . . . . . . . . . . . . . 56 3.4.2 特性分支 . . . . . . . . . . . . . . . . . . . . . . . . . . 56 3.5 远程分支 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.5.1 推送 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3.5.2 跟踪分支 . . . . . . . . . . . . . . . . . . . . . . . . . . 61 3.5.3 删除远程分支 . . . . . . . . . . . . . . . . . . . . . . . . 62 3.6 衍合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 iv 3.6.1 衍合基础 . . . . . . . . . . . . . . . . . . . . . . . . . . 62 3.6.2 更多有趣的衍合 . . . . . . . . . . . . . . . . . . . . . . . 64 3.6.3 衍合的风险 . . . . . . . . . . . . . . . . . . . . . . . . . 66 3.7 小结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 4 服务器上的 Git 69 4.1 协议 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 4.1.1 本地协议 . . . . . . . . . . . . . . . . . . . . . . . . . . 69 优点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 缺点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 4.1.2 SSH 协议 . . . . . . . . . . . . . . . . . . . . . . . . . . 70 优点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 缺点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 4.1.3 Git 协议 . . . . . . . . . . . . . . . . . . . . . . . . . . 71 优点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 缺点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 4.1.4 HTTP/S 协议 . . . . . . . . . . . . . . . . . . . . . . . . . 72 优点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 缺点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 4.2 在服务器部署 Git . . . . . . . . . . . . . . . . . . . . . . . . . . 73 4.2.1 将纯目录转移到服务器 . . . . . . . . . . . . . . . . . . . . 73 4.2.2 小型安装 . . . . . . . . . . . . . . . . . . . . . . . . . . 74 SSH 连接 . . . . . . . . . . . . . . . . . . . . . . . . . . 74 4.3 生成 SSH 公钥 . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 4.4 架设服务器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 4.5 公共访问 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 4.6 网页界面 GitWeb . . . . . . . . . . . . . . . . . . . . . . . . . . 79 4.7 权限管理器 Gitosis . . . . . . . . . . . . . . . . . . . . . . . . . 80 4.8 Git 进程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 4.9 Git 托管服务 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 4.9.1 GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 4.9.2 建立账户 . . . . . . . . . . . . . . . . . . . . . . . . . . 87 4.9.3 建立新仓库 . . . . . . . . . . . . . . . . . . . . . . . . . 87 4.9.4 从 Subversion 中导入项目 . . . . . . . . . . . . . . . . . . 89 4.9.5 开始合作 . . . . . . . . . . . . . . . . . . . . . . . . . . 90 4.9.6 项目页面 . . . . . . . . . . . . . . . . . . . . . . . . . . 91 4.9.7 派生(forking)项目 . . . . . . . . . . . . . . . . . . . . . 92 4.9.8 GitHub 小节 . . . . . . . . . . . . . . . . . . . . . . . . . 93 4.10 小节 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 5 分布式 Git 95 5.1 分布式工作流程 . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 5.1.1 集中式工作流 . . . . . . . . . . . . . . . . . . . . . . . . 95 5.1.2 集成管理员工作流 . . . . . . . . . . . . . . . . . . . . . . 96 5.1.3 司令官与副官工作流 . . . . . . . . . . . . . . . . . . . . . 97 5.2 为项目作贡献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 v 5.2.1 提交指南 . . . . . . . . . . . . . . . . . . . . . . . . . . 98 5.2.2 私有的小型团队 . . . . . . . . . . . . . . . . . . . . . . . 99 5.2.3 私有团队间协作 . . . . . . . . . . . . . . . . . . . . . . . 104 5.2.4 公开的小型项目 . . . . . . . . . . . . . . . . . . . . . . . 108 5.2.5 公开的大型项目 . . . . . . . . . . . . . . . . . . . . . . . 112 5.2.6 小结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 5.3 项目的管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 5.3.1 使用特性分支进行工作 . . . . . . . . . . . . . . . . . . . . 115 5.3.2 采纳来自邮件的补丁 . . . . . . . . . . . . . . . . . . . . . 115 使用 apply 命令应用补丁 . . . . . . . . . . . . . . . . . . . 115 使用 am 命令应用补丁 . . . . . . . . . . . . . . . . . . . . 116 5.3.3 检出远程分支 . . . . . . . . . . . . . . . . . . . . . . . . 118 5.3.4 决断代码取舍 . . . . . . . . . . . . . . . . . . . . . . . . 118 5.3.5 代码集成 . . . . . . . . . . . . . . . . . . . . . . . . . . 119 合并流程 . . . . . . . . . . . . . . . . . . . . . . . . . . 120 大项目的合并流程 . . . . . . . . . . . . . . . . . . . . . . 122 衍合与挑拣(cherry-pick)的流程 . . . . . . . . . . . . . . . 122 5.3.6 给发行版签名 . . . . . . . . . . . . . . . . . . . . . . . . 123 5.3.7 生成内部版本号 . . . . . . . . . . . . . . . . . . . . . . . 124 5.3.8 准备发布 . . . . . . . . . . . . . . . . . . . . . . . . . . 125 5.3.9 制作简报 . . . . . . . . . . . . . . . . . . . . . . . . . . 125 5.4 小结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 6 Git 工具 127 6.1 修订版本(Revision)选择 . . . . . . . . . . . . . . . . . . . . . . 127 6.1.1 单个修订版本 . . . . . . . . . . . . . . . . . . . . . . . . 127 6.1.2 简短的SHA . . . . . . . . . . . . . . . . . . . . . . . . . . 127 6.1.3 关于 SHA-1 的简短说明 . . . . . . . . . . . . . . . . . . . . 128 6.1.4 分支引用 . . . . . . . . . . . . . . . . . . . . . . . . . . 129 6.1.5 引用日志里的简称 . . . . . . . . . . . . . . . . . . . . . . 129 6.1.6 祖先引用 . . . . . . . . . . . . . . . . . . . . . . . . . . 130 6.1.7 提交范围 . . . . . . . . . . . . . . . . . . . . . . . . . . 132 双点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 多点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 三点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 6.2 交互式暂存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 6.2.1 暂存和撤回文件 . . . . . . . . . . . . . . . . . . . . . . . 134 6.2.2 暂存补丁 . . . . . . . . . . . . . . . . . . . . . . . . . . 136 6.3 储藏(Stashing) . . . . . . . . . . . . . . . . . . . . . . . . . . 137 6.3.1 储藏你的工作 . . . . . . . . . . . . . . . . . . . . . . . . 138 6.3.2 从储藏中创建分支 . . . . . . . . . . . . . . . . . . . . . . 139 6.4 重写历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 6.4.1 改变最近一次提交 . . . . . . . . . . . . . . . . . . . . . . 140 6.4.2 修改多个提交说明 . . . . . . . . . . . . . . . . . . . . . . 141 6.4.3 重排提交 . . . . . . . . . . . . . . . . . . . . . . . . . . 142 6.4.4 压制(Squashing)提交 . . . . . . . . . . . . . . . . . . . . . 143 vi 6.4.5 拆分提交 . . . . . . . . . . . . . . . . . . . . . . . . . . 144 6.4.6 核弹级选项: filter-branch . . . . . . . . . . . . . . . . . . 144 从所有提交中删除一个文件 . . . . . . . . . . . . . . . . . . 144 将一个子目录设置为新的根目录 . . . . . . . . . . . . . . . . 145 全局性地更换电子邮件地址 . . . . . . . . . . . . . . . . . . 145 6.5 使用 Git 调试 . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 6.5.1 文件标注 . . . . . . . . . . . . . . . . . . . . . . . . . . 146 6.5.2 二分查找 . . . . . . . . . . . . . . . . . . . . . . . . . . 147 6.6 子模块 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 6.6.1 子模块初步 . . . . . . . . . . . . . . . . . . . . . . . . . 149 6.6.2 克隆一个带子模块的项目 . . . . . . . . . . . . . . . . . . . 151 6.6.3 上层项目 . . . . . . . . . . . . . . . . . . . . . . . . . . 153 6.6.4 子模块的问题 . . . . . . . . . . . . . . . . . . . . . . . . 153 6.7 子树合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 6.8 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 7 自定义 Git 157 7.1 配置 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 7.1.1 客户端基本配置 . . . . . . . . . . . . . . . . . . . . . . . 157 core.editor . . . . . . . . . . . . . . . . . . . . . . . . . 158 commit.template . . . . . . . . . . . . . . . . . . . . . . . 158 core.pager . . . . . . . . . . . . . . . . . . . . . . . . . 159 user.signingkey . . . . . . . . . . . . . . . . . . . . . . . 159 core.excludesfile . . . . . . . . . . . . . . . . . . . . . . 159 help.autocorrect . . . . . . . . . . . . . . . . . . . . . . 159 7.1.2 Git中的着色 . . . . . . . . . . . . . . . . . . . . . . . . . 160 color.ui . . . . . . . . . . . . . . . . . . . . . . . . . . 160 color.* . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 7.1.3 外部的合并与比较工具 . . . . . . . . . . . . . . . . . . . . 160 7.1.4 格式化与空白 . . . . . . . . . . . . . . . . . . . . . . . . 163 core.autocrlf . . . . . . . . . . . . . . . . . . . . . . . . 163 core.whitespace . . . . . . . . . . . . . . . . . . . . . . . 164 7.1.5 服务器端配置 . . . . . . . . . . . . . . . . . . . . . . . . 164 receive.fsckObjects . . . . . . . . . . . . . . . . . . . . . 164 receive.denyNonFastForwards . . . . . . . . . . . . . . . . . 165 receive.denyDeletes . . . . . . . . . . . . . . . . . . . . . 165 7.2 Git属性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 7.2.1 二进制文件 . . . . . . . . . . . . . . . . . . . . . . . . . 165 识别二进制文件 . . . . . . . . . . . . . . . . . . . . . . . 165 比较二进制文件 . . . . . . . . . . . . . . . . . . . . . . . 166 7.2.2 关键字扩展 . . . . . . . . . . . . . . . . . . . . . . . . . 168 7.2.3 导出仓库 . . . . . . . . . . . . . . . . . . . . . . . . . . 170 export-ignore . . . . . . . . . . . . . . . . . . . . . . . . 170 export-subst . . . . . . . . . . . . . . . . . . . . . . . . 170 7.2.4 合并策略 . . . . . . . . . . . . . . . . . . . . . . . . . . 171 7.3 Git挂钩 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 vii 7.3.1 安装一个挂钩 . . . . . . . . . . . . . . . . . . . . . . . . 171 7.3.2 客户端挂钩 . . . . . . . . . . . . . . . . . . . . . . . . . 171 提交工作流挂钩 . . . . . . . . . . . . . . . . . . . . . . . 171 E-mail工作流挂钩 . . . . . . . . . . . . . . . . . . . . . . 172 其他客户端挂钩 . . . . . . . . . . . . . . . . . . . . . . . 172 7.3.3 服务器端挂钩 . . . . . . . . . . . . . . . . . . . . . . . . 173 pre-receive 和 post-receive . . . . . . . . . . . . . . . . . 173 update . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 7.4 Git 强制策略实例 . . . . . . . . . . . . . . . . . . . . . . . . . . 173 7.4.1 服务端挂钩 . . . . . . . . . . . . . . . . . . . . . . . . . 173 指定特殊的提交信息格式 . . . . . . . . . . . . . . . . . . . 174 实现基于用户的访问权限控制列表(ACL)系统 . . . . . . . . . . 175 只允许 Fast-Forward 类型的推送 . . . . . . . . . . . . . . . 177 7.4.2 Client-Side Hooks . . . . . . . . . . . . . . . . . . . . . . 179 7.5 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 8 Git 与其他系统 183 8.1 Git 与 Subversion . . . . . . . . . . . . . . . . . . . . . . . . . 183 8.1.1 git svn . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 8.1.2 初始设定 . . . . . . . . . . . . . . . . . . . . . . . . . . 184 8.1.3 入门 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 8.1.4 提交到 Subversion . . . . . . . . . . . . . . . . . . . . . . 186 8.1.5 拉取最新进展 . . . . . . . . . . . . . . . . . . . . . . . . 187 8.1.6 Git 分支问题 . . . . . . . . . . . . . . . . . . . . . . . . 188 8.1.7 Subversion 分支 . . . . . . . . . . . . . . . . . . . . . . . 189 创建新的 SVN 分支 . . . . . . . . . . . . . . . . . . . . . . 189 8.1.8 切换当前分支 . . . . . . . . . . . . . . . . . . . . . . . . 190 8.1.9 对应 Subversion 的命令 . . . . . . . . . . . . . . . . . . . 190 SVN 风格的历史 . . . . . . . . . . . . . . . . . . . . . . . 190 SVN 日志 . . . . . . . . . . . . . . . . . . . . . . . . . . 191 SVN 服务器信息 . . . . . . . . . . . . . . . . . . . . . . . 191 略 Subversion 之所略 . . . . . . . . . . . . . . . . . . . . 192 8.1.10Git-Svn 总结 . . . . . . . . . . . . . . . . . . . . . . . . 192 8.2 迁移到 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 8.2.1 导入 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 8.2.2 Subversion . . . . . . . . . . . . . . . . . . . . . . . . . 193 8.2.3 Perforce . . . . . . . . . . . . . . . . . . . . . . . . . . 194 8.2.4 自定导入脚本 . . . . . . . . . . . . . . . . . . . . . . . . 196 8.3 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 9 Git 内部原理 203 9.1 底层命令 (Plumbing) 和高层命令 (Porcelain) . . . . . . . . . . . . . 203 9.2 Git 对象 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 9.2.1 tree (树) 对象 . . . . . . . . . . . . . . . . . . . . . . . 206 9.2.2 commit (提交) 对象 . . . . . . . . . . . . . . . . . . . . . 208 9.2.3 对象存储 . . . . . . . . . . . . . . . . . . . . . . . . . . 210 viii 9.3 Git References . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 9.3.1 HEAD 标记 . . . . . . . . . . . . . . . . . . . . . . . . . . 213 9.3.2 Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 9.3.3 Remotes . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 9.4 Packfiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 9.5 The Refspec . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 9.5.1 推送 Refspec . . . . . . . . . . . . . . . . . . . . . . . . 220 9.5.2 删除引用 . . . . . . . . . . . . . . . . . . . . . . . . . . 221 9.6 传输协议 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 9.6.1 哑协议 . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 9.6.2 智能协议 . . . . . . . . . . . . . . . . . . . . . . . . . . 223 上传数据 . . . . . . . . . . . . . . . . . . . . . . . . . . 223 下载数据 . . . . . . . . . . . . . . . . . . . . . . . . . . 224 9.7 维护及数据恢复 . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 9.7.1 维护 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 9.7.2 数据恢复 . . . . . . . . . . . . . . . . . . . . . . . . . . 226 9.7.3 移除对象 . . . . . . . . . . . . . . . . . . . . . . . . . . 228 9.8 总结 . . . . .

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值