blob: 061262a30ec6a9c77a34bd1a138f428bfa0b0ec6 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
"""
ARIA modeling service changes module
"""
# pylint: disable=no-self-argument, no-member, abstract-method
from collections import namedtuple
from sqlalchemy import (
Column,
Text,
DateTime,
Enum,
)
from sqlalchemy.ext.declarative import declared_attr
from .types import (List, Dict)
from .mixins import ModelMixin
from . import relationship
class ServiceUpdateBase(ModelMixin):
"""
Deployment update model representation.
"""
__tablename__ = 'service_update'
__private_fields__ = ('service_fk',
'execution_fk')
created_at = Column(DateTime, nullable=False, index=True)
service_plan = Column(Dict, nullable=False)
service_update_nodes = Column(Dict)
service_update_service = Column(Dict)
service_update_node_templates = Column(List)
modified_entity_ids = Column(Dict)
state = Column(Text)
# region association proxies
@declared_attr
def execution_name(cls):
return relationship.association_proxy('execution', cls.name_column_name())
@declared_attr
def service_name(cls):
return relationship.association_proxy('service', cls.name_column_name())
# endregion
# region one_to_one relationships
# endregion
# region one_to_many relationships
@declared_attr
def steps(cls):
return relationship.one_to_many(cls, 'service_update_step')
# endregion
# region many_to_one relationships
@declared_attr
def execution(cls):
return relationship.one_to_one(cls, 'execution', back_populates=relationship.NO_BACK_POP)
@declared_attr
def service(cls):
return relationship.many_to_one(cls, 'service', back_populates='updates')
# endregion
# region foreign keys
@declared_attr
def execution_fk(cls):
return relationship.foreign_key('execution', nullable=True)
@declared_attr
def service_fk(cls):
return relationship.foreign_key('service')
# endregion
def to_dict(self, suppress_error=False, **kwargs):
dep_update_dict = super(ServiceUpdateBase, self).to_dict(suppress_error) #pylint: disable=no-member
# Taking care of the fact the DeploymentSteps are _BaseModels
dep_update_dict['steps'] = [step.to_dict() for step in self.steps]
return dep_update_dict
class ServiceUpdateStepBase(ModelMixin):
"""
Deployment update step model representation.
"""
__tablename__ = 'service_update_step'
__private_fields__ = ('service_update_fk',)
_action_types = namedtuple('ACTION_TYPES', 'ADD, REMOVE, MODIFY')
ACTION_TYPES = _action_types(ADD='add', REMOVE='remove', MODIFY='modify')
_entity_types = namedtuple(
'ENTITY_TYPES',
'NODE, RELATIONSHIP, PROPERTY, OPERATION, WORKFLOW, OUTPUT, DESCRIPTION, GROUP, PLUGIN')
ENTITY_TYPES = _entity_types(
NODE='node',
RELATIONSHIP='relationship',
PROPERTY='property',
OPERATION='operation',
WORKFLOW='workflow',
OUTPUT='output',
DESCRIPTION='description',
GROUP='group',
PLUGIN='plugin'
)
action = Column(Enum(*ACTION_TYPES, name='action_type'), nullable=False)
entity_id = Column(Text, nullable=False)
entity_type = Column(Enum(*ENTITY_TYPES, name='entity_type'), nullable=False)
# region association proxies
@declared_attr
def service_update_name(cls):
return relationship.association_proxy('service_update', cls.name_column_name())
# endregion
# region one_to_one relationships
# endregion
# region one_to_many relationships
# endregion
# region many_to_one relationships
@declared_attr
def service_update(cls):
return relationship.many_to_one(cls, 'service_update', back_populates='steps')
# endregion
# region foreign keys
@declared_attr
def service_update_fk(cls):
return relationship.foreign_key('service_update')
# endregion
def __hash__(self):
return hash((getattr(self, self.id_column_name()), self.entity_id))
def __lt__(self, other):
"""
the order is 'remove' < 'modify' < 'add'
:param other:
:return:
"""
if not isinstance(other, self.__class__):
return not self >= other
if self.action != other.action:
if self.action == 'remove':
return_value = True
elif self.action == 'add':
return_value = False
else:
return_value = other.action == 'add'
return return_value
if self.action == 'add':
return self.entity_type == 'node' and other.entity_type == 'relationship'
if self.action == 'remove':
return self.entity_type == 'relationship' and other.entity_type == 'node'
return False
class ServiceModificationBase(ModelMixin):
"""
Deployment modification model representation.
"""
__tablename__ = 'service_modification'
__private_fields__ = ('service_fk',)
STARTED = 'started'
FINISHED = 'finished'
ROLLEDBACK = 'rolledback'
STATES = [STARTED, FINISHED, ROLLEDBACK]
END_STATES = [FINISHED, ROLLEDBACK]
context = Column(Dict)
created_at = Column(DateTime, nullable=False, index=True)
ended_at = Column(DateTime, index=True)
modified_node_templates = Column(Dict)
nodes = Column(Dict)
status = Column(Enum(*STATES, name='service_modification_status'))
# region association proxies
@declared_attr
def service_name(cls):
return relationship.association_proxy('service', cls.name_column_name())
# endregion
# region one_to_one relationships
# endregion
# region one_to_many relationships
# endregion
# region many_to_one relationships
@declared_attr
def service(cls):
return relationship.many_to_one(cls, 'service', back_populates='modifications')
# endregion
# region foreign keys
@declared_attr
def service_fk(cls):
return relationship.foreign_key('service')
# endregion