infrahub-server 1.6.2__py3-none-any.whl → 1.7.0__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.
- infrahub/actions/tasks.py +4 -2
- infrahub/api/exceptions.py +2 -2
- infrahub/api/schema.py +3 -1
- infrahub/artifacts/tasks.py +1 -0
- infrahub/auth.py +2 -2
- infrahub/cli/db.py +54 -28
- infrahub/computed_attribute/gather.py +3 -4
- infrahub/computed_attribute/tasks.py +23 -6
- infrahub/config.py +8 -0
- infrahub/constants/enums.py +12 -0
- infrahub/core/account.py +12 -9
- infrahub/core/attribute.py +106 -108
- infrahub/core/branch/models.py +44 -71
- infrahub/core/branch/tasks.py +5 -3
- infrahub/core/changelog/diff.py +1 -20
- infrahub/core/changelog/models.py +0 -7
- infrahub/core/constants/__init__.py +17 -0
- infrahub/core/constants/database.py +0 -1
- infrahub/core/constants/schema.py +0 -1
- infrahub/core/convert_object_type/repository_conversion.py +3 -4
- infrahub/core/diff/branch_differ.py +1 -1
- infrahub/core/diff/conflict_transferer.py +1 -1
- infrahub/core/diff/data_check_synchronizer.py +4 -3
- infrahub/core/diff/enricher/cardinality_one.py +2 -2
- infrahub/core/diff/enricher/hierarchy.py +1 -1
- infrahub/core/diff/enricher/labels.py +1 -1
- infrahub/core/diff/merger/merger.py +28 -2
- infrahub/core/diff/merger/serializer.py +3 -10
- infrahub/core/diff/model/diff.py +1 -1
- infrahub/core/diff/query/merge.py +376 -135
- infrahub/core/diff/repository/repository.py +3 -1
- infrahub/core/graph/__init__.py +1 -1
- infrahub/core/graph/constraints.py +3 -3
- infrahub/core/graph/schema.py +2 -12
- infrahub/core/ipam/reconciler.py +8 -6
- infrahub/core/ipam/utilization.py +8 -15
- infrahub/core/manager.py +133 -152
- infrahub/core/merge.py +1 -1
- infrahub/core/metadata/__init__.py +0 -0
- infrahub/core/metadata/interface.py +37 -0
- infrahub/core/metadata/model.py +31 -0
- infrahub/core/metadata/query/__init__.py +0 -0
- infrahub/core/metadata/query/node_metadata.py +301 -0
- infrahub/core/migrations/graph/__init__.py +4 -0
- infrahub/core/migrations/graph/m012_convert_account_generic.py +12 -12
- infrahub/core/migrations/graph/m013_convert_git_password_credential.py +7 -12
- infrahub/core/migrations/graph/m017_add_core_profile.py +5 -2
- infrahub/core/migrations/graph/m018_uniqueness_nulls.py +2 -1
- infrahub/core/migrations/graph/m019_restore_rels_to_time.py +0 -10
- infrahub/core/migrations/graph/m020_duplicate_edges.py +0 -8
- infrahub/core/migrations/graph/m025_uniqueness_nulls.py +2 -1
- infrahub/core/migrations/graph/m026_0000_prefix_fix.py +2 -1
- infrahub/core/migrations/graph/m029_duplicates_cleanup.py +0 -1
- infrahub/core/migrations/graph/m031_check_number_attributes.py +2 -2
- infrahub/core/migrations/graph/m038_redo_0000_prefix_fix.py +2 -1
- infrahub/core/migrations/graph/m041_deleted_dup_edges.py +1 -1
- infrahub/core/migrations/graph/m049_remove_is_visible_relationship.py +53 -0
- infrahub/core/migrations/graph/m050_backfill_vertex_metadata.py +168 -0
- infrahub/core/migrations/query/__init__.py +2 -2
- infrahub/core/migrations/query/attribute_add.py +17 -6
- infrahub/core/migrations/query/attribute_remove.py +19 -5
- infrahub/core/migrations/query/attribute_rename.py +21 -5
- infrahub/core/migrations/query/node_duplicate.py +19 -4
- infrahub/core/migrations/query/schema_attribute_update.py +1 -1
- infrahub/core/migrations/schema/attribute_kind_update.py +26 -6
- infrahub/core/migrations/schema/attribute_name_update.py +1 -1
- infrahub/core/migrations/schema/attribute_supports_profile.py +5 -3
- infrahub/core/migrations/schema/models.py +3 -0
- infrahub/core/migrations/schema/node_attribute_add.py +5 -2
- infrahub/core/migrations/schema/node_attribute_remove.py +1 -1
- infrahub/core/migrations/schema/node_kind_update.py +1 -1
- infrahub/core/migrations/schema/node_remove.py +24 -2
- infrahub/core/migrations/schema/tasks.py +4 -1
- infrahub/core/migrations/shared.py +13 -6
- infrahub/core/models.py +6 -6
- infrahub/core/node/__init__.py +157 -58
- infrahub/core/node/base.py +9 -5
- infrahub/core/node/create.py +7 -3
- infrahub/core/node/delete_validator.py +1 -1
- infrahub/core/node/standard.py +100 -14
- infrahub/core/order.py +30 -0
- infrahub/core/property.py +0 -1
- infrahub/core/protocols.py +1 -0
- infrahub/core/protocols_base.py +10 -2
- infrahub/core/query/__init__.py +11 -6
- infrahub/core/query/attribute.py +164 -49
- infrahub/core/query/branch.py +58 -70
- infrahub/core/query/delete.py +1 -1
- infrahub/core/query/diff.py +7 -7
- infrahub/core/query/ipam.py +104 -43
- infrahub/core/query/node.py +1072 -281
- infrahub/core/query/relationship.py +531 -325
- infrahub/core/query/resource_manager.py +107 -18
- infrahub/core/query/standard_node.py +25 -5
- infrahub/core/query/utils.py +2 -4
- infrahub/core/relationship/constraints/count.py +1 -1
- infrahub/core/relationship/constraints/peer_kind.py +1 -1
- infrahub/core/relationship/constraints/peer_parent.py +1 -1
- infrahub/core/relationship/constraints/peer_relatives.py +1 -1
- infrahub/core/relationship/constraints/profiles_kind.py +1 -1
- infrahub/core/relationship/constraints/profiles_removal.py +168 -0
- infrahub/core/relationship/model.py +293 -139
- infrahub/core/schema/attribute_parameters.py +28 -1
- infrahub/core/schema/attribute_schema.py +11 -17
- infrahub/core/schema/basenode_schema.py +3 -0
- infrahub/core/schema/definitions/core/__init__.py +8 -2
- infrahub/core/schema/definitions/core/account.py +10 -10
- infrahub/core/schema/definitions/core/artifact.py +14 -8
- infrahub/core/schema/definitions/core/check.py +10 -4
- infrahub/core/schema/definitions/core/generator.py +26 -6
- infrahub/core/schema/definitions/core/graphql_query.py +1 -1
- infrahub/core/schema/definitions/core/group.py +9 -2
- infrahub/core/schema/definitions/core/ipam.py +80 -10
- infrahub/core/schema/definitions/core/menu.py +41 -7
- infrahub/core/schema/definitions/core/permission.py +16 -2
- infrahub/core/schema/definitions/core/profile.py +16 -2
- infrahub/core/schema/definitions/core/propose_change.py +24 -4
- infrahub/core/schema/definitions/core/propose_change_comment.py +23 -11
- infrahub/core/schema/definitions/core/propose_change_validator.py +50 -21
- infrahub/core/schema/definitions/core/repository.py +10 -0
- infrahub/core/schema/definitions/core/resource_pool.py +8 -1
- infrahub/core/schema/definitions/core/template.py +19 -2
- infrahub/core/schema/definitions/core/transform.py +11 -5
- infrahub/core/schema/definitions/core/webhook.py +27 -9
- infrahub/core/schema/manager.py +63 -43
- infrahub/core/schema/relationship_schema.py +6 -2
- infrahub/core/schema/schema_branch.py +115 -11
- infrahub/core/task/task.py +4 -2
- infrahub/core/utils.py +3 -25
- infrahub/core/validators/aggregated_checker.py +1 -1
- infrahub/core/validators/attribute/choices.py +1 -1
- infrahub/core/validators/attribute/enum.py +1 -1
- infrahub/core/validators/attribute/kind.py +6 -3
- infrahub/core/validators/attribute/length.py +1 -1
- infrahub/core/validators/attribute/min_max.py +1 -1
- infrahub/core/validators/attribute/number_pool.py +1 -1
- infrahub/core/validators/attribute/optional.py +1 -1
- infrahub/core/validators/attribute/regex.py +1 -1
- infrahub/core/validators/determiner.py +3 -3
- infrahub/core/validators/node/attribute.py +1 -1
- infrahub/core/validators/node/relationship.py +1 -1
- infrahub/core/validators/relationship/peer.py +1 -1
- infrahub/database/__init__.py +4 -4
- infrahub/dependencies/builder/constraint/grouped/node_runner.py +2 -0
- infrahub/dependencies/builder/constraint/relationship_manager/profiles_removal.py +8 -0
- infrahub/dependencies/registry.py +2 -0
- infrahub/display_labels/tasks.py +12 -3
- infrahub/git/integrator.py +18 -18
- infrahub/git/tasks.py +1 -1
- infrahub/git/utils.py +1 -1
- infrahub/graphql/app.py +2 -2
- infrahub/graphql/constants.py +3 -0
- infrahub/graphql/context.py +1 -1
- infrahub/graphql/field_extractor.py +1 -1
- infrahub/graphql/initialization.py +11 -0
- infrahub/graphql/loaders/account.py +134 -0
- infrahub/graphql/loaders/node.py +5 -12
- infrahub/graphql/loaders/peers.py +5 -7
- infrahub/graphql/manager.py +175 -21
- infrahub/graphql/metadata.py +91 -0
- infrahub/graphql/mutations/account.py +6 -6
- infrahub/graphql/mutations/attribute.py +0 -2
- infrahub/graphql/mutations/branch.py +9 -5
- infrahub/graphql/mutations/computed_attribute.py +1 -1
- infrahub/graphql/mutations/display_label.py +1 -1
- infrahub/graphql/mutations/hfid.py +1 -1
- infrahub/graphql/mutations/ipam.py +4 -6
- infrahub/graphql/mutations/main.py +9 -4
- infrahub/graphql/mutations/profile.py +16 -22
- infrahub/graphql/mutations/proposed_change.py +4 -4
- infrahub/graphql/mutations/relationship.py +40 -10
- infrahub/graphql/mutations/repository.py +14 -12
- infrahub/graphql/mutations/schema.py +2 -2
- infrahub/graphql/order.py +14 -0
- infrahub/graphql/queries/branch.py +62 -6
- infrahub/graphql/queries/diff/tree.py +5 -5
- infrahub/graphql/queries/resource_manager.py +25 -24
- infrahub/graphql/resolvers/account_metadata.py +84 -0
- infrahub/graphql/resolvers/ipam.py +6 -8
- infrahub/graphql/resolvers/many_relationship.py +77 -35
- infrahub/graphql/resolvers/resolver.py +59 -14
- infrahub/graphql/resolvers/single_relationship.py +87 -23
- infrahub/graphql/subscription/graphql_query.py +2 -0
- infrahub/graphql/types/__init__.py +0 -1
- infrahub/graphql/types/attribute.py +10 -5
- infrahub/graphql/types/branch.py +40 -53
- infrahub/graphql/types/enums.py +3 -0
- infrahub/graphql/types/metadata.py +28 -0
- infrahub/graphql/types/node.py +22 -2
- infrahub/graphql/types/relationship.py +10 -2
- infrahub/graphql/types/standard_node.py +12 -7
- infrahub/hfid/tasks.py +12 -3
- infrahub/lock.py +7 -0
- infrahub/menu/repository.py +1 -1
- infrahub/patch/queries/base.py +1 -1
- infrahub/pools/number.py +1 -8
- infrahub/profiles/gather.py +56 -0
- infrahub/profiles/mandatory_fields_checker.py +116 -0
- infrahub/profiles/models.py +66 -0
- infrahub/profiles/node_applier.py +154 -13
- infrahub/profiles/queries/get_profile_data.py +143 -31
- infrahub/profiles/tasks.py +79 -27
- infrahub/profiles/triggers.py +22 -0
- infrahub/proposed_change/action_checker.py +1 -1
- infrahub/proposed_change/tasks.py +4 -1
- infrahub/services/__init__.py +1 -1
- infrahub/services/adapters/cache/nats.py +1 -1
- infrahub/services/adapters/cache/redis.py +7 -0
- infrahub/tasks/artifact.py +1 -0
- infrahub/transformations/tasks.py +2 -2
- infrahub/trigger/catalogue.py +2 -0
- infrahub/trigger/models.py +1 -0
- infrahub/trigger/setup.py +3 -3
- infrahub/trigger/tasks.py +3 -0
- infrahub/validators/tasks.py +1 -0
- infrahub/webhook/gather.py +1 -1
- infrahub/webhook/models.py +1 -1
- infrahub/webhook/tasks.py +23 -7
- infrahub/workers/dependencies.py +9 -3
- infrahub/workers/infrahub_async.py +13 -4
- infrahub/workflows/catalogue.py +19 -0
- infrahub_sdk/analyzer.py +2 -2
- infrahub_sdk/branch.py +12 -39
- infrahub_sdk/checks.py +4 -4
- infrahub_sdk/client.py +36 -0
- infrahub_sdk/ctl/cli_commands.py +2 -1
- infrahub_sdk/ctl/graphql.py +15 -4
- infrahub_sdk/ctl/utils.py +2 -2
- infrahub_sdk/enums.py +6 -0
- infrahub_sdk/graphql/renderers.py +21 -0
- infrahub_sdk/graphql/utils.py +85 -0
- infrahub_sdk/node/attribute.py +12 -2
- infrahub_sdk/node/constants.py +12 -0
- infrahub_sdk/node/metadata.py +69 -0
- infrahub_sdk/node/node.py +65 -14
- infrahub_sdk/node/property.py +3 -0
- infrahub_sdk/node/related_node.py +37 -5
- infrahub_sdk/node/relationship.py +18 -1
- infrahub_sdk/operation.py +2 -2
- infrahub_sdk/schema/repository.py +1 -2
- infrahub_sdk/transforms.py +2 -2
- infrahub_sdk/types.py +18 -2
- {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/METADATA +17 -16
- {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/RECORD +252 -231
- infrahub_testcontainers/container.py +3 -3
- infrahub_testcontainers/docker-compose-cluster.test.yml +7 -7
- infrahub_testcontainers/docker-compose.test.yml +13 -5
- infrahub_testcontainers/models.py +3 -3
- infrahub_testcontainers/performance_test.py +1 -1
- infrahub/graphql/models.py +0 -6
- {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/WHEEL +0 -0
- {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/entry_points.txt +0 -0
- {infrahub_server-1.6.2.dist-info → infrahub_server-1.7.0.dist-info}/licenses/LICENSE.txt +0 -0
infrahub/core/changelog/diff.py
CHANGED
|
@@ -116,13 +116,6 @@ class DiffChangelogCollector:
|
|
|
116
116
|
value_current=self._convert_string_boolean_value(value=attr_property.new_value),
|
|
117
117
|
value_previous=self._convert_string_boolean_value(value=attr_property.previous_value),
|
|
118
118
|
)
|
|
119
|
-
case DatabaseEdgeType.IS_VISIBLE:
|
|
120
|
-
if _keep_branch_update(diff_property=attr_property):
|
|
121
|
-
changelog_attribute.add_property(
|
|
122
|
-
name="is_visible",
|
|
123
|
-
value_current=self._convert_string_boolean_value(value=attr_property.new_value),
|
|
124
|
-
value_previous=self._convert_string_boolean_value(value=attr_property.previous_value),
|
|
125
|
-
)
|
|
126
119
|
case DatabaseEdgeType.HAS_SOURCE:
|
|
127
120
|
if _keep_branch_update(diff_property=attr_property):
|
|
128
121
|
changelog_attribute.add_property(
|
|
@@ -176,12 +169,6 @@ class DiffChangelogCollector:
|
|
|
176
169
|
value_current=self._convert_string_boolean_value(value=rel_prop.new_value),
|
|
177
170
|
value_previous=self._convert_string_boolean_value(value=rel_prop.previous_value),
|
|
178
171
|
)
|
|
179
|
-
case DatabaseEdgeType.IS_VISIBLE:
|
|
180
|
-
changelog_rel.add_property(
|
|
181
|
-
name="is_visible",
|
|
182
|
-
value_current=self._convert_string_boolean_value(value=rel_prop.new_value),
|
|
183
|
-
value_previous=self._convert_string_boolean_value(value=rel_prop.previous_value),
|
|
184
|
-
)
|
|
185
172
|
case DatabaseEdgeType.HAS_OWNER:
|
|
186
173
|
changelog_rel.add_property(
|
|
187
174
|
name="owner",
|
|
@@ -198,7 +185,7 @@ class DiffChangelogCollector:
|
|
|
198
185
|
node.add_relationship(relationship_changelog=changelog_rel)
|
|
199
186
|
|
|
200
187
|
def _convert_string_boolean_value(self, value: str | None) -> bool | None:
|
|
201
|
-
"""Convert string based boolean for is_protected
|
|
188
|
+
"""Convert string based boolean for is_protected."""
|
|
202
189
|
if value is not None:
|
|
203
190
|
return str_to_bool(value)
|
|
204
191
|
|
|
@@ -218,12 +205,6 @@ class DiffChangelogCollector:
|
|
|
218
205
|
)
|
|
219
206
|
for peer_prop in peer.properties:
|
|
220
207
|
match peer_prop.property_type:
|
|
221
|
-
case DatabaseEdgeType.IS_VISIBLE:
|
|
222
|
-
peer_log.add_property(
|
|
223
|
-
name="is_visible",
|
|
224
|
-
value_current=self._convert_string_boolean_value(value=peer_prop.new_value),
|
|
225
|
-
value_previous=self._convert_string_boolean_value(value=peer_prop.previous_value),
|
|
226
|
-
)
|
|
227
208
|
case DatabaseEdgeType.IS_PROTECTED:
|
|
228
209
|
peer_log.add_property(
|
|
229
210
|
name="is_protected",
|
|
@@ -186,9 +186,6 @@ class RelationshipCardinalityManyChangelog(BaseModel):
|
|
|
186
186
|
properties["is_protected"] = PropertyChangelog(
|
|
187
187
|
name="is_protected", value=relationship.is_protected, value_previous=None
|
|
188
188
|
)
|
|
189
|
-
properties["is_visible"] = PropertyChangelog(
|
|
190
|
-
name="is_visible", value=relationship.is_protected, value_previous=None
|
|
191
|
-
)
|
|
192
189
|
if owner := getattr(relationship, "owner_id", None):
|
|
193
190
|
properties["owner"] = PropertyChangelog(name="owner", value=owner, value_previous=None)
|
|
194
191
|
if source := getattr(relationship, "source_id", None):
|
|
@@ -280,9 +277,6 @@ class NodeChangelog(BaseModel):
|
|
|
280
277
|
changelog_relationship.add_property(
|
|
281
278
|
name="is_protected", value_current=relationship.is_protected, value_previous=None
|
|
282
279
|
)
|
|
283
|
-
changelog_relationship.add_property(
|
|
284
|
-
name="is_visible", value_current=relationship.is_visible, value_previous=None
|
|
285
|
-
)
|
|
286
280
|
self.relationships[changelog_relationship.name] = changelog_relationship
|
|
287
281
|
elif relationship.schema.cardinality == RelationshipCardinality.MANY:
|
|
288
282
|
if relationship.schema.name not in self.relationships:
|
|
@@ -340,7 +334,6 @@ class NodeChangelog(BaseModel):
|
|
|
340
334
|
if owner_id := getattr(attribute, "owner_id", None):
|
|
341
335
|
changelog_attribute.add_property(name="owner", value_current=owner_id, value_previous=None)
|
|
342
336
|
changelog_attribute.add_property(name="is_protected", value_current=attribute.is_protected, value_previous=None)
|
|
343
|
-
changelog_attribute.add_property(name="is_visible", value_current=attribute.is_visible, value_previous=None)
|
|
344
337
|
self.attributes[changelog_attribute.name] = changelog_attribute
|
|
345
338
|
|
|
346
339
|
def get_related_nodes(self) -> list[ChangelogRelatedNode]:
|
|
@@ -46,6 +46,8 @@ NULL_VALUE = "NULL"
|
|
|
46
46
|
|
|
47
47
|
EVENT_NAMESPACE = "infrahub"
|
|
48
48
|
|
|
49
|
+
SYSTEM_USER_ID = "__system__"
|
|
50
|
+
|
|
49
51
|
|
|
50
52
|
class EventType(InfrahubStringEnum):
|
|
51
53
|
BRANCH_CREATED = f"{EVENT_NAMESPACE}.branch.created"
|
|
@@ -359,6 +361,21 @@ class AttributeDBNodeType(Flag):
|
|
|
359
361
|
IPNETWORK = DEFAULT | INDEX_ONLY | IPNETWORK_ONLY
|
|
360
362
|
|
|
361
363
|
|
|
364
|
+
class MetadataOptions(Flag):
|
|
365
|
+
NONE = 0
|
|
366
|
+
SOURCE = auto()
|
|
367
|
+
OWNER = auto()
|
|
368
|
+
LINKED_NODES = SOURCE | OWNER
|
|
369
|
+
IS_PROTECTED = auto()
|
|
370
|
+
CREATED_BY = auto()
|
|
371
|
+
CREATED_AT = auto()
|
|
372
|
+
UPDATED_BY = auto()
|
|
373
|
+
UPDATED_AT = auto()
|
|
374
|
+
TIMESTAMPS = CREATED_AT | UPDATED_AT
|
|
375
|
+
USERS = CREATED_BY | UPDATED_BY
|
|
376
|
+
USER_TIMESTAMPS = TIMESTAMPS | USERS
|
|
377
|
+
|
|
378
|
+
|
|
362
379
|
RESTRICTED_NAMESPACES: list[str] = [
|
|
363
380
|
"Account",
|
|
364
381
|
"Branch",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from infrahub import lock
|
|
2
2
|
from infrahub.core.branch import Branch
|
|
3
|
-
from infrahub.core.constants.infrahubkind import REPOSITORYVALIDATOR, USERVALIDATOR
|
|
4
3
|
from infrahub.core.convert_object_type.object_conversion import (
|
|
5
4
|
ConversionFieldInput,
|
|
6
5
|
convert_object_type,
|
|
@@ -8,7 +7,7 @@ from infrahub.core.convert_object_type.object_conversion import (
|
|
|
8
7
|
)
|
|
9
8
|
from infrahub.core.manager import NodeManager
|
|
10
9
|
from infrahub.core.node import Node
|
|
11
|
-
from infrahub.core.protocols import CoreReadOnlyRepository, CoreRepository
|
|
10
|
+
from infrahub.core.protocols import CoreReadOnlyRepository, CoreRepository, CoreRepositoryValidator, CoreUserValidator
|
|
12
11
|
from infrahub.core.schema import NodeSchema
|
|
13
12
|
from infrahub.core.timestamp import Timestamp
|
|
14
13
|
from infrahub.database import InfrahubDatabase
|
|
@@ -35,11 +34,11 @@ async def convert_repository_type(
|
|
|
35
34
|
|
|
36
35
|
# Fetch validators before deleting the repository otherwise validator-repository would no longer exist
|
|
37
36
|
user_validators = await NodeManager.query(
|
|
38
|
-
db=dbt, schema=
|
|
37
|
+
db=dbt, schema=CoreUserValidator, prefetch_relationships=True, filters={"repository__id": repository.id}
|
|
39
38
|
)
|
|
40
39
|
repository_validators = await NodeManager.query(
|
|
41
40
|
db=dbt,
|
|
42
|
-
schema=
|
|
41
|
+
schema=CoreRepositoryValidator,
|
|
43
42
|
prefetch_relationships=True,
|
|
44
43
|
filters={"repository__id": repository.id},
|
|
45
44
|
)
|
|
@@ -9,7 +9,7 @@ from .model.path import (
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class DiffConflictTransferer:
|
|
12
|
-
def __init__(self, diff_combiner: DiffCombiner):
|
|
12
|
+
def __init__(self, diff_combiner: DiffCombiner) -> None:
|
|
13
13
|
self.diff_combiner = diff_combiner
|
|
14
14
|
|
|
15
15
|
async def transfer(self, earlier: EnrichedDiffRoot, later: EnrichedDiffRoot) -> None:
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
|
|
3
|
-
from infrahub.core.constants import BranchConflictKeep
|
|
3
|
+
from infrahub.core.constants import BranchConflictKeep
|
|
4
4
|
from infrahub.core.diff.query.filters import EnrichedDiffQueryFilters
|
|
5
5
|
from infrahub.core.integrity.object_conflict.conflict_recorder import ObjectConflictValidatorRecorder
|
|
6
6
|
from infrahub.core.manager import NodeManager
|
|
7
7
|
from infrahub.core.node import Node
|
|
8
|
+
from infrahub.core.protocols import CoreProposedChange
|
|
8
9
|
from infrahub.database import InfrahubDatabase
|
|
9
10
|
from infrahub.exceptions import SchemaNotFoundError
|
|
10
11
|
from infrahub.proposed_change.constants import ProposedChangeState
|
|
@@ -28,7 +29,7 @@ class DiffDataCheckSynchronizer:
|
|
|
28
29
|
conflicts_extractor: DiffConflictsExtractor,
|
|
29
30
|
conflict_recorder: ObjectConflictValidatorRecorder,
|
|
30
31
|
diff_repository: DiffRepository,
|
|
31
|
-
):
|
|
32
|
+
) -> None:
|
|
32
33
|
self.db = db
|
|
33
34
|
self.conflicts_extractor = conflicts_extractor
|
|
34
35
|
self.conflict_recorder = conflict_recorder
|
|
@@ -52,7 +53,7 @@ class DiffDataCheckSynchronizer:
|
|
|
52
53
|
try:
|
|
53
54
|
proposed_changes = await NodeManager.query(
|
|
54
55
|
db=self.db,
|
|
55
|
-
schema=
|
|
56
|
+
schema=CoreProposedChange,
|
|
56
57
|
filters={"source_branch": enriched_diff.diff_branch_name, "state": ProposedChangeState.OPEN},
|
|
57
58
|
)
|
|
58
59
|
except SchemaNotFoundError:
|
|
@@ -28,10 +28,10 @@ class DiffCardinalityOneEnricher(DiffEnricherInterface):
|
|
|
28
28
|
- the peer_id property of the element will be the latest non-null peer ID for this element
|
|
29
29
|
- the element MUST have an EnrichedDiffProperty of property_type=IS_RELATED that correctly records
|
|
30
30
|
the previous and new values of the peer ID for this element
|
|
31
|
-
- changes to properties (
|
|
31
|
+
- changes to properties (IS_PROTECTED, etc) of a cardinality=one relationship are consolidated as well
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
|
-
def __init__(self, db: InfrahubDatabase):
|
|
34
|
+
def __init__(self, db: InfrahubDatabase) -> None:
|
|
35
35
|
self.db = db
|
|
36
36
|
self._node_schema_map: dict[str, MainSchemaTypes] = {}
|
|
37
37
|
|
|
@@ -24,7 +24,7 @@ log = get_logger()
|
|
|
24
24
|
class DiffHierarchyEnricher(DiffEnricherInterface):
|
|
25
25
|
"""Add hierarchy and parent/component nodes to diff even if the higher-level nodes are unchanged"""
|
|
26
26
|
|
|
27
|
-
def __init__(self, db: InfrahubDatabase, parent_adder: DiffParentNodeAdder):
|
|
27
|
+
def __init__(self, db: InfrahubDatabase, parent_adder: DiffParentNodeAdder) -> None:
|
|
28
28
|
self.db = db
|
|
29
29
|
self.parent_adder = parent_adder
|
|
30
30
|
|
|
@@ -35,7 +35,7 @@ class DisplayLabelRequest:
|
|
|
35
35
|
class DiffLabelsEnricher(DiffEnricherInterface):
|
|
36
36
|
"""Add display labels for nodes and labels for relationships"""
|
|
37
37
|
|
|
38
|
-
def __init__(self, db: InfrahubDatabase):
|
|
38
|
+
def __init__(self, db: InfrahubDatabase) -> None:
|
|
39
39
|
self.db = db
|
|
40
40
|
self._base_branch_name: str | None = None
|
|
41
41
|
self._diff_branch_name: str | None = None
|
|
@@ -6,6 +6,7 @@ from infrahub.core import registry
|
|
|
6
6
|
from infrahub.core.constants import DiffAction
|
|
7
7
|
from infrahub.core.diff.model.path import BranchTrackingId
|
|
8
8
|
from infrahub.core.diff.query.merge import (
|
|
9
|
+
DiffMergeMetadataQuery,
|
|
9
10
|
DiffMergeMigratedKindsQuery,
|
|
10
11
|
DiffMergePropertiesQuery,
|
|
11
12
|
DiffMergeQuery,
|
|
@@ -26,6 +27,8 @@ log = get_logger()
|
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
class DiffMerger:
|
|
30
|
+
metadata_batch_size = 500
|
|
31
|
+
|
|
29
32
|
def __init__(
|
|
30
33
|
self,
|
|
31
34
|
db: InfrahubDatabase,
|
|
@@ -33,12 +36,13 @@ class DiffMerger:
|
|
|
33
36
|
destination_branch: Branch,
|
|
34
37
|
diff_repository: DiffRepository,
|
|
35
38
|
serializer: DiffMergeSerializer,
|
|
36
|
-
):
|
|
39
|
+
) -> None:
|
|
37
40
|
self.source_branch = source_branch
|
|
38
41
|
self.destination_branch = destination_branch
|
|
39
42
|
self.db = db
|
|
40
43
|
self.diff_repository = diff_repository
|
|
41
44
|
self.serializer = serializer
|
|
45
|
+
self._affected_node_uuids: list[str] = []
|
|
42
46
|
|
|
43
47
|
async def merge_graph(self, at: Timestamp) -> EnrichedDiffRoot:
|
|
44
48
|
tracking_id = BranchTrackingId(name=self.source_branch.name)
|
|
@@ -69,6 +73,7 @@ class DiffMerger:
|
|
|
69
73
|
# make sure that we use the ADDED db_id if it exists
|
|
70
74
|
# it will not if a node was migrated and then deleted
|
|
71
75
|
migrated_kinds_id_map[n.uuid] = n.identifier.db_id
|
|
76
|
+
|
|
72
77
|
async for node_diff_dicts, property_diff_dicts in self.serializer.serialize_diff(diff=enriched_diff):
|
|
73
78
|
if node_diff_dicts:
|
|
74
79
|
log.info(f"Merging batch of nodes #{batch_num}")
|
|
@@ -105,13 +110,34 @@ class DiffMerger:
|
|
|
105
110
|
)
|
|
106
111
|
await migrated_merge_query.execute(db=self.db)
|
|
107
112
|
|
|
113
|
+
affected_node_uuids = [n.uuid for n in enriched_diff.nodes]
|
|
114
|
+
self._affected_node_uuids = affected_node_uuids
|
|
115
|
+
if affected_node_uuids:
|
|
116
|
+
for i in range(0, len(affected_node_uuids), self.metadata_batch_size):
|
|
117
|
+
batch_uuids = affected_node_uuids[i : i + self.metadata_batch_size]
|
|
118
|
+
log.info(f"Updating metadata for batch {i // self.metadata_batch_size + 1} ({len(batch_uuids)} nodes)")
|
|
119
|
+
metadata_query = await DiffMergeMetadataQuery.init(
|
|
120
|
+
db=self.db,
|
|
121
|
+
branch=self.source_branch,
|
|
122
|
+
at=at,
|
|
123
|
+
target_branch=self.destination_branch,
|
|
124
|
+
node_uuids=batch_uuids,
|
|
125
|
+
)
|
|
126
|
+
await metadata_query.execute(db=self.db)
|
|
127
|
+
|
|
108
128
|
self.source_branch.branched_from = at.to_string()
|
|
109
129
|
await self.source_branch.save(db=self.db)
|
|
110
130
|
registry.branch[self.source_branch.name] = self.source_branch
|
|
111
131
|
return enriched_diff
|
|
112
132
|
|
|
113
133
|
async def rollback(self, at: Timestamp) -> None:
|
|
134
|
+
if not self._affected_node_uuids:
|
|
135
|
+
return
|
|
114
136
|
rollback_query = await DiffMergeRollbackQuery.init(
|
|
115
|
-
db=self.db,
|
|
137
|
+
db=self.db,
|
|
138
|
+
branch=self.source_branch,
|
|
139
|
+
target_branch=self.destination_branch,
|
|
140
|
+
at=at,
|
|
141
|
+
node_uuids=self._affected_node_uuids,
|
|
116
142
|
)
|
|
117
143
|
await rollback_query.execute(db=self.db)
|
|
@@ -93,9 +93,7 @@ class DiffMergeSerializer:
|
|
|
93
93
|
if property_type in (DatabaseEdgeType.HAS_OWNER, DatabaseEdgeType.HAS_SOURCE, DatabaseEdgeType.IS_RELATED):
|
|
94
94
|
return raw_value
|
|
95
95
|
# these are boolean
|
|
96
|
-
if
|
|
97
|
-
raw_value, str
|
|
98
|
-
):
|
|
96
|
+
if property_type == DatabaseEdgeType.IS_PROTECTED and isinstance(raw_value, str):
|
|
99
97
|
return raw_value.lower() == "true"
|
|
100
98
|
# this must be HAS_VALUE
|
|
101
99
|
if raw_value in (None, NULL_VALUE):
|
|
@@ -249,13 +247,8 @@ class DiffMergeSerializer:
|
|
|
249
247
|
return attr_dict, attr_prop_dict
|
|
250
248
|
|
|
251
249
|
def _get_default_property_merge_dicts(self, action: DiffAction) -> dict[DatabaseEdgeType, PropertyMergeDict]:
|
|
252
|
-
# start with default values for
|
|
250
|
+
# start with default values for IS_PROTECTED b/c we always want to update them during a merge
|
|
253
251
|
return {
|
|
254
|
-
DatabaseEdgeType.IS_VISIBLE: PropertyMergeDict(
|
|
255
|
-
property_type=DatabaseEdgeType.IS_VISIBLE.value,
|
|
256
|
-
action=self._to_action_str(action),
|
|
257
|
-
value=None,
|
|
258
|
-
),
|
|
259
252
|
DatabaseEdgeType.IS_PROTECTED: PropertyMergeDict(
|
|
260
253
|
property_type=DatabaseEdgeType.IS_PROTECTED.value,
|
|
261
254
|
action=self._to_action_str(action),
|
|
@@ -335,7 +328,7 @@ class DiffMergeSerializer:
|
|
|
335
328
|
# handled above
|
|
336
329
|
continue
|
|
337
330
|
python_value_type: type = str
|
|
338
|
-
if property_diff.property_type
|
|
331
|
+
if property_diff.property_type is DatabaseEdgeType.IS_PROTECTED:
|
|
339
332
|
python_value_type = bool
|
|
340
333
|
actions_and_values = self._get_property_actions_and_values(
|
|
341
334
|
property_diff=property_diff, python_value_type=python_value_type
|
infrahub/core/diff/model/diff.py
CHANGED
|
@@ -26,7 +26,7 @@ class BaseDiffElement(BaseModel):
|
|
|
26
26
|
"""
|
|
27
27
|
resp: dict[str, Any] = {}
|
|
28
28
|
for key, value in self:
|
|
29
|
-
field_info = self.model_fields[key]
|
|
29
|
+
field_info = self.__class__.model_fields[key]
|
|
30
30
|
if isinstance(value, BaseModel):
|
|
31
31
|
resp[key] = value.to_graphql() # type: ignore[attr-defined]
|
|
32
32
|
elif isinstance(value, dict):
|