Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve mapping #123

Merged
merged 9 commits into from
Feb 1, 2024
Merged

Improve mapping #123

merged 9 commits into from
Feb 1, 2024

Conversation

snaselj
Copy link
Contributor

@snaselj snaselj commented Jan 23, 2024

Closes: NaN

What's Changed

  • Added extras.journalentry => extras.note mapping.
  • Added ipam.FHRPGroup => dcim.interfaceRedundancyGroup mapping.
  • Added disable_related_reference to configure_model to allow disabling references, e.g., for ObjectChange.
  • Added dict to empty values to cover the default value of the _custom_field_type field.
  • Added AUTO_ADD_FIELDS = ("content_types", "status"), based on their existence in Nautobot.
  • Added content type UIDs with source and target wrappers to the fields summary.
  • Added importer name to the fields summary.
  • Added check and fail if referenced record doesn't exist in source data, cache, or Nautobot.
  • Added fields.relation field definition.
  • Added --save-mappings-file to the management command to save mappings for later comparison.
  • Allowed PascalCase content types in configure_model and get_or_create_wrapper.
  • Fixed extras.tag.content_types assignment.
  • Fixed failing save() logging when a model instance is not str()able.
  • Fixed error when missing _custom_field_data field in the Nautobot model.
  • Fixed locations related content_types assignment.
  • Fixed the use of callables in default values.
  • Refactored definitions and importers to be better reusable and explanatory.
  • Refactored handle_sibling to assign the same importer.
  • Refactored internal type sets to NautobotField properties: is_reference, is_integer, is_auto_increment, is_content_type, can_import.
  • Renamed NautobotFieldWrapper => NautobotField.
  • Replaced InternalFieldType.GENERIC_FOREIGN_KEY with autodetected relation_and_type_importer.
  • Replaced InternalFieldType.DO_NOT_IMPORT_LAST_UPDATED with a disabled field import.
  • Replaced set_references_forwarding with the callable forward_references.
  • Merged objectchange and min test cases into custom test case.
  • Updated the process for creating test suites based on _INPUTS, _EXPECTED_SUMS, and fixture directories.

- Added `extras.journalentry` => `extras.note` mapping.
- Added `ipam.FHRPGroup` => `dcim.interfaceRedundancyGroup`.
- Added `disable_related_reference` to `configure_model` to allow disabling referencing e.g. for ObjectChange.
- Added `dict` to empty values to cover default value of `_custom_field_type` field.
- Added `AUTO_ADD_FIELDS = ("content_types", "status")`, based on existence in Nautobot.
- Added content type ids with source and target wrappers to fields summary.
- Added importer name to fields summary.
- Added check and fail, if referenced record doesn't exist in source data, cache or Nautobot.
- Added `fields.relation` field definition.
- Added `--save-mappings-file` to management command to save mappings for later comparision.
- Allowed PascalCase content types in `configure_model` and `get_or_create_wrapper`
- Fixed `extras.tag.content_types` assignment.
- Fixed failing `save()` logging when model instance is not `str()`able.
- Fixed error when missing `_custom_field_data` field in Nautobot model.
- Fixed locations `content_types` assignment.
- Fixed using callables in default values.
- Refactored definitions and importers to be better reusable and exaplanatory.
- Refactored `handle_sibling` to assign the same importer.
- Refactored internal type sets to NautobotField properties `is_reference`, `is_integer`, `is_auto_increment`, `is_content_type`, `can_import`.
- Renamed `NautobotFieldWrapper` => `NautobotField`.
- Replaced `InternalFieldType.GENERIC_FOREIGN_KEY` with autodetected `relation_and_type_importer`.
- Replaced `InternalFieldType.DO_NOT_IMPORT_LAST_UPDATED` by disabling the field import.
- Replaced `set_references_forwarding` with callable `forward_references`.
- Merged `objectchange` and `min` test cases to `custom`.
- Updated creating test suites based on `_INPUTS`, `_EXPECTED_SUMS` and fixture directories.
@snaselj snaselj marked this pull request as ready for review January 23, 2024 14:33
@snaselj
Copy link
Contributor Author

snaselj commented Jan 24, 2024

@glennmatthews @chadell

Could you please check this PR?

Copy link
Contributor

@glennmatthews glennmatthews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anything you can be doing in future to make the PRs a bit smaller and more self-contained? This one is a mix of 10 new features with a half dozen distinct bug fixes and heavy refactoring on top, and I for one find it quite difficult to follow and review as a result.

