diff options
-rw-r--r-- | .github/workflows/cleanup-mirror-pr-branch.yml | 35 | ||||
-rw-r--r-- | .github/workflows/repo-sync.yml | 18 | ||||
-rw-r--r-- | .github/workflows/trigger-pr-mirror-repo-sync.yml | 38 | ||||
-rw-r--r-- | .github/workflows/trigger-pr.yml | 19 | ||||
-rw-r--r-- | data/templates/accel-ppp/chap-secrets.ipoe.j2 | 2 | ||||
-rw-r--r-- | data/templates/frr/static_routes_macro.j2 | 10 | ||||
-rw-r--r-- | interface-definitions/include/static/static-route.xml.i | 2 | ||||
-rw-r--r-- | interface-definitions/service_ipoe-server.xml.in | 12 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_ipoe-server.py | 35 |
9 files changed, 128 insertions, 43 deletions
diff --git a/.github/workflows/cleanup-mirror-pr-branch.yml b/.github/workflows/cleanup-mirror-pr-branch.yml new file mode 100644 index 000000000..c5de9ab73 --- /dev/null +++ b/.github/workflows/cleanup-mirror-pr-branch.yml @@ -0,0 +1,35 @@ +name: Cleanup pr mirror branch + +on: + pull_request: + types: [closed] + branches: + - current + workflow_dispatch: + inputs: + branch: + description: 'Branch to delete' + required: true + +permissions: + contents: write + +jobs: + delete_branch: + if: ${{ (github.event_name == 'workflow_dispatch' || startsWith(github.event.pull_request.head.ref, 'mirror/')) && github.repository_owner != 'vyos' }} + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Delete branch + run: | + branch=${{ github.event_name == 'workflow_dispatch' && github.event.inputs.branch || github.event.pull_request.head.ref }} + if [[ $branch != mirror/* ]]; then + echo "Branch name to clean must start with 'mirror/'" + exit 1 + fi + repo=${{ github.repository }} + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} + git push origin --delete $branch diff --git a/.github/workflows/repo-sync.yml b/.github/workflows/repo-sync.yml deleted file mode 100644 index 752cf947a..000000000 --- a/.github/workflows/repo-sync.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Repo-sync - -on: - pull_request_target: - types: - - closed - branches: - - current - - equuleus - workflow_dispatch: - -jobs: - trigger-sync: - uses: vyos/.github/.github/workflows/trigger-repo-sync.yml@current - secrets: - REMOTE_REPO: ${{ secrets.REMOTE_REPO }} - REMOTE_OWNER: ${{ secrets.REMOTE_OWNER }} - PAT: ${{ secrets.PAT }} diff --git a/.github/workflows/trigger-pr-mirror-repo-sync.yml b/.github/workflows/trigger-pr-mirror-repo-sync.yml new file mode 100644 index 000000000..9653c2dca --- /dev/null +++ b/.github/workflows/trigger-pr-mirror-repo-sync.yml @@ -0,0 +1,38 @@ +name: Trigger Mirror PR and Repo Sync +on: + pull_request_target: + types: + - closed + branches: + - current + +env: + GH_TOKEN: ${{ secrets.PAT }} + +concurrency: + group: trigger-pr-mirror-repo-sync-${{ github.event.pull_request.base.ref }} + cancel-in-progress: false +jobs: + trigger-mirror-pr-repo-sync: + if: ${{ github.repository_owner == 'vyos' }} + runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: write + + steps: + - name: Bullfrog Secure Runner + uses: bullfrogsec/bullfrog@v0 + with: + egress-policy: audit + + - name: Trigger repo sync + shell: bash + run: | + echo "Triggering sync workflow for ${{ secrets.REMOTE_OWNER }}/${{ secrets.REMOTE_REPO }}" + echo "Triggering sync workflow with PAT ${{ secrets.PAT }}" + curl -X POST \ + -H "Accept: application/vnd.github.everest-preview+json" \ + -H "Authorization: Bearer ${{ secrets.PAT }}" \ + https://api.github.com/repos/${{ secrets.REMOTE_OWNER }}/${{ secrets.REMOTE_REPO }}/actions/workflows/mirror-pr-and-sync.yml/dispatches \ + -d '{"ref":"git-actions", "inputs": {"pr_number": "${{ github.event.pull_request.number }}", "sync_branch": "${{ github.event.pull_request.base.ref }}"}}' diff --git a/.github/workflows/trigger-pr.yml b/.github/workflows/trigger-pr.yml deleted file mode 100644 index f88458a81..000000000 --- a/.github/workflows/trigger-pr.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Trigger PR - -on: - pull_request_target: - types: - - closed - branches: - - circinus - -jobs: - trigger-PR: - uses: vyos/.github/.github/workflows/trigger-pr.yml@current - with: - source_branch: 'circinus' - target_branch: 'circinus' - secrets: - REMOTE_REPO: ${{ secrets.REMOTE_REPO }} - REMOTE_OWNER: ${{ secrets.REMOTE_OWNER }} - PAT: ${{ secrets.PAT }} diff --git a/data/templates/accel-ppp/chap-secrets.ipoe.j2 b/data/templates/accel-ppp/chap-secrets.ipoe.j2 index 43083e22e..dd85160c0 100644 --- a/data/templates/accel-ppp/chap-secrets.ipoe.j2 +++ b/data/templates/accel-ppp/chap-secrets.ipoe.j2 @@ -6,7 +6,7 @@ {% if mac_config.vlan is vyos_defined %} {% set iface = iface ~ '.' ~ mac_config.vlan %} {% endif %} -{{ "%-11s" | format(iface) }} * {{ mac | lower }} * {{ mac_config.rate_limit.download ~ '/' ~ mac_config.rate_limit.upload if mac_config.rate_limit.download is vyos_defined and mac_config.rate_limit.upload is vyos_defined }} +{{ "%-11s" | format(iface) }} * {{ mac | lower }} {{ mac_config.static_ip if mac_config.static_ip is vyos_defined else '*' }} {{ mac_config.rate_limit.download ~ '/' ~ mac_config.rate_limit.upload if mac_config.rate_limit.download is vyos_defined and mac_config.rate_limit.upload is vyos_defined }} {% endfor %} {% endif %} {% endfor %} diff --git a/data/templates/frr/static_routes_macro.j2 b/data/templates/frr/static_routes_macro.j2 index cf8046968..db31700c5 100644 --- a/data/templates/frr/static_routes_macro.j2 +++ b/data/templates/frr/static_routes_macro.j2 @@ -6,10 +6,12 @@ {{ ip_ipv6 }} route {{ prefix }} reject {{ prefix_config.reject.distance if prefix_config.reject.distance is vyos_defined }} {{ 'tag ' ~ prefix_config.reject.tag if prefix_config.reject.tag is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }} {% endif %} {% if prefix_config.dhcp_interface is vyos_defined %} -{% set next_hop = prefix_config.dhcp_interface | get_dhcp_router %} -{% if next_hop is vyos_defined %} -{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ prefix_config.dhcp_interface }} {{ 'table ' ~ table if table is vyos_defined }} -{% endif %} +{% for dhcp_interface in prefix_config.dhcp_interface %} +{% set next_hop = dhcp_interface | get_dhcp_router %} +{% if next_hop is vyos_defined %} +{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ dhcp_interface }} {{ 'table ' ~ table if table is vyos_defined }} +{% endif %} +{% endfor %} {% endif %} {% if prefix_config.interface is vyos_defined %} {% for interface, interface_config in prefix_config.interface.items() if interface_config.disable is not defined %} diff --git a/interface-definitions/include/static/static-route.xml.i b/interface-definitions/include/static/static-route.xml.i index 29921a731..51e45c6f7 100644 --- a/interface-definitions/include/static/static-route.xml.i +++ b/interface-definitions/include/static/static-route.xml.i @@ -13,7 +13,7 @@ <children> #include <include/static/static-route-blackhole.xml.i> #include <include/static/static-route-reject.xml.i> - #include <include/dhcp-interface.xml.i> + #include <include/dhcp-interface-multi.xml.i> #include <include/generic-description.xml.i> <tagNode name="interface"> <properties> diff --git a/interface-definitions/service_ipoe-server.xml.in b/interface-definitions/service_ipoe-server.xml.in index 39cfb7889..6cc4471af 100644 --- a/interface-definitions/service_ipoe-server.xml.in +++ b/interface-definitions/service_ipoe-server.xml.in @@ -70,6 +70,18 @@ <constraintErrorMessage>VLAN IDs need to be in range 1-4094</constraintErrorMessage> </properties> </leafNode> + <leafNode name="static-ip"> + <properties> + <help>Static client IP address</help> + <valueHelp> + <format>ipv4</format> + <description>IPv4 address</description> + </valueHelp> + <constraint> + <validator name="ipv4-address"/> + </constraint> + </properties> + </leafNode> </children> </tagNode> </children> diff --git a/smoketest/scripts/cli/test_service_ipoe-server.py b/smoketest/scripts/cli/test_service_ipoe-server.py index be03179bf..ab0898d17 100755 --- a/smoketest/scripts/cli/test_service_ipoe-server.py +++ b/smoketest/scripts/cli/test_service_ipoe-server.py @@ -260,6 +260,41 @@ delegate={delegate_2_prefix},{delegate_mask},name={pool_name}""" tmp = ','.join(vlans) self.assertIn(f'{interface},{tmp}', conf['ipoe']['vlan-mon']) + def test_ipoe_server_static_client_ip(self): + mac_address = '08:00:27:2f:d8:06' + ip_address = '192.0.2.100' + + # Test configuration of local authentication for PPPoE server + self.basic_config() + # Rewrite authentication from basic_config + self.set( + [ + 'authentication', + 'interface', + interface, + 'mac', + mac_address, + 'static-ip', + ip_address, + ] + ) + self.set(['authentication', 'mode', 'local']) + # commit changes + self.cli_commit() + + # Validate configuration values + conf = ConfigParser(allow_no_value=True, delimiters='=', strict=False) + conf.read(self._config_file) + + # basic verification + self.verify(conf) + + # check local users + tmp = cmd(f'sudo cat {self._chap_secrets}') + regex = f'{interface}\s+\*\s+{mac_address}\s+{ip_address}' + tmp = re.findall(regex, tmp) + self.assertTrue(tmp) + @unittest.skip("PPP is not a part of IPoE") def test_accel_ppp_options(self): pass |