-
Notifications
You must be signed in to change notification settings - Fork 30
Add Fortigate FortiOS Driver #160
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
+263
−27
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
97b1973
initial add of fortigate fortios driver
jtdub b43d91c
add updated fortigate driver
jtdub f5d2ffd
update get_hconfig_driver to get rid of pylint error
jtdub cfd3619
update get_hconfig_driver
jtdub 09d4831
resolve duplicatechild error
jtdub 8803f47
ruff
jtdub 3241677
fortigate -> fortinet and specificity
jtdub c2b1330
use swap_negation
jtdub 448983a
revert duplicate child update for further investigation
jtdub 266b986
revert duplicate child update for further investigation
jtdub b408bdc
add duplicate child test for xr
jtdub d366296
ruff
jtdub 8c72a29
working through duplicate child error
jtdub d956e55
linting
jtdub File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| from collections.abc import Iterable | ||
| from typing import Optional | ||
|
|
||
| from hier_config.child import HConfigChild | ||
| from hier_config.models import ( | ||
| MatchRule, | ||
| ParentAllowsDuplicateChildRule, | ||
| PerLineSubRule, | ||
| SectionalExitingRule, | ||
| ) | ||
| from hier_config.platforms.driver_base import HConfigDriverBase, HConfigDriverRules | ||
|
|
||
|
|
||
| class HConfigDriverFortinetFortiOS(HConfigDriverBase): | ||
| """Driver for Fortinet FortiOS.""" | ||
|
|
||
| @staticmethod | ||
| def _instantiate_rules() -> HConfigDriverRules: | ||
| return HConfigDriverRules( | ||
| sectional_exiting=[ | ||
| SectionalExitingRule( | ||
| match_rules=(MatchRule(startswith="config "),), exit_text="end" | ||
| ), | ||
| SectionalExitingRule( | ||
| match_rules=( | ||
| MatchRule(startswith="config "), | ||
| MatchRule(startswith="edit "), | ||
| ), | ||
| exit_text="next", | ||
| ), | ||
| ], | ||
| parent_allows_duplicate_child=[ | ||
| ParentAllowsDuplicateChildRule( | ||
| match_rules=(MatchRule(startswith="config"),) | ||
| ), | ||
| ], | ||
| per_line_sub=[ | ||
| PerLineSubRule(search="^end$", replace=" end"), | ||
| PerLineSubRule(search="^next$", replace=" next"), | ||
| ], | ||
| ) | ||
|
|
||
| def swap_negation(self, child: HConfigChild) -> HConfigChild: | ||
| """Swap negation of a `self.text`.""" | ||
| if child.text.startswith(self.negation_prefix): | ||
| child.text = f"{self.declaration_prefix}{child.text_without_negation}" | ||
| elif child.text.startswith(self.declaration_prefix): | ||
| child.text = f"{self.negation_prefix}{child.text.removeprefix(self.declaration_prefix).split()[0]}" | ||
|
|
||
| return child | ||
|
|
||
| def idempotent_for( | ||
| self, config: HConfigChild, other_children: Iterable[HConfigChild] | ||
| ) -> Optional[HConfigChild]: | ||
| """Override idempotent_for to only consider a config idempotent | ||
| if the same command exists in the other set. | ||
| """ | ||
| for other_child in other_children: | ||
| if ( | ||
| config.text.startswith(self.declaration_prefix) | ||
| and other_child.text.startswith(self.declaration_prefix) | ||
| and config.text.split()[1] == other_child.text.split()[1] | ||
| ): | ||
| return other_child | ||
| return super().idempotent_for(config, other_children) | ||
|
|
||
| @property | ||
| def negation_prefix(self) -> str: | ||
| return "unset " | ||
|
|
||
| @property | ||
| def declaration_prefix(self) -> str: | ||
| return "set " | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| from hier_config import get_hconfig_fast_load | ||
| from hier_config.models import Platform | ||
|
|
||
|
|
||
| def test_duplicate_child() -> None: | ||
| platform = Platform.CISCO_XR | ||
| running_config = get_hconfig_fast_load( | ||
| platform, | ||
| ( | ||
| "route-policy SET_COMMUNITY_AND_PERMIT", | ||
| " if destination in (192.0.2.0/24, 198.51.100.0/24) then", | ||
| " set community (65001:100) additive", | ||
| " pass", | ||
| " else", | ||
| " drop", | ||
| " endif", | ||
| "end-policy", | ||
| "", | ||
| "route-policy SET_LOCAL_PREF_AND_PASS", | ||
| " if destination in (203.0.113.0/24) then", | ||
| " set local-preference 200", | ||
| " pass", | ||
| " else", | ||
| " drop", | ||
| " endif", | ||
| "end-policy", | ||
| ), | ||
| ) | ||
| generated_config = get_hconfig_fast_load( | ||
| platform, | ||
| ( | ||
| "route-policy SET_COMMUNITY_AND_PERMIT", | ||
| " if destination in (192.0.2.0/24, 198.51.100.0/24) then", | ||
| " set community (65001:100) additive", | ||
| " pass", | ||
| " else", | ||
| " drop", | ||
| " endif", | ||
| "end-policy", | ||
| "", | ||
| ), | ||
| ) | ||
| remediation_config = running_config.config_to_get_to(generated_config) | ||
| assert remediation_config.dump_simple(sectional_exiting=True) == ( | ||
| "no route-policy SET_LOCAL_PREF_AND_PASS", | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| from hier_config import get_hconfig_fast_load | ||
| from hier_config.constructors import get_hconfig | ||
| from hier_config.models import Platform | ||
|
|
||
|
|
||
| def test_swap_negation() -> None: | ||
| platform = Platform.FORTINET_FORTIOS | ||
| running_config = get_hconfig_fast_load( | ||
| platform, | ||
| ( | ||
| "config system interface", | ||
| " edit port1", | ||
| " set description 'Port 1'", | ||
| " set status down", | ||
| " next", | ||
| "end", | ||
| "config system dns", | ||
| " set primary 192.0.2.1", | ||
| " set secondary 192.0.2.2", | ||
| "end", | ||
| ), | ||
| ) | ||
| generated_config = get_hconfig_fast_load( | ||
| platform, | ||
| ( | ||
| "config system interface", | ||
| " edit port1", | ||
| " set status down", | ||
| " next", | ||
| "end", | ||
| "config system dns", | ||
| " set primary 192.0.2.1", | ||
| "end", | ||
| ), | ||
| ) | ||
| remediation_config = running_config.config_to_get_to(generated_config) | ||
| assert remediation_config.dump_simple(sectional_exiting=True) == ( | ||
| "config system interface", | ||
| " edit port1", | ||
| " unset description", | ||
| " next", | ||
| " end", | ||
| "config system dns", | ||
| " unset secondary", | ||
| " end", | ||
| ) | ||
|
|
||
|
|
||
| def test_idempotent_for() -> None: | ||
| platform = Platform.FORTINET_FORTIOS | ||
| running_config = get_hconfig_fast_load( | ||
| platform, | ||
| ( | ||
| "config system interface", | ||
| " edit port1", | ||
| " set description 'Old Description'", | ||
| " set status up", | ||
| " next", | ||
| "end", | ||
| "config system dns", | ||
| " set primary 192.0.2.1", | ||
| " set secondary 192.0.2.2", | ||
| "end", | ||
| ), | ||
| ) | ||
| generated_config = get_hconfig_fast_load( | ||
| platform, | ||
| ( | ||
| "config system interface", | ||
| " edit port1", | ||
| " set description 'New Description'", | ||
| " set status up", | ||
| " next", | ||
| "end", | ||
| "config system dns", | ||
| " set primary 192.0.2.1", | ||
| " set secondary 192.0.2.3", | ||
| "end", | ||
| ), | ||
| ) | ||
| remediation_config = running_config.config_to_get_to(generated_config) | ||
| assert remediation_config.dump_simple(sectional_exiting=True) == ( | ||
| "config system interface", | ||
| " edit port1", | ||
| " set description 'New Description'", | ||
| " next", | ||
| " end", | ||
| "config system dns", | ||
| " set secondary 192.0.2.3", | ||
| " end", | ||
| ) | ||
|
|
||
|
|
||
| def test_future() -> None: | ||
| platform = Platform.FORTINET_FORTIOS | ||
| running_config = get_hconfig(platform) | ||
| remediation_config = get_hconfig_fast_load( | ||
| platform, | ||
| ( | ||
| "config system interface", | ||
| " edit port2", | ||
| " set description 'Port 2'", | ||
| " set status up", | ||
| " next", | ||
| "end", | ||
| ), | ||
| ) | ||
| future_config = running_config.future(remediation_config) | ||
| assert not tuple(remediation_config.unified_diff(future_config)) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.