From c70b608be3cb17a07b0b92ba35a453aea064e9bd Mon Sep 17 00:00:00 2001 From: xiaodongwang Date: Tue, 2 Sep 2014 16:42:48 -0700 Subject: [PATCH] add roles checking and roles in order Change-Id: I87735bf4e0432d3dae4c27b3322e517b82d3b3bf --- compass/db/api/adapter.py | 4 +++ compass/db/api/cluster.py | 32 ++++++++++++++++++ compass/db/models.py | 59 +++++++++++++++++++++------------ conf/flavor/openstack_chef.conf | 5 +-- 4 files changed, 76 insertions(+), 24 deletions(-) diff --git a/compass/db/api/adapter.py b/compass/db/api/adapter.py index 6579bbef..c57783af 100644 --- a/compass/db/api/adapter.py +++ b/compass/db/api/adapter.py @@ -168,6 +168,10 @@ def add_flavors_internal(session): session, models.AdapterFlavorRole, False, flavor.id, role.id ) + utils.update_db_object( + session, flavor, + patched_ordered_flavor_roles=[role_name] + ) def get_adapters_internal(session): diff --git a/compass/db/api/cluster.py b/compass/db/api/cluster.py index 8ecbf7a0..a329408f 100644 --- a/compass/db/api/cluster.py +++ b/compass/db/api/cluster.py @@ -1157,6 +1157,36 @@ def update_cluster_hosts( } +def validate_clusterhost(session, clusterhost): + roles = clusterhost.roles + if not roles: + raise exception.InvalidParameter( + 'empty roles for clusterhost %s' % clusterhost.name + ) + + +def validate_cluster(session, cluster): + cluster_roles = [ + flavor_role.role + for flavor_role in cluster.flavor.flavor_roles + ] + necessary_roles = set([ + role.name for role in cluster_roles if not role.optional + ]) + clusterhost_roles = set([]) + for clusterhost in cluster.clusterhosts: + roles = clusterhost.roles + for role in roles: + clusterhost_roles.add(role.name) + missing_roles = necessary_roles - clusterhost_roles + if missing_roles: + raise exception.InvalidParameter( + 'some roles %s are not assigned to any host in cluster %s' % ( + list(missing_roles), cluster.name + ) + ) + + @utils.supported_filters(optional_support_keys=['review']) @database.run_in_session() @user_api.check_user_permission_in_session( @@ -1221,7 +1251,9 @@ def review_cluster(session, reviewer, cluster_id, review={}, **kwargs): deployed_package_config, cluster.adapter_id, True ) + validate_clusterhost(session, clusterhost) utils.update_db_object(session, clusterhost, config_validated=True) + validate_cluster(session, cluster) utils.update_db_object(session, cluster, config_validated=True) return { 'cluster': cluster, diff --git a/compass/db/models.py b/compass/db/models.py index 822d8dfd..29c8dd12 100644 --- a/compass/db/models.py +++ b/compass/db/models.py @@ -651,12 +651,12 @@ class ClusterHost(BASE, TimestampMixin, HelperMixin): def roles(self): role_names = list(self._roles) if not role_names: - return None + return [] flavor = self.cluster.flavor if not flavor: - return None + return [] roles = [] - for flavor_role in flavor.flavor_roles: + for flavor_role in flavor.ordered_flavor_roles: role = flavor_role.role if role.name in role_names: roles.append(role) @@ -664,7 +664,7 @@ class ClusterHost(BASE, TimestampMixin, HelperMixin): @roles.setter def roles(self, value): - self._roles = value + self._roles = list(value) self.config_validated = False @property @@ -725,10 +725,9 @@ class ClusterHost(BASE, TimestampMixin, HelperMixin): 'state': state_dict['state'] }) roles = self.roles - if roles: - dict_info['roles'] = [ - role.to_dict() for role in roles - ] + dict_info['roles'] = [ + role.to_dict() for role in roles + ] return dict_info @@ -1832,12 +1831,6 @@ class OperatingSystem(BASE, HelperMixin): dict_info.update(self.parent.metadata_dict()) for metadata in self.root_metadatas: dict_info.update(metadata.to_dict()) - dict_info.setdefault( - '_self', { - 'name': 'root', - 'field_type_data': 'dict', - } - ) return dict_info @property @@ -1911,6 +1904,7 @@ class AdapterFlavor(BASE, HelperMixin): name = Column(String(80), unique=True) display_name = Column(String(80)) template = Column(String(80)) + _ordered_flavor_roles = Column(JSONEncoded, default=[]) flavor_roles = relationship( AdapterFlavorRole, @@ -1927,6 +1921,32 @@ class AdapterFlavor(BASE, HelperMixin): UniqueConstraint('name', 'adapter_id', name='constraint'), ) + @property + def ordered_flavor_roles(self): + flavor_roles = dict([ + (flavor_role.role.name, flavor_role) + for flavor_role in self.flavor_roles + ]) + ordered_flavor_roles = [] + for flavor_role in list(self._ordered_flavor_roles): + if flavor_role in flavor_roles: + ordered_flavor_roles.append(flavor_roles[flavor_role]) + return ordered_flavor_roles + + @ordered_flavor_roles.setter + def ordered_flavor_roles(self, value): + self._ordered_flavor_roles = list(value) + + @property + def patched_ordered_flavor_roles(self): + return self.ordered_flavor_roles + + @patched_ordered_flavor_roles.setter + def patched_ordered_flavor_roles(self, value): + ordered_flavor_roles = list(self._ordered_flavor_roles) + ordered_flavor_roles.extend(value) + self._ordered_flavor_roles = ordered_flavor_roles + def __init__(self, name, adapter_id, **kwargs): self.name = name self.adapter_id = adapter_id @@ -1947,7 +1967,8 @@ class AdapterFlavor(BASE, HelperMixin): def to_dict(self): dict_info = super(AdapterFlavor, self).to_dict() dict_info['roles'] = [ - flavor_role.to_dict() for flavor_role in self.flavor_roles + flavor_role.to_dict() + for flavor_role in self.ordered_flavor_roles ] return dict_info @@ -1960,7 +1981,7 @@ class AdapterRole(BASE, HelperMixin): name = Column(String(80)) display_name = Column(String(80)) description = Column(Text) - optional = Column(Boolean) + optional = Column(Boolean, default=False) adapter_id = Column( Integer, ForeignKey( @@ -2168,12 +2189,6 @@ class Adapter(BASE, HelperMixin): dict_info.update(self.parent.metadata_dict()) for metadata in self.root_metadatas: dict_info.update(metadata.to_dict()) - dict_info.setdefault( - '_self', { - 'name': 'root', - 'field_type_data': 'dict', - } - ) return dict_info @property diff --git a/conf/flavor/openstack_chef.conf b/conf/flavor/openstack_chef.conf index 95040a84..ec5f4c61 100644 --- a/conf/flavor/openstack_chef.conf +++ b/conf/flavor/openstack_chef.conf @@ -17,9 +17,10 @@ FLAVORS = [{ 'display_name': 'multi-nodes', 'template': 'multnodes.tmpl', 'roles': [ - 'os-compute-controller','os-compute-worker', 'os-network-server', + 'os-ops-database', 'os-ops-messaging', 'os-compute-controller', + 'os-compute-worker', 'os-network-server', 'os-network-worker', 'os-block-storage-volume', 'os-block-storage-controller', 'os-image', 'os-dashboard', - 'os-identity', 'os-ops-messaging', 'os-ops-database', 'ha-proxy' + 'os-identity', 'ha-proxy' ] }]