|
| 1 | + |
| 2 | +# Global and Model Flags |
| 3 | + |
| 4 | +These flags offer a powerful way to instruct the core engine how to handle some specific situation without changing the data. One way to think of the flags is to represent them as configuration for the core engine. Currently 2 sets of flags are supported: |
| 5 | +- **global flags**: applicable to all data. |
| 6 | +- **model flags**: applicable to a specific model or to individual instances of a model. |
| 7 | + |
| 8 | +> *The flags are stored in binary format which allows storing multiple flags in a single variable. See the section below [Working with flags](#working-with-flags) to learn how to manage them.* |
| 9 | +
|
| 10 | +The list of supported flags is expected to grow over time as more use cases are identified. If you think some additional flags should be supported, please reach out via Github to start a discussion. |
| 11 | + |
| 12 | +## Global flags |
| 13 | + |
| 14 | +Global flags can be defined at runtime when calling one of these functions : `diff_to` ,`diff_from`, `sync_to` or `sync_from` |
| 15 | + |
| 16 | +```python |
| 17 | +from diffsync.enum import DiffSyncFlags |
| 18 | +flags = DiffSyncFlags.SKIP_UNMATCHED_DST |
| 19 | +diff = nautobot.diff_from(local, flags=flags) |
| 20 | +``` |
| 21 | + |
| 22 | +### Supported Global Flags |
| 23 | + |
| 24 | +| Name | Description | Binary Value | |
| 25 | +|---|---|---| |
| 26 | +| CONTINUE_ON_FAILURE | Continue synchronizing even if failures are encountered when syncing individual models. | 0b1 | |
| 27 | +| SKIP_UNMATCHED_SRC | Ignore objects that only exist in the source/"from" DiffSync when determining diffs and syncing. If this flag is set, no new objects will be created in the target/"to" DiffSync. | 0b10 | |
| 28 | +| SKIP_UNMATCHED_DST | Ignore objects that only exist in the target/"to" DiffSync when determining diffs and syncing. If this flag is set, no objects will be deleted from the target/"to" DiffSync. | 0b100 | |
| 29 | +| SKIP_UNMATCHED_BOTH | Convenience value combining both SKIP_UNMATCHED_SRC and SKIP_UNMATCHED_DST into a single flag | 0b110 | |
| 30 | +| LOG_UNCHANGED_RECORDS | If this flag is set, a log message will be generated during synchronization for each model, even unchanged ones. | 0b1000 | |
| 31 | + |
| 32 | +## Model flags |
| 33 | + |
| 34 | +Model flags are stored in the attribute `model_flags` of each model and are usually set when the data is being loaded into the adapter. |
| 35 | + |
| 36 | +```python |
| 37 | +from diffsync import DiffSync |
| 38 | +from diffsync.enum import DiffSyncModelFlags |
| 39 | +from model import MyDeviceModel |
| 40 | + |
| 41 | +class MyAdapter(DiffSync): |
| 42 | + |
| 43 | + device = MyDeviceModel |
| 44 | + |
| 45 | + def load(self, data): |
| 46 | + """Load all devices into the adapter and add the flag IGNORE to all firewall devices.""" |
| 47 | + for device in data.get("devices"): |
| 48 | + obj = self.device(name=device["name"]) |
| 49 | + if "firewall" in device["name"]: |
| 50 | + obj.model_flags = DiffSyncModelFlags.IGNORE |
| 51 | + self.add(obj) |
| 52 | +``` |
| 53 | + |
| 54 | +### Supported Model Flags |
| 55 | + |
| 56 | +| Name | Description | Binary Value | |
| 57 | +|---|---|---| |
| 58 | +| IGNORE | Do not render diffs containing this model; do not make any changes to this model when synchronizing. Can be used to indicate a model instance that exists but should not be changed by DiffSync. | 0b1 | |
| 59 | +| SKIP_CHILDREN_ON_DELETE | When deleting this model, do not recursively delete its children. Can be used for the case where deletion of a model results in the automatic deletion of all its children. | 0b10 | |
| 60 | + |
| 61 | +## Working with flags |
| 62 | + |
| 63 | +Flags are stored in binary format. In binary format, each bit of a variable represents 1 flag which allow us to have up to many flags stored in a single variable. Using binary flags provides more flexibility to add support for more flags in the future without redefining the current interfaces and the current DiffSync API. |
| 64 | + |
| 65 | +### Enable a flag (Bitwise OR) |
| 66 | + |
| 67 | +Enabling a flag is possible with the bitwise OR operator `|=`. It's important to use the bitwise operator OR when enabling a flags to ensure that the value of other flags remains unchanged. |
| 68 | + |
| 69 | +```python |
| 70 | +>>> from diffsync.enum import DiffSyncFlags |
| 71 | +>>> flags = DiffSyncFlags.CONTINUE_ON_FAILURE |
| 72 | +>>> flags |
| 73 | +<DiffSyncFlags.CONTINUE_ON_FAILURE: 1> |
| 74 | +>>> bin(flags.value) |
| 75 | +'0b1' |
| 76 | +>>> flags |= DiffSyncFlags.SKIP_UNMATCHED_DST |
| 77 | +>>> flags |
| 78 | +<DiffSyncFlags.SKIP_UNMATCHED_DST|CONTINUE_ON_FAILURE: 5> |
| 79 | +>>> bin(flags.value) |
| 80 | +'0b101' |
| 81 | +``` |
| 82 | + |
| 83 | +### Checking the value of a specific flag (bitwise AND) |
| 84 | + |
| 85 | +Validating if a flag is enabled is possible with the bitwise operator AND: `&`. The AND operator will return 0 if the flag is not set and the binary value of the flag if it's enabled. To convert the result of the test into a proper conditional it's possible to wrap the bitwise AND operator into a `bool` function. |
| 86 | + |
| 87 | +```python |
| 88 | +>>> from diffsync.enum import DiffSyncFlags |
| 89 | +>>> flags = DiffSyncFlags.NONE |
| 90 | +>>> bool(flags & DiffSyncFlags.CONTINUE_ON_FAILURE) |
| 91 | +False |
| 92 | +>>> flags |= DiffSyncFlags.CONTINUE_ON_FAILURE |
| 93 | +>>> bool(flags & DiffSyncFlags.CONTINUE_ON_FAILURE) |
| 94 | +True |
| 95 | +``` |
| 96 | + |
| 97 | +### Disable a flag (bitwise NOT) |
| 98 | + |
| 99 | +After a flag has been enabled, it's possible to disable it with a bitwise AND NOT operator : `&= ~` |
| 100 | + |
| 101 | +```python |
| 102 | +>>> from diffsync.enum import DiffSyncFlags |
| 103 | +>>> flags = DiffSyncFlags.NONE |
| 104 | +# Setting the flags SKIP_UNMATCHED_DST and CONTINUE_ON_FAILURE |
| 105 | +>>> flags |= DiffSyncFlags.SKIP_UNMATCHED_DST | DiffSyncFlags.CONTINUE_ON_FAILURE |
| 106 | +>>> flags |
| 107 | +<DiffSyncFlags.SKIP_UNMATCHED_DST|CONTINUE_ON_FAILURE: 5> |
| 108 | +>>> bool(flags & DiffSyncFlags.SKIP_UNMATCHED_DST) |
| 109 | +True |
| 110 | +# Unsetting the flag SKIP_UNMATCHED_DST; CONTINUE_ON_FAILURE remains set |
| 111 | +>>> flags &= ~DiffSyncFlags.SKIP_UNMATCHED_DST |
| 112 | +>>> flags |
| 113 | +<DiffSyncFlags.CONTINUE_ON_FAILURE: 1> |
| 114 | +>>> bool(flags & DiffSyncFlags.SKIP_UNMATCHED_DST) |
| 115 | +False |
| 116 | +``` |
0 commit comments