fields={
"postchange_data": "object_data",
# TBD: This should be defined on Nautobot side
"time": fields.force(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -9,7 +9,9 @@
"name": "November",
"color": "2f6a31",
"description": "",
"content_types": []
"content_types": [
56
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh. I would have thought that if you're using --natural-foreign to generate the NetBox dump that these would be strings, not integer PKs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These samples are Nautobot data samples to test final Nautobot data against. Generated without --natural-foreign

https://github.com/nautobot/nautobot-app-netbox-importer/blob/u/snaselj-napps-172-mappings/nautobot_netbox_importer/tests/test_import.py#L302

"tenancy.tenantgroup": 1,
"tenancy.tenant": 5,
"users.user": 1,
"users.user": 6,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still feel like object counts are the absolute minimum test introspection that we should be doing on the migrated data. Are you doing any validation of specific object fields post-import for correctness as well? Because we should be.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are testing final Nautobot data against stored samples, as described above. The test is here:

https://github.com/nautobot/nautobot-app-netbox-importer/blob/u/snaselj-napps-172-mappings/nautobot_netbox_importer/tests/test_import.py#L292

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these old tests being removed? Are they not still relevant to test the importer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

min and objectchange tests has been merged to custom test.

custom test is covering cases, that are not covered by public NetBox dumps.

@snaselj
Copy link
Contributor Author

snaselj commented Jan 26, 2024

Is there anything you can be doing in future to make the PRs a bit smaller and more self-contained? This one is a mix of 10 new features with a half dozen distinct bug fixes and heavy refactoring on top, and I for one find it quite difficult to follow and review as a result.

You are right @glennmatthews , this is not nice to review, sorry for it. Will do better next time.

"termination_b": "termination_b",
},
)
adapter.configure_model("dcim.cable")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the fields are not needed anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

)
adapter.configure_model(
"dcim.interface",
fields={
"status": "status",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why status is not needed anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -38,3 +35,7 @@ def setup(adapter: SourceAdapter) -> None:
"role": fields.role(adapter, "ipam.role"),
},
)
adapter.configure_model(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this mapping "clean"? no need to do some inner attribute mapping?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fields comments, group_id, auth_type and auth_key are not imported. Not sure, how to import these fields, doesn't seem to have their Nautobot counterparts.

Comment on lines +41 to +42
field.handle_sibling("site", field.nautobot.name)
field.handle_sibling("region", field.nautobot.name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are these changes needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to call handle_sibling after set_importer to assign the same importer on sibling fields. This improves summary, where it's possible to see importer name on sibling fields. Doesn't affect the actual import logic.



def setup(adapter: SourceAdapter) -> None:
"""Setup locations for NetBox importer."""

def forward_references(wrapper: SourceModelWrapper, references: SourceReferences) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a description of what is doing could help to understand it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a description.


region_type_uid = location_type_wrapper.cache_record(
{
"id": "Region",
"name": "Region",
"nestable": True,
"content_types": None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are no needed any more?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -24,7 +24,6 @@ def setup(adapter: SourceAdapter) -> None:
adapter.configure_model(
"virtualization.vminterface",
fields={
"status": "status",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that status is added to all the models with status, by default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, as described above.

@chadell
Copy link
Contributor

chadell commented Jan 26, 2024

Is there anything you can be doing in future to make the PRs a bit smaller and more self-contained? This one is a mix of 10 new features with a half dozen distinct bug fixes and heavy refactoring on top, and I for one find it quite difficult to follow and review as a result.

You are right @glennmatthews , this is not nice to review, sorry for it. Will do better next time.

the problem is that it takes longer to review than 3 PRs with well-defined changes. I hope to use this PR to understand what needs to be changed to support a change in NetBox/Nautobot, and I feel we lost this opportunity. It's not still clear to me

@@ -23,24 +37,12 @@ def role(adapter: SourceAdapter, source_content_type: str) -> SourceFieldDefinit
role_wrapper = adapter.configure_model(
source_content_type,
nautobot_content_type="extras.role",
fields={"color": "color", "content_types": "content_types"},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not necessary content_types?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Described above, content_types fields are auto added.

def get_nautobot_field_and_type(
model: NautobotBaseModelType,
field_name: str,
) -> Tuple[Optional[NautobotField], InternalFieldType]:
) -> Tuple[Optional[DjangoField], InternalFieldType]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we move from NautoboField to DjangoField?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to the refactoring of GenericForeignKey fields. These fields are not needed anymore and it was the only fields that were not standard DjangoField. So it was possible to remove this type and replace it with the DjangoField type only.

https://github.com/nautobot/nautobot-app-netbox-importer/pull/123/files#diff-6b479358489e04d98598db52da0a5cce8c2636d21202d851e16589d38820e84eL42

@snaselj
Copy link
Contributor Author

snaselj commented Jan 26, 2024

All comments are resolved now.

@chadell
Copy link
Contributor

chadell commented Jan 29, 2024

All comments are resolved now.

I'm going to do a local test, and if passes, I would move it forward

@snaselj
Copy link
Contributor Author

snaselj commented Jan 29, 2024

@chadell Added demo execution documentation.

@snaselj snaselj requested a review from chadell January 29, 2024 12:30

```bash
invoke import-netbox \
--demo-version 3.6 \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why "demo"? what if I'm importing "actual" data?
could I know which versions are available?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I get it. The demo-version is for testing, then we should make it more evident as an alternative to the --file option that we would use in a real environment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could alos mention where thi demo data is coming from

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better description added.

```bash
invoke import-netbox \
--demo-version 3.6 \
--save-mappings-file=generated-mappings.json \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the goal of this mappings.json?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Described lated in the document in it's own chapter.

docs/dev/demo.md Outdated

### DiffSync

The next step is to perform a DiffSync. The output will look similar to the following:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

people may not konw what is Diffysync or how it works


The last part of the import process is to display a summary of the import [described in the user documentation](../user/summary.md).

## Generated Mappings
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the data mappings are generated on the fly depending on the NetBox data and Nautobot models, isn't it? so it's something thatcan't be determined a prior by the versions without the real data, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct.

Copy link
Contributor

@chadell chadell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
I have tested as described by the instructions and it looks great.
Looking forward to seeing a PR with ONLY adding support for NetBox 3.7 before getting the last good to go for release!

@snaselj snaselj merged commit 54af566 into develop Feb 1, 2024
8 checks passed
@snaselj snaselj deleted the u/snaselj-napps-172-mappings branch February 1, 2024 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants