Skip to content

Commit 1536947

Browse files
Slurpit one to many support (#32)
* Fix issue with object reference
1 parent 6f2a9c6 commit 1536947

File tree

7 files changed

+51
-54
lines changed

7 files changed

+51
-54
lines changed

examples/slurpit_to_infrahub/config.yml

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ name: from-slurpit
33
source:
44
name: slurpitsync
55
settings:
6-
url: "http://localhost"
7-
api_key: "<API_KEY>"
6+
url: "<URL>"
7+
api_key: "<TOKEN>"
88

99
destination:
1010
name: infrahub
@@ -23,7 +23,7 @@ order: [
2323
"InfraVLAN",
2424
"InfraVRF",
2525
"InfraInterface",
26-
"InfraPrefix",
26+
"InfraPrefix",
2727
"InfraIPAddress"
2828
]
2929

@@ -129,6 +129,9 @@ schema_mapping:
129129
mapping: Version
130130
- name: file
131131
mapping: File
132+
- name: devices
133+
mapping: hostname
134+
reference: InfraDevice
132135

133136
- name: InfraVLAN
134137
identifiers: ['vlan_id', "name"]
@@ -141,7 +144,7 @@ schema_mapping:
141144

142145
- name: InfraVRF
143146
identifiers: ["name"]
144-
filters:
147+
filters:
145148
- field: Vrf
146149
operation: is_not_empty
147150
mapping: planning_results.routing-table
@@ -152,17 +155,20 @@ schema_mapping:
152155
- name: InfraInterface
153156
identifiers: ["device", "name"]
154157
mapping: planning_results.interfaces
155-
fields:
158+
transforms:
159+
- field: desc_string
160+
expression: "{{Description | string}}"
161+
fields:
156162
- name: name
157163
mapping: Interface
158164
- name: description
159-
mapping: Description
165+
mapping: desc_string
160166
- name: mac_address
161167
mapping: MAC_normalized
162168
- name: device
163169
mapping: hostname
164170
reference: InfraDevice
165-
171+
166172
- name: InfraPrefix
167173
identifiers: ['vrf', 'prefix']
168174
mapping: filter_networks
@@ -174,7 +180,7 @@ schema_mapping:
174180
reference: InfraVRF
175181

176182
- name: InfraIPAddress
177-
identifiers: ["address", 'prefix']
183+
identifiers: ["address", 'ip_prefix']
178184
mapping: filter_interfaces
179185
transforms:
180186
- field: dev_int
@@ -187,6 +193,6 @@ schema_mapping:
187193
- name: interface
188194
mapping: dev_int
189195
reference: InfraInterface
190-
- name: prefix
196+
- name: ip_prefix
191197
mapping: vrf_prefix
192198
reference: InfraPrefix

examples/slurpit_to_infrahub/infrahub/sync_adapter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
from .sync_models import (
44
InfraDevice,
55
InfraHardwareInfo,
6-
InfraInterface,
76
InfraIPAddress,
7+
InfraInterface,
88
InfraPlatform,
99
InfraPrefix,
10-
InfraVersion,
1110
InfraVLAN,
1211
InfraVRF,
12+
InfraVersion,
1313
LocationGeneric,
1414
OrganizationGeneric,
1515
TemplateDeviceType,

examples/slurpit_to_infrahub/infrahub/sync_models.py

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
from typing import Any, Optional
1+
from typing import Any, List, Optional
22

33
from infrahub_sync.adapters.infrahub import InfrahubModel
44

5-
65
# -------------------------------------------------------
76
# AUTO-GENERATED FILE, DO NOT MODIFY
87
# This file has been generated with the command `infrahub-sync generate`
@@ -22,7 +21,6 @@ class InfraDevice(InfrahubModel):
2221
local_id: Optional[str] = None
2322
local_data: Optional[Any] = None
2423

25-
2624
class InfraHardwareInfo(InfrahubModel):
2725
_modelname = "InfraHardwareInfo"
2826
_identifiers = ("device", "serial")
@@ -37,19 +35,17 @@ class InfraHardwareInfo(InfrahubModel):
3735
local_id: Optional[str] = None
3836
local_data: Optional[Any] = None
3937

40-
4138
class InfraIPAddress(InfrahubModel):
4239
_modelname = "InfraIPAddress"
43-
_identifiers = ("address", "prefix")
40+
_identifiers = ("address", "ip_prefix")
4441
_attributes = ("interface",)
4542
address: str
4643
interface: Optional[str] = None
47-
prefix: Optional[str] = None
44+
ip_prefix: Optional[str] = None
4845

4946
local_id: Optional[str] = None
5047
local_data: Optional[Any] = None
5148

52-
5349
class InfraInterface(InfrahubModel):
5450
_modelname = "InfraInterface"
5551
_identifiers = ("device", "name")
@@ -62,7 +58,6 @@ class InfraInterface(InfrahubModel):
6258
local_id: Optional[str] = None
6359
local_data: Optional[Any] = None
6460

65-
6661
class InfraPlatform(InfrahubModel):
6762
_modelname = "InfraPlatform"
6863
_identifiers = ("name",)
@@ -72,7 +67,6 @@ class InfraPlatform(InfrahubModel):
7267
local_id: Optional[str] = None
7368
local_data: Optional[Any] = None
7469

75-
7670
class InfraPrefix(InfrahubModel):
7771
_modelname = "InfraPrefix"
7872
_identifiers = ("vrf", "prefix")
@@ -83,7 +77,6 @@ class InfraPrefix(InfrahubModel):
8377
local_id: Optional[str] = None
8478
local_data: Optional[Any] = None
8579

86-
8780
class InfraVLAN(InfrahubModel):
8881
_modelname = "InfraVLAN"
8982
_identifiers = ("vlan_id", "name")
@@ -94,7 +87,6 @@ class InfraVLAN(InfrahubModel):
9487
local_id: Optional[str] = None
9588
local_data: Optional[Any] = None
9689

97-
9890
class InfraVRF(InfrahubModel):
9991
_modelname = "InfraVRF"
10092
_identifiers = ("name",)
@@ -104,37 +96,35 @@ class InfraVRF(InfrahubModel):
10496
local_id: Optional[str] = None
10597
local_data: Optional[Any] = None
10698

107-
10899
class InfraVersion(InfrahubModel):
109100
_modelname = "InfraVersion"
110101
_identifiers = ("version",)
111-
_attributes = ("file",)
102+
_attributes = ("devices", "file")
112103
version: str
113104
file: Optional[str] = None
105+
devices: Optional[List[str]] = []
114106

115107
local_id: Optional[str] = None
116108
local_data: Optional[Any] = None
117109

118-
119110
class LocationGeneric(InfrahubModel):
120111
_modelname = "LocationGeneric"
121112
_identifiers = ("name",)
122-
_attributes = ("description", "number", "street", "zipcode", "country", "phonenumber", "city", "county", "state")
113+
_attributes = ("description", "number", "street", "city", "county", "state", "zipcode", "country", "phonenumber")
123114
name: str
124115
description: Optional[str] = None
125116
number: Optional[str] = None
126117
street: Optional[str] = None
127-
zipcode: Optional[str] = None
128-
country: Optional[str] = None
129-
phonenumber: Optional[str] = None
130118
city: Optional[str] = None
131119
county: Optional[str] = None
132120
state: Optional[str] = None
121+
zipcode: Optional[str] = None
122+
country: Optional[str] = None
123+
phonenumber: Optional[str] = None
133124

134125
local_id: Optional[str] = None
135126
local_data: Optional[Any] = None
136127

137-
138128
class OrganizationGeneric(InfrahubModel):
139129
_modelname = "OrganizationGeneric"
140130
_identifiers = ("name",)
@@ -145,7 +135,6 @@ class OrganizationGeneric(InfrahubModel):
145135
local_id: Optional[str] = None
146136
local_data: Optional[Any] = None
147137

148-
149138
class TemplateDeviceType(InfrahubModel):
150139
_modelname = "TemplateDeviceType"
151140
_identifiers = ("name",)

examples/slurpit_to_infrahub/slurpitsync/sync_adapter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
from .sync_models import (
44
InfraDevice,
55
InfraHardwareInfo,
6-
InfraInterface,
76
InfraIPAddress,
7+
InfraInterface,
88
InfraPlatform,
99
InfraPrefix,
10-
InfraVersion,
1110
InfraVLAN,
1211
InfraVRF,
12+
InfraVersion,
1313
LocationGeneric,
1414
OrganizationGeneric,
1515
TemplateDeviceType,

examples/slurpit_to_infrahub/slurpitsync/sync_models.py

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
from typing import Any, Optional
1+
from typing import Any, List, Optional
22

33
from infrahub_sync.adapters.slurpitsync import SlurpitsyncModel
44

5-
65
# -------------------------------------------------------
76
# AUTO-GENERATED FILE, DO NOT MODIFY
87
# This file has been generated with the command `infrahub-sync generate`
@@ -22,7 +21,6 @@ class InfraDevice(SlurpitsyncModel):
2221
local_id: Optional[str] = None
2322
local_data: Optional[Any] = None
2423

25-
2624
class InfraHardwareInfo(SlurpitsyncModel):
2725
_modelname = "InfraHardwareInfo"
2826
_identifiers = ("device", "serial")
@@ -37,19 +35,17 @@ class InfraHardwareInfo(SlurpitsyncModel):
3735
local_id: Optional[str] = None
3836
local_data: Optional[Any] = None
3937

40-
4138
class InfraIPAddress(SlurpitsyncModel):
4239
_modelname = "InfraIPAddress"
43-
_identifiers = ("address", "prefix")
40+
_identifiers = ("address", "ip_prefix")
4441
_attributes = ("interface",)
4542
address: str
4643
interface: Optional[str] = None
47-
prefix: Optional[str] = None
44+
ip_prefix: Optional[str] = None
4845

4946
local_id: Optional[str] = None
5047
local_data: Optional[Any] = None
5148

52-
5349
class InfraInterface(SlurpitsyncModel):
5450
_modelname = "InfraInterface"
5551
_identifiers = ("device", "name")
@@ -62,7 +58,6 @@ class InfraInterface(SlurpitsyncModel):
6258
local_id: Optional[str] = None
6359
local_data: Optional[Any] = None
6460

65-
6661
class InfraPlatform(SlurpitsyncModel):
6762
_modelname = "InfraPlatform"
6863
_identifiers = ("name",)
@@ -72,7 +67,6 @@ class InfraPlatform(SlurpitsyncModel):
7267
local_id: Optional[str] = None
7368
local_data: Optional[Any] = None
7469

75-
7670
class InfraPrefix(SlurpitsyncModel):
7771
_modelname = "InfraPrefix"
7872
_identifiers = ("vrf", "prefix")
@@ -83,7 +77,6 @@ class InfraPrefix(SlurpitsyncModel):
8377
local_id: Optional[str] = None
8478
local_data: Optional[Any] = None
8579

86-
8780
class InfraVLAN(SlurpitsyncModel):
8881
_modelname = "InfraVLAN"
8982
_identifiers = ("vlan_id", "name")
@@ -94,7 +87,6 @@ class InfraVLAN(SlurpitsyncModel):
9487
local_id: Optional[str] = None
9588
local_data: Optional[Any] = None
9689

97-
9890
class InfraVRF(SlurpitsyncModel):
9991
_modelname = "InfraVRF"
10092
_identifiers = ("name",)
@@ -104,37 +96,35 @@ class InfraVRF(SlurpitsyncModel):
10496
local_id: Optional[str] = None
10597
local_data: Optional[Any] = None
10698

107-
10899
class InfraVersion(SlurpitsyncModel):
109100
_modelname = "InfraVersion"
110101
_identifiers = ("version",)
111-
_attributes = ("file",)
102+
_attributes = ("devices", "file")
112103
version: str
113104
file: Optional[str] = None
105+
devices: Optional[List[str]] = []
114106

115107
local_id: Optional[str] = None
116108
local_data: Optional[Any] = None
117109

118-
119110
class LocationGeneric(SlurpitsyncModel):
120111
_modelname = "LocationGeneric"
121112
_identifiers = ("name",)
122-
_attributes = ("description", "number", "street", "zipcode", "country", "phonenumber", "city", "county", "state")
113+
_attributes = ("description", "number", "street", "city", "county", "state", "zipcode", "country", "phonenumber")
123114
name: str
124115
description: Optional[str] = None
125116
number: Optional[str] = None
126117
street: Optional[str] = None
127-
zipcode: Optional[str] = None
128-
country: Optional[str] = None
129-
phonenumber: Optional[str] = None
130118
city: Optional[str] = None
131119
county: Optional[str] = None
132120
state: Optional[str] = None
121+
zipcode: Optional[str] = None
122+
country: Optional[str] = None
123+
phonenumber: Optional[str] = None
133124

134125
local_id: Optional[str] = None
135126
local_data: Optional[Any] = None
136127

137-
138128
class OrganizationGeneric(SlurpitsyncModel):
139129
_modelname = "OrganizationGeneric"
140130
_identifiers = ("name",)
@@ -145,7 +135,6 @@ class OrganizationGeneric(SlurpitsyncModel):
145135
local_id: Optional[str] = None
146136
local_data: Optional[Any] = None
147137

148-
149138
class TemplateDeviceType(SlurpitsyncModel):
150139
_modelname = "TemplateDeviceType"
151140
_identifiers = ("name",)

infrahub_sync/adapters/infrahub.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def update_node(node: InfrahubNodeSync, attrs: dict) -> InfrahubNodeSync:
5757
for existing_id in existing_only:
5858
attr.remove(existing_id)
5959

60+
attr.fetch()
6061
for new_id in new_only:
6162
attr.add(new_id)
6263

@@ -208,7 +209,8 @@ def infrahub_node_to_diffsync(self, node: InfrahubNodeSync) -> dict:
208209
elif rel_schema.cardinality == "many":
209210
values = []
210211
rel_manager = getattr(node, rel_schema.name)
211-
for peer in rel_manager:
212+
rel_manager.fetch()
213+
for peer in rel_manager.peers:
212214
peer_node = self.client.store.get(key=peer.id, kind=rel_schema.peer)
213215
peer_data = self.infrahub_node_to_diffsync(node=peer_node)
214216
peer_model = getattr(self, rel_schema.peer)

infrahub_sync/adapters/slurpitsync.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,17 @@ def slurpit_obj_to_diffsync(
271271
# raise IndexError(f"Unable to locate the node {field.reference} {node_id}")
272272
node = matching_nodes[0]
273273
data[field.name] = node.get_unique_id()
274+
else:
275+
data[field.name] = []
276+
if node := obj.get(field.mapping):
277+
node_id = self.build_mapping(reference=field.reference, obj=obj)
278+
matching_nodes = [item for item in nodes if str(item) == node_id]
279+
if len(matching_nodes) == 0:
280+
self.skipped.append(node)
281+
continue
282+
# raise IndexError(f"Unable to locate the node {field.reference} {node_id}")
283+
data[field.name].append(matching_nodes[0].get_unique_id())
284+
data[field.name] = sorted(data[field.name])
274285
return data
275286

276287

0 commit comments

Comments
 (0)