pychestrate-core 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccai/pychestrate/core/__init__.py +0 -0
- ccai/pychestrate/core/examples/create_database.py +52 -0
- ccai/pychestrate/core/storage/__init__.py +0 -0
- ccai/pychestrate/core/storage/core/__init__.py +0 -0
- ccai/pychestrate/core/storage/dbconnection.py +269 -0
- ccai/pychestrate/core/storage/dbio.py +158 -0
- ccai/pychestrate/core/storage/defaults.py +29 -0
- ccai/pychestrate/core/storage/orm.py +725 -0
- pychestrate_core-0.0.1.dist-info/METADATA +53 -0
- pychestrate_core-0.0.1.dist-info/RECORD +12 -0
- pychestrate_core-0.0.1.dist-info/WHEEL +4 -0
- pychestrate_core-0.0.1.dist-info/licenses/LICENSE.md +204 -0
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. module:: orm
|
|
3
|
+
:platform: Darwin, Linux, Unix, Windows
|
|
4
|
+
:synopsis: Contains the ORM associated with the akit database storage
|
|
5
|
+
|
|
6
|
+
.. moduleauthor:: Myron Walker <myron.walker@gmail.com>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__author__ = "Myron Walker"
|
|
10
|
+
__copyright__ = "Copyright 2025, Automation Mojo LLC"
|
|
11
|
+
__credits__ = []
|
|
12
|
+
__version__ = "1.0.0"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
import enum
|
|
16
|
+
import json
|
|
17
|
+
import uuid
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
from sqlalchemy import (
|
|
21
|
+
BigInteger,
|
|
22
|
+
Boolean,
|
|
23
|
+
Column,
|
|
24
|
+
DateTime,
|
|
25
|
+
Enum,
|
|
26
|
+
Float,
|
|
27
|
+
Integer,
|
|
28
|
+
String,
|
|
29
|
+
Text,
|
|
30
|
+
VARCHAR,
|
|
31
|
+
ForeignKey,
|
|
32
|
+
TEXT,
|
|
33
|
+
UniqueConstraint,
|
|
34
|
+
)
|
|
35
|
+
from sqlalchemy import inspect, func, text
|
|
36
|
+
from sqlalchemy.types import JSON
|
|
37
|
+
|
|
38
|
+
from sqlalchemy.orm import declarative_base, relationship, backref
|
|
39
|
+
|
|
40
|
+
from sqlalchemy_utils.types.uuid import UUIDType
|
|
41
|
+
|
|
42
|
+
from ccai.pychestrate.core.storage.defaults import utc_now
|
|
43
|
+
|
|
44
|
+
class SerializableModel:
|
|
45
|
+
"""
|
|
46
|
+
Mixin style class that adds serialization to data model objects.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def to_dict(self):
|
|
50
|
+
"""
|
|
51
|
+
Iterates the formal data attributes of a model and outputs a dictionary
|
|
52
|
+
with the data based on the model.
|
|
53
|
+
"""
|
|
54
|
+
dval = {}
|
|
55
|
+
|
|
56
|
+
model = type(self)
|
|
57
|
+
mapper = inspect(model)
|
|
58
|
+
for col in mapper.attrs:
|
|
59
|
+
col_key = col.key
|
|
60
|
+
dval[col_key] = str(getattr(self, col_key))
|
|
61
|
+
|
|
62
|
+
return dval
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def to_json(self, indent=4):
|
|
66
|
+
"""
|
|
67
|
+
Iterates the formal data attributes of a model and creates a dictionary
|
|
68
|
+
with the data based on the model, then converts the dictionary to a
|
|
69
|
+
JSON string.
|
|
70
|
+
"""
|
|
71
|
+
model_dict = self.to_dict()
|
|
72
|
+
json_str = json.dumps(model_dict, indent=indent)
|
|
73
|
+
return json_str
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
PychestrateModelBase = declarative_base()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class AccountStatus(str, enum.Enum):
|
|
80
|
+
"""
|
|
81
|
+
Enum-like class to represent the status of a user or enterprise account.
|
|
82
|
+
"""
|
|
83
|
+
ACTIVE = 'active'
|
|
84
|
+
INACTIVE = 'inactive'
|
|
85
|
+
SUSPENDED = 'suspended'
|
|
86
|
+
DELETED = 'deleted'
|
|
87
|
+
|
|
88
|
+
@classmethod
|
|
89
|
+
def is_valid(cls, status):
|
|
90
|
+
return status in (cls.ACTIVE, cls.INACTIVE, cls.SUSPENDED, cls.DELETED)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class AuthenticationType(str, enum.Enum):
|
|
94
|
+
"""
|
|
95
|
+
Enum-like class to represent the type of authentications that should be used to authenticate the user.
|
|
96
|
+
"""
|
|
97
|
+
INTERNAL = 'internal'
|
|
98
|
+
OAUTH = 'oauth2'
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class RepositoryType(enum.Enum):
|
|
102
|
+
"""Enumeration describing the primary content maintained by a repository."""
|
|
103
|
+
|
|
104
|
+
CODE = "code"
|
|
105
|
+
DOCUMENTATION = "documentation"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class RepositoryScope(enum.Enum):
|
|
109
|
+
"""Enumeration describing the scope of artifacts provided by a repository."""
|
|
110
|
+
|
|
111
|
+
PRODUCT = "product"
|
|
112
|
+
LOCAL = "local"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class WorkQueueJobType(enum.Enum):
|
|
116
|
+
"""
|
|
117
|
+
An enumeration that indicates the JobType of a WorkQueue item. This indicates if a
|
|
118
|
+
work item is a global work item available for execution on any qualified work site or
|
|
119
|
+
if it is a local work item which is meant to execute locally.
|
|
120
|
+
"""
|
|
121
|
+
Local = 1
|
|
122
|
+
Global = 2
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class WorkQueueState(enum.Enum):
|
|
126
|
+
"""
|
|
127
|
+
An enumeration that indicates the JobType of a WorkQueue item. This indicates if a
|
|
128
|
+
work item is a global work item available for execution on any qualified work site or
|
|
129
|
+
if it is a local work item which is meant to execute locally.
|
|
130
|
+
"""
|
|
131
|
+
Enabled = 1
|
|
132
|
+
Disabled = 2
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class WorkPacketStatus(enum.Enum):
|
|
136
|
+
"""Enumeration of lifecycle states for a :class:`WorkPacket`."""
|
|
137
|
+
|
|
138
|
+
QUEUED = "QUEUED"
|
|
139
|
+
RUNNING = "RUNNING"
|
|
140
|
+
SUCCEEDED = "SUCCEEDED"
|
|
141
|
+
FAILED = "FAILED"
|
|
142
|
+
CANCELED = "CANCELED"
|
|
143
|
+
BLOCKED = "BLOCKED"
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class BuildJobTemplate(PychestrateModelBase, SerializableModel):
|
|
147
|
+
"""
|
|
148
|
+
A data model that stores global build job templates.
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
__tablename__ = "buildjob_template"
|
|
152
|
+
|
|
153
|
+
id = Column('bjtmp_id', BigInteger, primary_key=True, autoincrement=True)
|
|
154
|
+
name = Column('bjtmp_name', VARCHAR(128), nullable=False, unique=True)
|
|
155
|
+
description = Column('bjtmp_description', Text, nullable=True)
|
|
156
|
+
specification = Column('bjtmp_specification', JSON, nullable=False)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class BuildTemplate(PychestrateModelBase, SerializableModel):
|
|
160
|
+
"""
|
|
161
|
+
A data model that stores global build templates.
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
__tablename__ = "build_template"
|
|
165
|
+
|
|
166
|
+
id = Column('btmp_id', BigInteger, primary_key=True, autoincrement=True)
|
|
167
|
+
name = Column('btmp_name', VARCHAR(128), nullable=False, unique=True)
|
|
168
|
+
description = Column('btmp_description', Text, nullable=True)
|
|
169
|
+
specification = Column('btmp_specification', JSON, nullable=False)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class TestJobTemplate(PychestrateModelBase, SerializableModel):
|
|
173
|
+
"""
|
|
174
|
+
A data model that stores global test job templates.
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
__tablename__ = "testjob_template"
|
|
178
|
+
|
|
179
|
+
id = Column('tjtmp_id', BigInteger, primary_key=True, autoincrement=True)
|
|
180
|
+
name = Column('tjtmp_name', VARCHAR(128), nullable=False, unique=True)
|
|
181
|
+
description = Column('tjtmp_description', Text, nullable=True)
|
|
182
|
+
specification = Column('tjtmp_specification', JSON, nullable=False)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class Product(PychestrateModelBase, SerializableModel):
|
|
187
|
+
"""A data model that represents a product composed from multiple components."""
|
|
188
|
+
|
|
189
|
+
__tablename__ = "product"
|
|
190
|
+
|
|
191
|
+
id = Column("prod_id", BigInteger, primary_key=True, autoincrement=True)
|
|
192
|
+
name = Column("prod_name", VARCHAR(128), nullable=False, unique=True)
|
|
193
|
+
description = Column("prod_description", Text, nullable=True)
|
|
194
|
+
|
|
195
|
+
components = relationship(
|
|
196
|
+
"ProductComponent",
|
|
197
|
+
back_populates="product",
|
|
198
|
+
cascade="all, delete-orphan",
|
|
199
|
+
lazy="selectin",
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
product_repositories = relationship(
|
|
203
|
+
"ProductToRepository",
|
|
204
|
+
back_populates="product",
|
|
205
|
+
cascade="all, delete-orphan",
|
|
206
|
+
lazy="selectin",
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
releases = relationship(
|
|
210
|
+
"Release",
|
|
211
|
+
back_populates="product",
|
|
212
|
+
cascade="all, delete-orphan",
|
|
213
|
+
lazy="selectin",
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class ProductComponent(PychestrateModelBase, SerializableModel):
|
|
218
|
+
"""Represents a component of a product that maps to a source repository."""
|
|
219
|
+
|
|
220
|
+
__tablename__ = "product_component"
|
|
221
|
+
|
|
222
|
+
__table_args__ = (
|
|
223
|
+
UniqueConstraint("prod_id", "comp_name", name="uq_component_product_name"),
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
id = Column("comp_id", BigInteger, primary_key=True, autoincrement=True)
|
|
227
|
+
name = Column("comp_name", VARCHAR(128), nullable=False)
|
|
228
|
+
description = Column("comp_description", Text, nullable=True)
|
|
229
|
+
|
|
230
|
+
product_id = Column(
|
|
231
|
+
"prod_id", BigInteger, ForeignKey("product.prod_id"), nullable=False, index=True
|
|
232
|
+
)
|
|
233
|
+
repository_id = Column(
|
|
234
|
+
"repo_id", BigInteger, ForeignKey("repository.repo_id"), nullable=False, index=True
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
product = relationship("Product", back_populates="components", lazy="selectin")
|
|
238
|
+
repository = relationship("Repository", back_populates="components", lazy="selectin")
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
class ProductToRepository(PychestrateModelBase, SerializableModel):
|
|
242
|
+
"""Associates product level repositories such as documentation with a product."""
|
|
243
|
+
|
|
244
|
+
__tablename__ = "product_to_repository"
|
|
245
|
+
|
|
246
|
+
__table_args__ = (
|
|
247
|
+
UniqueConstraint("prod_id", "repo_id", name="uq_product_repository"),
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
id = Column("ptor_id", BigInteger, primary_key=True, autoincrement=True)
|
|
251
|
+
product_id = Column(
|
|
252
|
+
"prod_id", BigInteger, ForeignKey("product.prod_id"), nullable=False, index=True
|
|
253
|
+
)
|
|
254
|
+
repository_id = Column(
|
|
255
|
+
"repo_id", BigInteger, ForeignKey("repository.repo_id"), nullable=False, index=True
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
product = relationship("Product", back_populates="product_repositories", lazy="selectin")
|
|
259
|
+
repository = relationship("Repository", back_populates="product_links", lazy="selectin")
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class ReleaseTrain(PychestrateModelBase, SerializableModel):
|
|
263
|
+
"""Represents the symbolic branch structure used to orchestrate a release train."""
|
|
264
|
+
|
|
265
|
+
__tablename__ = "release_train"
|
|
266
|
+
|
|
267
|
+
id = Column("rtrain_id", BigInteger, primary_key=True, autoincrement=True)
|
|
268
|
+
name = Column("rtrain_name", VARCHAR(128), nullable=False, unique=True)
|
|
269
|
+
description = Column("rtrain_description", Text, nullable=True)
|
|
270
|
+
|
|
271
|
+
branches = relationship(
|
|
272
|
+
"ReleaseTrainBranch",
|
|
273
|
+
back_populates="train",
|
|
274
|
+
cascade="all, delete-orphan",
|
|
275
|
+
lazy="selectin",
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
releases = relationship(
|
|
279
|
+
"Release",
|
|
280
|
+
back_populates="release_train",
|
|
281
|
+
lazy="selectin",
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
class ReleaseTrainBranchType(str, enum.Enum):
|
|
286
|
+
"""Enumerates the logical role a symbolic branch plays within a release train."""
|
|
287
|
+
|
|
288
|
+
TEAM = "team"
|
|
289
|
+
INTEGRATION = "integration"
|
|
290
|
+
MAINLINE = "mainline"
|
|
291
|
+
SUPPORT = "support"
|
|
292
|
+
OTHER = "other"
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
class ReleaseTrainBranch(PychestrateModelBase, SerializableModel):
|
|
296
|
+
"""Symbolic branches that define the flow of a release train."""
|
|
297
|
+
|
|
298
|
+
__tablename__ = "release_train_branch"
|
|
299
|
+
|
|
300
|
+
__table_args__ = (
|
|
301
|
+
UniqueConstraint("rtrain_id", "rtbranch_name", name="uq_release_train_branch"),
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
id = Column("rtbranch_id", BigInteger, primary_key=True, autoincrement=True)
|
|
305
|
+
name = Column("rtbranch_name", VARCHAR(128), nullable=False)
|
|
306
|
+
description = Column("rtbranch_description", Text, nullable=True)
|
|
307
|
+
branch_type = Column(
|
|
308
|
+
"rtbranch_type",
|
|
309
|
+
Enum(ReleaseTrainBranchType, name="release_train_branch_type", native_enum=False),
|
|
310
|
+
nullable=False,
|
|
311
|
+
default=ReleaseTrainBranchType.OTHER,
|
|
312
|
+
)
|
|
313
|
+
display_order = Column("rtbranch_display_order", Integer, nullable=False, default=0)
|
|
314
|
+
is_terminal = Column("rtbranch_is_terminal", Boolean, nullable=False, default=False)
|
|
315
|
+
metadata_payload = Column("rtbranch_metadata", JSON, nullable=True)
|
|
316
|
+
|
|
317
|
+
release_train_id = Column(
|
|
318
|
+
"rtrain_id", BigInteger, ForeignKey("release_train.rtrain_id"), nullable=False, index=True
|
|
319
|
+
)
|
|
320
|
+
parent_id = Column(
|
|
321
|
+
"parent_rtbranch_id",
|
|
322
|
+
BigInteger,
|
|
323
|
+
ForeignKey("release_train_branch.rtbranch_id"),
|
|
324
|
+
nullable=True,
|
|
325
|
+
index=True,
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
train = relationship("ReleaseTrain", back_populates="branches", lazy="selectin")
|
|
329
|
+
parent = relationship(
|
|
330
|
+
"ReleaseTrainBranch",
|
|
331
|
+
remote_side=lambda: [ReleaseTrainBranch.id],
|
|
332
|
+
backref=backref(
|
|
333
|
+
"children",
|
|
334
|
+
lazy="selectin",
|
|
335
|
+
order_by="ReleaseTrainBranch.display_order",
|
|
336
|
+
),
|
|
337
|
+
lazy="selectin",
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
branch_assignments = relationship(
|
|
341
|
+
"ReleaseBranchAssignment",
|
|
342
|
+
back_populates="symbolic_branch",
|
|
343
|
+
cascade="all, delete-orphan",
|
|
344
|
+
lazy="selectin",
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class Release(PychestrateModelBase, SerializableModel):
|
|
349
|
+
"""Represents a release of a product built from a release train."""
|
|
350
|
+
|
|
351
|
+
__tablename__ = "release"
|
|
352
|
+
|
|
353
|
+
__table_args__ = (
|
|
354
|
+
UniqueConstraint("prod_id", "release_name", name="uq_release_product_name"),
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
id = Column("release_id", BigInteger, primary_key=True, autoincrement=True)
|
|
358
|
+
name = Column("release_name", VARCHAR(128), nullable=False)
|
|
359
|
+
description = Column("release_description", Text, nullable=True)
|
|
360
|
+
documentation_url = Column("release_documentation_url", VARCHAR(2048), nullable=True)
|
|
361
|
+
start_date = Column("release_start_date", DateTime(timezone=True), nullable=True)
|
|
362
|
+
release_date = Column("release_release_date", DateTime(timezone=True), nullable=True)
|
|
363
|
+
|
|
364
|
+
product_id = Column(
|
|
365
|
+
"prod_id", BigInteger, ForeignKey("product.prod_id"), nullable=False, index=True
|
|
366
|
+
)
|
|
367
|
+
release_train_id = Column(
|
|
368
|
+
"rtrain_id", BigInteger, ForeignKey("release_train.rtrain_id"), nullable=True, index=True
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
product = relationship("Product", back_populates="releases", lazy="selectin")
|
|
372
|
+
release_train = relationship("ReleaseTrain", back_populates="releases", lazy="selectin")
|
|
373
|
+
|
|
374
|
+
branch_assignments = relationship(
|
|
375
|
+
"ReleaseBranchAssignment",
|
|
376
|
+
back_populates="release",
|
|
377
|
+
cascade="all, delete-orphan",
|
|
378
|
+
lazy="selectin",
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
class ReleaseBranchAssignment(PychestrateModelBase, SerializableModel):
|
|
383
|
+
"""Maps a symbolic release train branch to a literal branch name for a release."""
|
|
384
|
+
|
|
385
|
+
__tablename__ = "release_branch_assignment"
|
|
386
|
+
|
|
387
|
+
__table_args__ = (
|
|
388
|
+
UniqueConstraint(
|
|
389
|
+
"release_id",
|
|
390
|
+
"rtbranch_id",
|
|
391
|
+
name="uq_release_branch_assignment",
|
|
392
|
+
),
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
id = Column("rba_id", BigInteger, primary_key=True, autoincrement=True)
|
|
396
|
+
literal_branch_name = Column("rba_literal_branch_name", VARCHAR(256), nullable=False)
|
|
397
|
+
|
|
398
|
+
release_id = Column(
|
|
399
|
+
"release_id", BigInteger, ForeignKey("release.release_id"), nullable=False, index=True
|
|
400
|
+
)
|
|
401
|
+
release_train_branch_id = Column(
|
|
402
|
+
"rtbranch_id",
|
|
403
|
+
BigInteger,
|
|
404
|
+
ForeignKey("release_train_branch.rtbranch_id"),
|
|
405
|
+
nullable=False,
|
|
406
|
+
index=True,
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
release = relationship("Release", back_populates="branch_assignments", lazy="selectin")
|
|
410
|
+
symbolic_branch = relationship("ReleaseTrainBranch", back_populates="branch_assignments", lazy="selectin")
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
class Repository(PychestrateModelBase, SerializableModel):
|
|
414
|
+
"""
|
|
415
|
+
A data modelf for storing repository information.
|
|
416
|
+
"""
|
|
417
|
+
|
|
418
|
+
__tablename__ = "repository"
|
|
419
|
+
|
|
420
|
+
__table_args__ = (UniqueConstraint('repo_name', 'repo_repository', name='uq_repository_name_url'),)
|
|
421
|
+
|
|
422
|
+
id = Column('repo_id', BigInteger, primary_key=True, autoincrement=True)
|
|
423
|
+
name = Column('repo_name', VARCHAR(128), nullable=False)
|
|
424
|
+
url = Column('repo_repository', VARCHAR(2048), nullable=False, unique=True)
|
|
425
|
+
repotype = Column('repo_type', Enum(RepositoryType, name='repository_type', native_enum=False), nullable=False)
|
|
426
|
+
scope = Column('repo_scope', Enum(RepositoryScope, name='repository_scope', native_enum=False), nullable=False)
|
|
427
|
+
repoconf = Column('repo_conf', JSON, nullable=False)
|
|
428
|
+
product_links = relationship('ProductToRepository', back_populates='repository', cascade='all, delete-orphan', lazy='selectin')
|
|
429
|
+
components = relationship('ProductComponent', back_populates='repository', lazy='selectin')
|
|
430
|
+
branches = relationship('Branch', back_populates='repository', cascade='all, delete-orphan', lazy='selectin')
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
class Branch(PychestrateModelBase, SerializableModel):
|
|
434
|
+
"""
|
|
435
|
+
A data model for storing source branch information.
|
|
436
|
+
"""
|
|
437
|
+
|
|
438
|
+
__tablename__ = "branch"
|
|
439
|
+
|
|
440
|
+
__table_args__ = (UniqueConstraint('repo_id', 'branch_name', name='uq_branch_repo_name'),)
|
|
441
|
+
|
|
442
|
+
id = Column('branch_id', BigInteger, primary_key=True, autoincrement=True)
|
|
443
|
+
name = Column('branch_name', VARCHAR(128), nullable=False)
|
|
444
|
+
owner = Column('branch_owner', VARCHAR(128), nullable=False)
|
|
445
|
+
|
|
446
|
+
repo_id = Column('repo_id', BigInteger, ForeignKey('repository.repo_id'), nullable=False, index=True)
|
|
447
|
+
|
|
448
|
+
repository = relationship('Repository', back_populates='branches', lazy='selectin')
|
|
449
|
+
|
|
450
|
+
build_jobs = relationship('BuildJob', back_populates='branch', cascade='all, delete-orphan', lazy='selectin')
|
|
451
|
+
build_results = relationship('BuildResult', back_populates='branch', cascade='all, delete-orphan', lazy='selectin')
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
class BuildJob(PychestrateModelBase, SerializableModel):
|
|
455
|
+
"""
|
|
456
|
+
A data model for storing build job information.
|
|
457
|
+
"""
|
|
458
|
+
|
|
459
|
+
__tablename__ = "build_job"
|
|
460
|
+
|
|
461
|
+
id = Column('bjob_id', BigInteger, primary_key=True, autoincrement=True)
|
|
462
|
+
name = Column('bjob_name', VARCHAR(128), nullable=False)
|
|
463
|
+
start = Column('bjob_start', DateTime(timezone=True), nullable=False, server_default=func.now())
|
|
464
|
+
stop = Column('bjob_stop', DateTime(timezone=True), nullable=True)
|
|
465
|
+
change = Column('bjob_change', VARCHAR(128), nullable=False)
|
|
466
|
+
status = Column('bjob_status', Enum(WorkPacketStatus, name='build_job_status', native_enum=False), nullable=False, default=WorkPacketStatus.QUEUED)
|
|
467
|
+
|
|
468
|
+
branch_id = Column('branch_id', BigInteger, ForeignKey('branch.branch_id'), nullable=False, index=True)
|
|
469
|
+
|
|
470
|
+
branch = relationship('Branch', back_populates='build_jobs', lazy='selectin')
|
|
471
|
+
result = relationship('BuildResult', back_populates='job', uselist=False, cascade='all, delete-orphan', lazy='selectin')
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
class BuildResult(PychestrateModelBase, SerializableModel):
|
|
475
|
+
"""
|
|
476
|
+
A data model for storing build information.
|
|
477
|
+
"""
|
|
478
|
+
|
|
479
|
+
__tablename__ = "build_result"
|
|
480
|
+
|
|
481
|
+
id = Column('build_id', BigInteger, primary_key=True, autoincrement=True)
|
|
482
|
+
name = Column('build_name', VARCHAR(128), nullable=False)
|
|
483
|
+
start = Column('build_start', DateTime(timezone=True), nullable=False, server_default=func.now())
|
|
484
|
+
stop = Column('build_stop', DateTime(timezone=True), nullable=True)
|
|
485
|
+
change = Column('build_change', VARCHAR(128), nullable=False)
|
|
486
|
+
|
|
487
|
+
branch_id = Column('branch_id', BigInteger, ForeignKey('branch.branch_id'), nullable=False, index=True)
|
|
488
|
+
job_id = Column('bjob_id', BigInteger, ForeignKey('build_job.bjob_id'), nullable=True, index=True)
|
|
489
|
+
|
|
490
|
+
branch = relationship('Branch', back_populates='build_results', lazy='selectin')
|
|
491
|
+
job = relationship('BuildJob', back_populates='result', lazy='selectin')
|
|
492
|
+
|
|
493
|
+
byproducts = relationship('BuildByProduct', back_populates='build', cascade='all, delete-orphan', lazy='selectin')
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
class BuildByProduct(PychestrateModelBase, SerializableModel):
|
|
497
|
+
"""
|
|
498
|
+
A data mode for linking build byproducts to build
|
|
499
|
+
"""
|
|
500
|
+
__tablename__ = "build_byproduct"
|
|
501
|
+
|
|
502
|
+
id = Column('bbp_id', BigInteger, primary_key=True, autoincrement=True)
|
|
503
|
+
product = Column('bbp_product', VARCHAR(128), nullable=False)
|
|
504
|
+
arch = Column('bbp_arch', VARCHAR(128), nullable=False)
|
|
505
|
+
buildno = Column('bbp_buildno', VARCHAR(128), nullable=False)
|
|
506
|
+
flavor = Column('bbp_flavor', VARCHAR(128), nullable=False)
|
|
507
|
+
result_url = Column('bbp_result_url', VARCHAR(2048), nullable=False)
|
|
508
|
+
|
|
509
|
+
build_id = Column('build_id', BigInteger, ForeignKey('build_result.build_id'), nullable=False, index=True)
|
|
510
|
+
|
|
511
|
+
build = relationship('BuildResult', back_populates='byproducts', lazy='selectin')
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
class User(PychestrateModelBase, SerializableModel):
|
|
515
|
+
"""
|
|
516
|
+
A data model for the minimal amount of User information to store
|
|
517
|
+
for relating automation data to an enterprise user.
|
|
518
|
+
"""
|
|
519
|
+
|
|
520
|
+
__tablename__ = 'user'
|
|
521
|
+
|
|
522
|
+
id = Column('user_id', UUIDType, primary_key=True, default=uuid.uuid4, server_default=text('gen_random_uuid()'))
|
|
523
|
+
first_name = Column('user_firstName', VARCHAR(40), nullable=False)
|
|
524
|
+
last_name = Column('user_lastName', VARCHAR(40), nullable=False)
|
|
525
|
+
email = Column('user_email', VARCHAR(128), nullable=False, unique=True)
|
|
526
|
+
login = Column('user_login', VARCHAR(128), nullable=False, unique=True)
|
|
527
|
+
ownertag = Column('user_ownertag', VARCHAR(40), nullable=True)
|
|
528
|
+
|
|
529
|
+
work_packets = relationship('WorkPacket', back_populates='user', lazy='selectin')
|
|
530
|
+
|
|
531
|
+
test_runs = relationship('TestJobRun', back_populates='user', lazy='selectin')
|
|
532
|
+
|
|
533
|
+
feature_groups = relationship('FeatureGroupMembership', back_populates='user', lazy='selectin', cascade='all, delete-orphan')
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
class WorkQueue(PychestrateModelBase, SerializableModel):
|
|
537
|
+
"""
|
|
538
|
+
A data model for a
|
|
539
|
+
"""
|
|
540
|
+
__tablename__ = 'work_queue'
|
|
541
|
+
|
|
542
|
+
id = Column('queue_id', UUIDType, primary_key=True, nullable=False, default=uuid.uuid4, server_default=text('gen_random_uuid()'))
|
|
543
|
+
name = Column('queue_name', String(128), nullable=False, unique=True)
|
|
544
|
+
qtype = Column('queue_type', String(128), nullable=False)
|
|
545
|
+
description = Column('queue_desc', TEXT, nullable=False)
|
|
546
|
+
state = Column('queue_state', Enum(WorkQueueState, name='work_queue_state', native_enum=False), nullable=False)
|
|
547
|
+
|
|
548
|
+
packets = relationship('WorkPacket', back_populates='queue', cascade='all, delete-orphan', lazy='selectin')
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
class WorkPacket(PychestrateModelBase, SerializableModel):
|
|
552
|
+
"""
|
|
553
|
+
A data model for a WorkPacket(s) and the work items that are part of a work queue.
|
|
554
|
+
"""
|
|
555
|
+
__tablename__ = 'work_packet'
|
|
556
|
+
|
|
557
|
+
id = Column('wkpack_id', BigInteger, primary_key=True, autoincrement=True)
|
|
558
|
+
|
|
559
|
+
jtype = Column('wkpk_jtype', Enum(WorkQueueJobType, name='work_queue_job_type', native_enum=False), nullable=False)
|
|
560
|
+
title = Column('wkpk_title', String(1024), nullable=False)
|
|
561
|
+
description = Column('wkpk_description', Text, nullable=False)
|
|
562
|
+
branch = Column('wkpk_branch', String(1024), nullable=True)
|
|
563
|
+
build = Column('wkpk_build', String(1024), nullable=True)
|
|
564
|
+
flavor = Column('wkpk_flavor', String(1024), nullable=True)
|
|
565
|
+
ownertag = Column('wkpk_ownertag', VARCHAR(40), nullable=True)
|
|
566
|
+
added = Column('wkpk_added', DateTime(timezone=True), nullable=False, server_default=func.now())
|
|
567
|
+
start = Column('wkpk_start', DateTime(timezone=True), nullable=True)
|
|
568
|
+
stop = Column('wkpk_stop', DateTime(timezone=True), nullable=True)
|
|
569
|
+
progress = Column('wkpk_progress', Float, default=0.0)
|
|
570
|
+
status = Column('wkpk_status', Enum(WorkPacketStatus, name='work_packet_status', native_enum=False), nullable=False, index=True)
|
|
571
|
+
packet = Column('wkpk_packet', TEXT, nullable=False)
|
|
572
|
+
|
|
573
|
+
queue_id = Column('queue_id', UUIDType, ForeignKey('work_queue.queue_id'), nullable=False, index=True)
|
|
574
|
+
user_id = Column('user_id', UUIDType, ForeignKey('user.user_id'), nullable=False, index=True)
|
|
575
|
+
|
|
576
|
+
queue = relationship('WorkQueue', back_populates='packets', lazy='selectin')
|
|
577
|
+
|
|
578
|
+
user = relationship('User', back_populates='work_packets', lazy='selectin')
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
class FeatureGroup(PychestrateModelBase, SerializableModel):
|
|
582
|
+
"""
|
|
583
|
+
A data model for storing information about feature groups.
|
|
584
|
+
"""
|
|
585
|
+
__tablename__ = 'feature_group'
|
|
586
|
+
|
|
587
|
+
id = Column('fg_id', BigInteger, primary_key=True, autoincrement=True)
|
|
588
|
+
name = Column('fg_name', VARCHAR(256), nullable=False)
|
|
589
|
+
description = Column('fg_description', TEXT, nullable=False)
|
|
590
|
+
|
|
591
|
+
test_jobs = relationship('TestJob', back_populates='owner_feature_group', lazy='selectin')
|
|
592
|
+
|
|
593
|
+
memberships = relationship('FeatureGroupMembership', back_populates='feature_group', cascade='all, delete-orphan', lazy='selectin')
|
|
594
|
+
|
|
595
|
+
test_runs = relationship('TestJobRun', back_populates='feature_group', lazy='selectin')
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
class TestJob(PychestrateModelBase, SerializableModel):
|
|
599
|
+
"""
|
|
600
|
+
A data model for storing information about test jobs and
|
|
601
|
+
user and feature group associations with a given test job.
|
|
602
|
+
"""
|
|
603
|
+
__tablename__ = 'test_job'
|
|
604
|
+
|
|
605
|
+
id = Column('tj_id', UUIDType, primary_key=True, default=uuid.uuid4, server_default=text('gen_random_uuid()'))
|
|
606
|
+
title = Column('tj_title', VARCHAR(1024), nullable=False)
|
|
607
|
+
description = Column('tj_description', Text, nullable=False)
|
|
608
|
+
|
|
609
|
+
owner_fg_id = Column('owner_fg_id', BigInteger, ForeignKey('feature_group.fg_id'), nullable=True, index=True)
|
|
610
|
+
|
|
611
|
+
owner_feature_group = relationship('FeatureGroup', back_populates='test_jobs', lazy='selectin')
|
|
612
|
+
|
|
613
|
+
runs = relationship('TestJobRun', back_populates='job', cascade='all, delete-orphan', lazy='selectin')
|
|
614
|
+
|
|
615
|
+
result_containers = relationship('TestResultContainer', back_populates='test_job', cascade='all, delete-orphan', lazy='selectin')
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
class TestJobRun(PychestrateModelBase, SerializableModel):
|
|
619
|
+
"""
|
|
620
|
+
A data model for a TestJob run.
|
|
621
|
+
"""
|
|
622
|
+
|
|
623
|
+
__tablename__ = 'test_job_run'
|
|
624
|
+
|
|
625
|
+
instance = Column('tjr_instance', UUIDType, nullable=False, primary_key=True, default=uuid.uuid4, server_default=text('gen_random_uuid()'))
|
|
626
|
+
branch = Column('tjr_branch', VARCHAR(1024), nullable=True)
|
|
627
|
+
build = Column('tjr_build', VARCHAR(1024), nullable=True)
|
|
628
|
+
flavor = Column('tjr_flavor', VARCHAR(1024), nullable=True)
|
|
629
|
+
ownertag = Column('wkpk_ownertag', UUIDType, nullable=True)
|
|
630
|
+
start = Column('tjr_start', DateTime(timezone=True), nullable=False, server_default=func.now(), index=True)
|
|
631
|
+
stop = Column('tjr_stop', DateTime(timezone=True), nullable=True)
|
|
632
|
+
detail = Column('tjr_detail', JSON, nullable=True)
|
|
633
|
+
|
|
634
|
+
job_id = Column('job_id', UUIDType, ForeignKey('test_job.tj_id'), nullable=False, index=True)
|
|
635
|
+
user_id = Column('user_id', UUIDType, ForeignKey('user.user_id'), nullable=False, index=True)
|
|
636
|
+
|
|
637
|
+
fg_id = Column('fg_id', BigInteger, ForeignKey('feature_group.fg_id'), nullable=True, index=True)
|
|
638
|
+
|
|
639
|
+
job = relationship('TestJob', back_populates='runs', lazy='selectin')
|
|
640
|
+
|
|
641
|
+
user = relationship('User', back_populates='test_runs', lazy='selectin')
|
|
642
|
+
|
|
643
|
+
feature_group = relationship('FeatureGroup', back_populates='test_runs', lazy='selectin')
|
|
644
|
+
|
|
645
|
+
results = relationship('TestResult', back_populates='test_run', cascade='all, delete-orphan', lazy='selectin')
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
class TestResult(PychestrateModelBase, SerializableModel):
|
|
649
|
+
"""
|
|
650
|
+
A data model for a TestResult node that is part of a test result tree.
|
|
651
|
+
"""
|
|
652
|
+
__tablename__ = 'test_result'
|
|
653
|
+
|
|
654
|
+
instance = Column('tstr_instance', UUIDType, nullable=False, primary_key=True, default=uuid.uuid4, server_default=text('gen_random_uuid()'))
|
|
655
|
+
name = Column('tstr_name', VARCHAR(1024), nullable=False)
|
|
656
|
+
monikers = Column('tstr_monikers', JSON, nullable=True)
|
|
657
|
+
pivots = Column('tstr_pivots', JSON, nullable=True)
|
|
658
|
+
rtype = Column('tstr_rtype', String(50), nullable=False)
|
|
659
|
+
result = Column('tstr_result', String(50), nullable=False)
|
|
660
|
+
start = Column('tstr_start', DateTime(timezone=True), nullable=False, server_default=func.now())
|
|
661
|
+
stop = Column('tstr_stop', DateTime(timezone=True), nullable=True)
|
|
662
|
+
detail = Column('tstr_detail', JSON, nullable=True)
|
|
663
|
+
|
|
664
|
+
testrun = Column('tjr_instance', UUIDType, ForeignKey('test_job_run.tjr_instance'), nullable=True, index=True)
|
|
665
|
+
|
|
666
|
+
test_run = relationship('TestJobRun', back_populates='results', lazy='selectin')
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
class TestResultContainer(PychestrateModelBase, SerializableModel):
|
|
670
|
+
"""
|
|
671
|
+
A data model for a TestResultContainer node that is part of a test result tree. The
|
|
672
|
+
TestResultContainer node serves as a parent and container for individual result based
|
|
673
|
+
nodes.
|
|
674
|
+
"""
|
|
675
|
+
__tablename__ = 'test_result_container'
|
|
676
|
+
|
|
677
|
+
id = Column('tstrcont_id', BigInteger, primary_key=True, autoincrement=True)
|
|
678
|
+
name = Column('tstrcont_name', VARCHAR(1024), nullable=False)
|
|
679
|
+
instance = Column('tstrcont_instance', UUIDType, nullable=False, default=uuid.uuid4, server_default=text('gen_random_uuid()'))
|
|
680
|
+
parent = Column('tstrcont_parent', UUIDType, nullable=True)
|
|
681
|
+
rtype = Column('tstrcont_rtype', String(50), nullable=False)
|
|
682
|
+
|
|
683
|
+
testjob_id = Column('tj_id', UUIDType, ForeignKey('test_job.tj_id'), index=True)
|
|
684
|
+
|
|
685
|
+
test_job = relationship('TestJob', back_populates='result_containers', lazy='selectin')
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
class FeatureGroupMembership(PychestrateModelBase, SerializableModel):
|
|
689
|
+
"""
|
|
690
|
+
A data model for associating FeatureGroup(s) to Users(s)
|
|
691
|
+
"""
|
|
692
|
+
__tablename__ = "feature_group_membership"
|
|
693
|
+
|
|
694
|
+
fg_id = Column('fg_id', BigInteger, ForeignKey('feature_group.fg_id'), primary_key=True, index=True)
|
|
695
|
+
user_id = Column('user_id', UUIDType, ForeignKey('user.user_id'), primary_key=True, index=True)
|
|
696
|
+
|
|
697
|
+
join_date = Column('fgm_join_date', DateTime(timezone=True), nullable=False, server_default=func.now())
|
|
698
|
+
departure_date = Column('fgm_departure_date', DateTime(timezone=True), nullable=True)
|
|
699
|
+
|
|
700
|
+
feature_group = relationship('FeatureGroup', back_populates='memberships', lazy='selectin')
|
|
701
|
+
|
|
702
|
+
user = relationship('User', back_populates='feature_groups', lazy='selectin')
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
class OauthUser(PychestrateModelBase, SerializableModel):
|
|
706
|
+
"""Represents a user authenticated through an OAuth provider."""
|
|
707
|
+
|
|
708
|
+
__tablename__ = "users"
|
|
709
|
+
|
|
710
|
+
id = Column('user_id', VARCHAR(40), primary_key=True)
|
|
711
|
+
|
|
712
|
+
provider = Column('user_provider', VARCHAR(50), nullable=True, doc="OAuth provider name (google, github, gitlab, microsoft, apple)")
|
|
713
|
+
provider_ref_id = Column('user_provider_ref_id', VARCHAR(255), nullable=False, index=True, doc="Unique identifier from the OAuth provider" \
|
|
714
|
+
" (sub or id) for the user account")
|
|
715
|
+
firstname = Column('user_firstname', VARCHAR(255), nullable=False, doc="First name of the user, if provided")
|
|
716
|
+
lastname = Column('user_lastname', VARCHAR(255), nullable=False, doc="Last name of the user, if provided")
|
|
717
|
+
display_name = Column('user_display_name', VARCHAR(255), nullable=True, doc="Display name of the user")
|
|
718
|
+
username = Column('user_username', VARCHAR(255), nullable=False, doc="Username of the user, if provided")
|
|
719
|
+
email = Column('user_email', VARCHAR(255), nullable=False, doc="Email address associated with the account")
|
|
720
|
+
avatar_uri = Column('user_avatar_uri', VARCHAR(1024), nullable=True, doc="URI of the user's avatar or profile picture")
|
|
721
|
+
status = Column('user_status', VARCHAR(20), nullable=False, default='active', doc="Status of the user account (e.g., 'active', 'inactive')")
|
|
722
|
+
roles = Column('user_roles', VARCHAR(1024), nullable=True, doc="Comma-separated list of roles assigned to the user (e.g., 'admin,user')")
|
|
723
|
+
authtype = Column('user_authtype', VARCHAR(20), nullable=False, default='consumer', doc="Type of user (e.g., 'internal', 'consumer')")
|
|
724
|
+
created_at = Column('user_created_at', DateTime, default=utc_now, nullable=False, doc="Timestamp when the user record was created")
|
|
725
|
+
updated_at = Column('user_updated_at', DateTime, default=utc_now, onupdate=utc_now, nullable=False, doc="Timestamp when the user record was last updated")
|