diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bedf6a6bba3c5fb7b5e422e976b696afc4aad956..9826fc8d5a6936bda414dcb4f851f55da24b813f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -53,9 +53,9 @@ build-documentation: image: python:latest before_script: - - pip install mkdocs-material + - cd $CI_PROJECT_DIR/docs script: - - mkdocs build --site-dir public + - build-docs.sh artifacts: paths: @@ -75,7 +75,7 @@ lint-documentation: artifacts: true before_script: - - cd $CI_PROJECT_DIR/vale + - cd $CI_PROJECT_DIR/docs/vale - vale sync script: diff --git a/README.md b/README.md index 75cbf42745d08cf5a24ca94b142b0a53dd74b679..f1584901240fbdfc1f2177a98c218d667dfb21a7 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,5 @@ The GÉANT interpretation of [``orchestrator-core``](https://github.com/workfloworchestrator/orchestrator-core). ## Documentation -You can build the documentation locally using [build-docs.sh](docs/build-docs.sh). +You can build the documentation locally using [build-docs.sh](docs/build-docs.sh). It is available online at +[docs.gap.geant.org](https://docs.gap.geant.org/). diff --git a/docs/includes/glossary.md b/docs/includes/glossary.md index 20557ed522b1a24aca286bfaa1a6cd786b96dfa0..fc93b30caecde6546772b606aefa4819a95def96 100644 --- a/docs/includes/glossary.md +++ b/docs/includes/glossary.md @@ -1,4 +1,5 @@ *[AAA]: Authentication, Authorisation, Accounting +*[BFD]: Bidirectional Forwarding Detection *[BGP]: Border Gateway Protocol *[BSS]: Business Support Systems *[CFS]: Customer Facing Service @@ -15,13 +16,17 @@ *[GP]: Physical Port *[GSO]: GÉANT Service Orchestrator *[GUI]: Graphical User Interface +*[IAS]: GÉANT Internet Access Service *[iBGP]: Internal BGP *[IGP]: Internal Gateway Protocol *[IFS]: Interface Facing Service *[IPAM]: IP Address Management *[IS-IS]: Intermediate System to Intermediate System +*[ISO]: International Standards Organisations *[L3VPN]: Layer 3 VPN +*[LLDP]: Link-Layer Discovery Protocol *[LSO]: Lightweight Service Orchestrator +*[MAC]: Medium Access Control *[MPLS]: Multi-Protocol Label Switching *[MTTR]: Mean Time To Repair *[MTU]: Maximum Transmission Unit @@ -31,6 +36,7 @@ *[PoP]: Point of Presence *[REST]: Representational State Transfer *[RFC]: Request For Comments +*[SBP]: Service Binding Port *[SDP]: Service Delivery Point *[SNMP]: Simple Network Management Protocol *[SOT]: Source Of Truth diff --git a/docs/source/architecture/components/netbox/index.md b/docs/source/architecture/components/netbox/index.md index 2f5160b94778c92c6662f0985720b8208fec2775..121761fd7b4b863abebf68453560d00c86b9835a 100644 --- a/docs/source/architecture/components/netbox/index.md +++ b/docs/source/architecture/components/netbox/index.md @@ -15,7 +15,7 @@ There are some strong assumptions that are made about GAP: The new routers have a static hardware configuration which depends on the tier of the site at which it is installed. The following table summarizes the possible configurations: -| Tier | Chassis | Control plane | Switching fabric | Linecard | +| Tier | Chassis | Control plane | Switching fabric | Line card | |------|---------|---------------|------------------|----------------------------------| | 1 | SR7s | 2x CPM2-s | 4x SFM7-s | 2x XCM2 - 2x XMA2-s (36p QSFPDD) | | 2 | SR7s | 2x CPM2-s | 4x SFM7-s | 2x XCM2 - 2x XMA2-s (36p QSFPDD) | diff --git a/docs/source/index.md b/docs/source/index.md index e91efa9d0fef5900432afb3158bf083f1308c939..8bd239521a1d8975f39e5519e62badda68ebc9cb 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -43,8 +43,8 @@ This site is organized in 4 main sections: that the GAP interacts with. The documentation provided in this portal is final and reviewed. For information -about the ongoing work please refer to the [internal wiki page](https://wiki. -geant.org/display/NNAT/GOAT+-+Geant+Orchestration+and+Automation+Team). +about the ongoing work please refer to the +[internal wiki page](https://wiki.geant.org/display/NNAT/GOAT+-+Geant+Orchestration+and+Automation+Team). !!! Tip diff --git a/docs/test-docs.sh b/docs/test-docs.sh index 2adbe6b0680a8ee99fcb245ae1fec3713f191f4f..55ce69cfa7c84fe5151c157dc3e3df4b66240dd4 100755 --- a/docs/test-docs.sh +++ b/docs/test-docs.sh @@ -1,4 +1,4 @@ #!/bin/bash -vale --config=docs/vale/.vale.ini sync -vale --glob='!*/migrations/*' --config=docs/vale/.vale.ini docs/source gso +vale --config=vale/.vale.ini sync +vale --glob='!*/migrations/*' --config=vale/.vale.ini source ../gso diff --git a/docs/vale/.vale.ini b/docs/vale/.vale.ini index 305a1b4b2e544f6112ea8f697373e47903b6c424..544ed75c86ba74850525b59570ba3f089c65e783 100644 --- a/docs/vale/.vale.ini +++ b/docs/vale/.vale.ini @@ -6,7 +6,7 @@ Vocab = geant-jargon Packages = proselint, Microsoft -[*] +[*.{py,md}] ; Replacing a ... with … shouldn't be holding back the entire CI pipeline proselint.Typography = warning ; Same applies for not using contractions, the custom package actually lints in the opposite direction @@ -16,8 +16,9 @@ custom.Contractions = YES Microsoft.Passive = NO ; We are not a general audience Microsoft.GeneralURL = NO +Microsoft.We = NO -[*.{py,rst}] +[*.py] ; We only lint .rst and .py files BasedOnStyles = Vale, proselint, Microsoft ; Some headers are generated and we have no real influence over them @@ -27,17 +28,10 @@ proselint.Annotations = NO ; Using a "regular" - instead of an en dash is totally fine Microsoft.Negative = NO Microsoft.RangeFormat = NO -Microsoft.We = suggestion +Microsoft.SentenceLength = NO TokenIgnores = (:term:`\S+`), (:param \S+(?: \S+)?:), (:type \S+:), (:return \S+:), (:rtype: \S+), (:class:`\S+`) -[*/glossary.rst] -; Ignore acronyms being undefined in the file that defines all acronyms by definition. -Microsoft.Acronyms = NO -Microsoft.Contractions = NO -custom.Contractions = YES -Microsoft.Passive = NO - [*.md] BasedOnStyles = Vale, proselint, Microsoft diff --git a/docs/vale/styles/config/vocabularies/geant-jargon/accept.txt b/docs/vale/styles/config/vocabularies/geant-jargon/accept.txt index 6509f0d5bdb354bcd9c17eab9cf79fb900653ee1..f6c9a3eb5e5976cbb5c73f33353a95b944600df9 100644 --- a/docs/vale/styles/config/vocabularies/geant-jargon/accept.txt +++ b/docs/vale/styles/config/vocabularies/geant-jargon/accept.txt @@ -1,37 +1,87 @@ -GÉANT Automation Platform -G[ÉE]ANT -[GSO|gso] -(GSO|gso) -N(okia|OKIA) -IMS -Vereniging -[T|t]erminate -TERMINATED? -WFO -Ansible -[Dd]eprovision +AAA +AAI +AMT API +Ansible +[Bb]ackbone +BFD +BGP +BSS +CFS +DCIM +DDI +DHCP DNS -dry_run +DTAP Dark_fiber -[Aa]ddress -[Ii]ptrunk -[Aa]llocate -PHASE 1 -[Mm]odify +EARL +EVE +FIXME FQDN -AAI -[Mm]iddleware -TWAMP -Pydantic -UUID -SNMP -V?LAN -OPA -OIDC +FXP +GA +GAN +GAP +GOAT +GP +GSO +GUI +G[ÉE]ANT +GÉANT Automation Platform HTTPBearer +IAS +IFS +IGP +IMS +IPAM +IS-?IS +ISO Kentik -UTC -EARL +L3VPN +LAG +LLDP +LSO +MAC +MPLS +MTTR +MTU +N(okia|OKIA) +NREN +OIDC +OOB +OPA +(OSS|oss) +PHASE 1 +Po[Pp] +Pydantic +[Rr]eachability +[Rr](EST|est) +RFC +SBP +SDP +SID +SNMP +SOT SURF +TBA +TERMINATED? +TWAMP +UAT +UTC +UUID +V?LAN +VM +Vereniging +WFO +[Aa]ddress +[Aa]llocate +[Dd]eprovision [Ee]nsure +[GSO|gso] +[Ii]ptrunk +[Mm]iddleware +[Mm]odify +[Tt]erminate +dry_run +eBGP +iBGP diff --git a/gso/products/__init__.py b/gso/products/__init__.py index 90cd71c5a5a94cbfff23775c193dcf3affb86a08..c0e3d173e57a96a559a49996d1815404b698b274 100644 --- a/gso/products/__init__.py +++ b/gso/products/__init__.py @@ -1,7 +1,7 @@ """Module that updates the domain model of :term:`GSO`. Should contain all types of subscriptions. .. warning:: - Whenever a new product is added, this should be reflected in the :py:class:`gso.products.ProductType` enumerator. + Whenever a new product is added, this should be reflected in the `ProductType` enumerator. This does not hold for adding a new type of already existing product. """ diff --git a/gso/services/netbox_client.py b/gso/services/netbox_client.py index 3b71f49dd54fa643c5a7c465c9cd3deb68d61c35..a64ec75860572d8b2da8323e5a6551caf3a1a326 100644 --- a/gso/services/netbox_client.py +++ b/gso/services/netbox_client.py @@ -109,7 +109,7 @@ class NetboxClient: ) -> Interfaces: """Create new interface on a device, where device is defined by name. - The type parameter can be 1000base-t, 10gbase-t, lag, etc. + The type parameter can be 1000base-t, 10gbase-t, LAG, etc. For more details on type definition have a look in choices.py in the netbox API implementation in module DCIM. Returns the new interface object as dict. """ diff --git a/gso/workflows/edge_port/create_edge_port.py b/gso/workflows/edge_port/create_edge_port.py index 3782800b426fc0b4f08fd70a6dfa2a72947c11fb..18629e98f26d188b257ad5217f42704c14da991c 100644 --- a/gso/workflows/edge_port/create_edge_port.py +++ b/gso/workflows/edge_port/create_edge_port.py @@ -168,7 +168,7 @@ def initialize_subscription( @step("Reserve interfaces in NetBox") def reserve_interfaces_in_netbox(subscription: EdgePortProvisioning) -> State: - """Create the :term:`LAG` interfaces in NetBox and attach the lag interfaces to the physical interfaces.""" + """Create the :term:`LAG` interfaces in NetBox and attach the LAG interfaces to the physical interfaces.""" nbclient = NetboxClient() edge_port = subscription.edge_port # Create :term:`LAG` interfaces diff --git a/gso/workflows/edge_port/modify_edge_port.py b/gso/workflows/edge_port/modify_edge_port.py index b2923004e4b74d730006c1f8d0998a9c3da29287..67ff810b7d54b1fb8cb33a48373f47953f0f7a99 100644 --- a/gso/workflows/edge_port/modify_edge_port.py +++ b/gso/workflows/edge_port/modify_edge_port.py @@ -244,7 +244,7 @@ def allocate_interfaces_in_netbox(subscription: EdgePort, previous_ae_members: l iface_name=member.interface_name, ) - # detach the old interfaces from lag + # detach the old interfaces from LAG nbclient.detach_interfaces_from_lag( device_name=subscription.edge_port.node.router_fqdn, lag_name=subscription.edge_port.edge_port_name ) diff --git a/gso/workflows/iptrunk/create_iptrunk.py b/gso/workflows/iptrunk/create_iptrunk.py index 39a0faf49b06c42e60a4f530118d228c1f95c2ed..2d7be47def406f43d113fa0673abc18b50894fb9 100644 --- a/gso/workflows/iptrunk/create_iptrunk.py +++ b/gso/workflows/iptrunk/create_iptrunk.py @@ -514,7 +514,7 @@ def register_dns_records(subscription: IptrunkInactive) -> State: @step("NextBox integration") def reserve_interfaces_in_netbox(subscription: IptrunkInactive) -> State: - """Create the :term:`LAG` interfaces in NetBox and attach the lag interfaces to the physical interfaces.""" + """Create the :term:`LAG` interfaces in NetBox and attach the LAG interfaces to the physical interfaces.""" nbclient = NetboxClient() for trunk_side in subscription.iptrunk.iptrunk_sides: if get_router_vendor(trunk_side.iptrunk_side_node.owner_subscription_id) == Vendor.NOKIA: diff --git a/gso/workflows/iptrunk/modify_trunk_interface.py b/gso/workflows/iptrunk/modify_trunk_interface.py index dec0d14927ef2f01fd3e84c06c83a7c3264407e6..d2056db74cb75ef1a2eaa6fe63b9677f645c9294 100644 --- a/gso/workflows/iptrunk/modify_trunk_interface.py +++ b/gso/workflows/iptrunk/modify_trunk_interface.py @@ -438,7 +438,7 @@ def _netbox_allocate_interfaces(side_block: IptrunkSideBlock, previous_ae_member iface_name=interface.interface_name, ) - # detach the old interfaces from lag + # detach the old interfaces from LAG if side_block.iptrunk_side_ae_iface: nbclient.detach_interfaces_from_lag( device_name=side_block.iptrunk_side_node.router_fqdn, diff --git a/gso/workflows/l3_core_service/modify_l3_core_service.py b/gso/workflows/l3_core_service/modify_l3_core_service.py index 3073b6deae63a456b428119157fd0cbd3b7ea6f8..e5f1f127bf25f8c623cbd37782a8d80b4ffee78c 100644 --- a/gso/workflows/l3_core_service/modify_l3_core_service.py +++ b/gso/workflows/l3_core_service/modify_l3_core_service.py @@ -326,7 +326,7 @@ def create_new_sbp_blocks(subscription: L3CoreService, added_service_binding_por target=Target.MODIFY, ) def modify_l3_core_service() -> StepList: - """Modify a NRN L3 Core Service subscription.""" + """Modify an L3 Core Service subscription.""" access_ports_are_removed = conditional(lambda state: bool(len(state["removed_access_ports"]) > 0)) access_ports_are_modified = conditional(lambda state: bool(len(state["modified_sbp_list"]) > 0)) access_ports_are_added = conditional(lambda state: bool(len(state["added_service_binding_ports"]) > 0)) diff --git a/test/services/test_netbox_client.py b/test/services/test_netbox_client.py index d03bf828cc5af5add0b53171ef403d8f07ab1609..55b82af17c7e9b67b140ed66d51e88905ec14b3a 100644 --- a/test/services/test_netbox_client.py +++ b/test/services/test_netbox_client.py @@ -268,7 +268,7 @@ def test_get_interfaces_by_device(mock_api, device, interface, data_config_filen @patch("gso.services.netbox_client.pynetbox.api") def test_attach_interface_to_lag(mock_api, device, interface, lag, data_config_filename: PathLike): - """Test if a interface is attached correctly to a lag interface.""" + """Test if a interface is attached correctly to a LAG interface.""" # Define site effect function def get_side_effect(**kwargs): @@ -288,7 +288,7 @@ def test_attach_interface_to_lag(mock_api, device, interface, lag, data_config_f mock_save.save.return_value = interface interface.save = mock_save - # Check if interface attached to lag + # Check if interface attached to LAG lag_interface = NetboxClient().attach_interface_to_lag(device.name, lag.name, interface.name, description) assert lag_interface is not None diff --git a/test/workflows/edge_port/test_terminate_edge_port.py b/test/workflows/edge_port/test_terminate_edge_port.py index b5a16866548235c3f878190d757f9ebe9507b35e..9af27ab4195c0d7bccb544eab432b4e5a216dcc7 100644 --- a/test/workflows/edge_port/test_terminate_edge_port.py +++ b/test/workflows/edge_port/test_terminate_edge_port.py @@ -45,8 +45,8 @@ def test_successful_edge_port_termination( assert_complete(result) # Check NetboxClient calls - assert mocked_delete_interface.call_count == 1 # Delete the lag - assert mocked_free_interface.call_count == 2 # Free interfaces attached to the lag which is 2 + assert mocked_delete_interface.call_count == 1 # Delete the LAG + assert mocked_free_interface.call_count == 2 # Free interfaces attached to the LAG which is 2 state = extract_state(result) subscription_id = state["subscription_id"] diff --git a/test/workflows/iptrunk/test_migrate_iptrunk.py b/test/workflows/iptrunk/test_migrate_iptrunk.py index 74c80af387544fc686ea69451d14ff22d008da01..078942a1e9a9c347f8af5eb3cd773dfc6932436d 100644 --- a/test/workflows/iptrunk/test_migrate_iptrunk.py +++ b/test/workflows/iptrunk/test_migrate_iptrunk.py @@ -200,7 +200,7 @@ def test_migrate_iptrunk_success( # noqa: PLR0915 num_nokia_reserved = 2 * (vendor_new == Vendor.NOKIA) num_nokia_attached = 2 * (vendor_new == Vendor.NOKIA) - # Only interfaces lag delete for nokia node is tested + # Only interfaces LAG delete for nokia node is tested num_nokia_lag_del = 1 * (vendor_old == Vendor.NOKIA) # Only free interfaces when node was nokia diff --git a/test/workflows/iptrunk/test_modify_trunk_interface.py b/test/workflows/iptrunk/test_modify_trunk_interface.py index 77470e79d7865cd68aa3254ae14b67a497171004..2dcb23e2b00a9b063144e827f434129f5d9411e7 100644 --- a/test/workflows/iptrunk/test_modify_trunk_interface.py +++ b/test/workflows/iptrunk/test_modify_trunk_interface.py @@ -151,7 +151,7 @@ def test_iptrunk_modify_trunk_interface_success( # Define free interfaces for only nokia sides num_free_ifaces = 2 * (vendor_side_a == Vendor.NOKIA) + 2 * (vendor_side_b == Vendor.NOKIA) - # lag interface for nokia sides + # LAG interface for nokia sides num_lag_ifaces = int(vendor_side_a == Vendor.NOKIA) + int(vendor_side_b == Vendor.NOKIA) assert mocked_reserve_interface.call_count == num_ifaces # Only nokia interfaces per side num is randomly generated