"Fossies" - the Fresh Open Source Software Archive

Member "keystone-17.0.0/keystone/resource/backends/sql_model.py" (13 May 2020, 5426 Bytes) of package /linux/misc/openstack/keystone-17.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "sql_model.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 16.0.1_vs_17.0.0.

    1 # Licensed under the Apache License, Version 2.0 (the "License"); you may
    2 # not use this file except in compliance with the License. You may obtain
    3 # a copy of the License at
    4 #
    5 #      http://www.apache.org/licenses/LICENSE-2.0
    6 #
    7 # Unless required by applicable law or agreed to in writing, software
    8 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    9 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   10 # License for the specific language governing permissions and limitations
   11 # under the License.
   12 
   13 from sqlalchemy import orm
   14 from sqlalchemy.orm import collections
   15 
   16 from keystone.common import resource_options
   17 from keystone.common import sql
   18 from keystone.resource.backends import base
   19 from keystone.resource.backends import resource_options as ro
   20 
   21 
   22 class Project(sql.ModelBase, sql.ModelDictMixinWithExtras):
   23     # NOTE(henry-nash): From the manager and above perspective, the domain_id
   24     # is nullable.  However, to ensure uniqueness in multi-process
   25     # configurations, it is better to still use the sql uniqueness constraint.
   26     # Since the support for a nullable component of a uniqueness constraint
   27     # across different sql databases is mixed, we instead store a special value
   28     # to represent null, as defined in NULL_DOMAIN_ID above.
   29 
   30     def to_dict(self, include_extra_dict=False):
   31         d = super(Project, self).to_dict(
   32             include_extra_dict=include_extra_dict)
   33         if d['domain_id'] == base.NULL_DOMAIN_ID:
   34             d['domain_id'] = None
   35         # NOTE(notmorgan): Eventually it may make sense to drop the empty
   36         # option dict creation to the superclass (if enough models use it)
   37         d['options'] = resource_options.ref_mapper_to_dict_options(self)
   38         return d
   39 
   40     @classmethod
   41     def from_dict(cls, project_dict):
   42         new_dict = project_dict.copy()
   43         # TODO(morgan): move this functionality to a common location
   44         resource_options = {}
   45         options = new_dict.pop('options', {})
   46         for opt in cls.resource_options_registry.options:
   47             if opt.option_name in options:
   48                 opt_value = options[opt.option_name]
   49                 # NOTE(notmorgan): None is always a valid type
   50                 if opt_value is not None:
   51                     opt.validator(opt_value)
   52                 resource_options[opt.option_id] = opt_value
   53         project_obj = super(Project, cls).from_dict(new_dict)
   54         setattr(project_obj, '_resource_options', resource_options)
   55         return project_obj
   56 
   57     __tablename__ = 'project'
   58     attributes = ['id', 'name', 'domain_id', 'description', 'enabled',
   59                   'parent_id', 'is_domain', 'tags']
   60     resource_options_registry = ro.PROJECT_OPTIONS_REGISTRY
   61     id = sql.Column(sql.String(64), primary_key=True)
   62     name = sql.Column(sql.String(64), nullable=False)
   63     domain_id = sql.Column(sql.String(64), sql.ForeignKey('project.id'),
   64                            nullable=False)
   65     description = sql.Column(sql.Text())
   66     enabled = sql.Column(sql.Boolean)
   67     extra = sql.Column(sql.JsonBlob())
   68     parent_id = sql.Column(sql.String(64), sql.ForeignKey('project.id'))
   69     is_domain = sql.Column(sql.Boolean, default=False, nullable=False,
   70                            server_default='0')
   71     _tags = orm.relationship(
   72         'ProjectTag',
   73         single_parent=True,
   74         lazy='subquery',
   75         cascade='all,delete-orphan',
   76         backref='project',
   77         primaryjoin='and_(ProjectTag.project_id==Project.id)'
   78     )
   79     _resource_option_mapper = orm.relationship(
   80         'ProjectOption',
   81         single_parent=True,
   82         cascade='all,delete,delete-orphan',
   83         lazy='subquery',
   84         backref='project',
   85         collection_class=collections.attribute_mapped_collection('option_id')
   86     )
   87 
   88     # Unique constraint across two columns to create the separation
   89     # rather than just only 'name' being unique
   90     __table_args__ = (sql.UniqueConstraint('domain_id', 'name'),)
   91 
   92     @property
   93     def tags(self):
   94         if self._tags:
   95             return [tag.name for tag in self._tags]
   96         return []
   97 
   98     @tags.setter
   99     def tags(self, values):
  100         new_tags = []
  101         for tag in values:
  102             tag_ref = ProjectTag()
  103             tag_ref.project_id = self.id
  104             tag_ref.name = str(tag)
  105             new_tags.append(tag_ref)
  106         self._tags = new_tags
  107 
  108 
  109 class ProjectTag(sql.ModelBase, sql.ModelDictMixin):
  110 
  111     def to_dict(self):
  112         d = super(ProjectTag, self).to_dict()
  113         return d
  114 
  115     __tablename__ = 'project_tag'
  116     attributes = ['project_id', 'name']
  117     project_id = sql.Column(
  118         sql.String(64), sql.ForeignKey('project.id', ondelete='CASCADE'),
  119         nullable=False, primary_key=True)
  120     name = sql.Column(sql.Unicode(255), nullable=False, primary_key=True)
  121     __table_args__ = (sql.UniqueConstraint('project_id', 'name'),)
  122 
  123 
  124 class ProjectOption(sql.ModelBase):
  125     __tablename__ = 'project_option'
  126     project_id = sql.Column(sql.String(64),
  127                             sql.ForeignKey('project.id', ondelete='CASCADE'),
  128                             nullable=False, primary_key=True)
  129     option_id = sql.Column(sql.String(4), nullable=False,
  130                            primary_key=True)
  131     option_value = sql.Column(sql.JsonBlob, nullable=True)
  132 
  133     def __init__(self, option_id, option_value):
  134         self.option_id = option_id
  135         self.option_value = option_value