diff --git a/CHANGELOG.md b/CHANGELOG.md index a90be71de..ffbe6a44a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -90,6 +90,7 @@ All notable changes to this project will be documented in this file. - Add histogram metric for GetConfig request duration - Add gRPC middleware for prometheus metrics - Add device status label to controller_grpc_getconfig_requests_total metric + - Add logic to shutdown user BGP, IBGP sessions, MSDP neighbors, and ISIS when device.status is drained - Device agents - Increase default controller request timeout in config agent - Initial state collect in telemetry agent diff --git a/controlplane/controller/internal/controller/fixtures/base.config.drained.txt b/controlplane/controller/internal/controller/fixtures/base.config.drained.txt new file mode 100644 index 000000000..068eca965 --- /dev/null +++ b/controlplane/controller/internal/controller/fixtures/base.config.drained.txt @@ -0,0 +1,168 @@ +! +hardware counter feature gre tunnel interface out +hardware counter feature gre tunnel interface in +! +hardware access-list update default-result permit +! +logging buffered 128000 +no logging console +logging facility local7 +! +ip name-server vrf default 1.1.1.1 +ip name-server vrf default 9.9.9.9 +clock timezone UTC +! +ip multicast-routing +! +router pim sparse-mode + ipv4 + rp address 10.0.0.0 239.0.0.0/24 override +! +vrf instance vrf1 +ip routing +ip routing vrf vrf1 +! +ntp server 0.pool.ntp.org +ntp server 1.pool.ntp.org +ntp server 2.pool.ntp.org +! +hardware access-list update default-result permit +! +no ip access-list MAIN-CONTROL-PLANE-ACL +ip access-list MAIN-CONTROL-PLANE-ACL + counters per-entry + 10 permit icmp any any + 20 permit ip any any tracked + 30 permit udp any any eq bfd ttl eq 255 + 40 permit udp any any eq bfd-echo ttl eq 254 + 50 permit udp any any eq multihop-bfd micro-bfd sbfd + 60 permit udp any eq sbfd any eq sbfd-initiator + 70 permit ospf any any + 80 permit tcp any any eq ssh telnet www snmp bgp https msdp ldp netconf-ssh gnmi + 90 permit udp any any eq bootps bootpc snmp rip ntp ldp ptp-event ptp-general + 100 permit tcp any any eq mlag ttl eq 255 + 110 permit udp any any eq mlag ttl eq 255 + 120 permit vrrp any any + 130 permit ahp any any + 140 permit pim any any + 150 permit igmp any any + 160 permit tcp any any range 5900 5910 + 170 permit tcp any any range 50000 50100 + 180 permit udp any any range 51000 51100 + 190 permit tcp any any eq 3333 + 200 permit tcp any any eq nat ttl eq 255 + 210 permit tcp any eq bgp any + 220 permit rsvp any any + 230 permit tcp any any eq 9340 + 240 permit tcp any any eq 9559 + 250 permit udp any any eq 8503 + 260 permit udp any any eq lsp-ping + 270 permit udp any eq lsp-ping any + 280 remark Permit TWAMP (UDP 862) + 290 permit udp any any eq 862 +! +system control-plane + ip access-group MAIN-CONTROL-PLANE-ACL in +! +interface Loopback255 + ip address 14.14.14.14/32 + node-segment ipv4 index 15 + isis enable 1 +! +interface Ethernet1/1 + mtu 2048 + no switchport + ip address 172.16.0.2/31 + pim ipv4 sparse-mode + isis enable 1 + isis circuit-type level-2 + isis hello-interval 1 + isis metric 40000 + no isis passive + isis hello padding + isis network point-to-point +! +interface Ethernet1/2 + mtu 2048 + no switchport + ip address 172.16.0.4/31 + pim ipv4 sparse-mode +! +interface Loopback1000 + description RP Address + ip address 10.0.0.0/32 +! +mpls ip +! +mpls icmp ttl-exceeded tunneling +mpls icmp ip source-interface Loopback255 +! +router bgp 65342 + router-id 14.14.14.14 + timers bgp 1 3 + distance bgp 20 200 200 + no neighbor 12.12.12.12 + neighbor 12.12.12.12 remote-as 65342 + neighbor 12.12.12.12 next-hop-self + neighbor 12.12.12.12 update-source Loopback256 + neighbor 12.12.12.12 description remote-dzd-ipv4 + neighbor 12.12.12.12 timers 3 9 + neighbor 12.12.12.12 send-community + no neighbor 15.15.15.15 + neighbor 15.15.15.15 remote-as 65342 + neighbor 15.15.15.15 next-hop-self + neighbor 15.15.15.15 update-source Loopback255 + neighbor 15.15.15.15 description remote-dzd-vpnv4 + neighbor 15.15.15.15 timers 3 9 + neighbor 15.15.15.15 send-community + address-family ipv4 + neighbor 12.12.12.12 activate + no neighbor 15.15.15.15 activate + ! + address-family vpn-ipv4 + neighbor 15.15.15.15 activate + ! + vrf vrf1 + rd 65342:1 + route-target import vpn-ipv4 65342:1 + route-target export vpn-ipv4 65342:1 + router-id 7.7.7.7 +! +router isis 1 + net 49.0000.0e0e.0e0e.0000.00 + router-id ipv4 14.14.14.14 + log-adjacency-changes + ! + address-family ipv4 unicast + ! + segment-routing mpls + no shutdown + set-overload-bit +! +ip community-list COMM-ALL_USERS permit 21682:1200 +ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 +ip community-list COMM-TST_USERS permit 21682:10050 +! +no ip access-list SEC-USER-PUB-MCAST-IN +ip access-list SEC-USER-PUB-MCAST-IN + counters per-entry + permit icmp any any + permit tcp any any eq bgp + permit ip any 224.0.0.13/32 + permit ip any 239.0.0.0/24 + deny ip any any +! +no ip access-list SEC-USER-SUB-MCAST-IN +ip access-list SEC-USER-SUB-MCAST-IN + counters per-entry + permit icmp any any + permit tcp any any eq bgp + permit ip any 224.0.0.13/32 + deny ip any any +! +no router msdp +router msdp + peer 12.12.12.12 + mesh-group DZ-1 + local-interface Loopback256 + description remote-dzd diff --git a/controlplane/controller/internal/controller/fixtures/base.config.txt b/controlplane/controller/internal/controller/fixtures/base.config.txt index 9543032e5..0319bb29f 100644 --- a/controlplane/controller/internal/controller/fixtures/base.config.txt +++ b/controlplane/controller/internal/controller/fixtures/base.config.txt @@ -137,6 +137,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/base.config.with.mgmt.vrf.txt b/controlplane/controller/internal/controller/fixtures/base.config.with.mgmt.vrf.txt index 7ea22312f..0302495de 100644 --- a/controlplane/controller/internal/controller/fixtures/base.config.with.mgmt.vrf.txt +++ b/controlplane/controller/internal/controller/fixtures/base.config.with.mgmt.vrf.txt @@ -113,6 +113,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/e2e.last.user.tmpl b/controlplane/controller/internal/controller/fixtures/e2e.last.user.tmpl index 421f89c2d..90fda914e 100644 --- a/controlplane/controller/internal/controller/fixtures/e2e.last.user.tmpl +++ b/controlplane/controller/internal/controller/fixtures/e2e.last.user.tmpl @@ -114,6 +114,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/e2e.peer.removal.tmpl b/controlplane/controller/internal/controller/fixtures/e2e.peer.removal.tmpl index 4cfcfe6e4..77bc6e1a4 100644 --- a/controlplane/controller/internal/controller/fixtures/e2e.peer.removal.tmpl +++ b/controlplane/controller/internal/controller/fixtures/e2e.peer.removal.tmpl @@ -163,6 +163,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/e2e.tmpl b/controlplane/controller/internal/controller/fixtures/e2e.tmpl index a24b401e4..7488500fa 100644 --- a/controlplane/controller/internal/controller/fixtures/e2e.tmpl +++ b/controlplane/controller/internal/controller/fixtures/e2e.tmpl @@ -200,6 +200,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/interfaces.txt b/controlplane/controller/internal/controller/fixtures/interfaces.txt index 6b3afa00c..1c07480ca 100644 --- a/controlplane/controller/internal/controller/fixtures/interfaces.txt +++ b/controlplane/controller/internal/controller/fixtures/interfaces.txt @@ -185,6 +185,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/mixed.tunnel.tmpl b/controlplane/controller/internal/controller/fixtures/mixed.tunnel.tmpl index c9a605500..f98c7a3d8 100644 --- a/controlplane/controller/internal/controller/fixtures/mixed.tunnel.tmpl +++ b/controlplane/controller/internal/controller/fixtures/mixed.tunnel.tmpl @@ -199,6 +199,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/multicast.tunnel.tmpl b/controlplane/controller/internal/controller/fixtures/multicast.tunnel.tmpl index 6b0a134de..356902ad9 100644 --- a/controlplane/controller/internal/controller/fixtures/multicast.tunnel.tmpl +++ b/controlplane/controller/internal/controller/fixtures/multicast.tunnel.tmpl @@ -176,6 +176,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/nohardware.tunnel.tmpl b/controlplane/controller/internal/controller/fixtures/nohardware.tunnel.tmpl index d0f0db4d0..b07a53e73 100644 --- a/controlplane/controller/internal/controller/fixtures/nohardware.tunnel.tmpl +++ b/controlplane/controller/internal/controller/fixtures/nohardware.tunnel.tmpl @@ -188,6 +188,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/unicast.tunnel.tmpl b/controlplane/controller/internal/controller/fixtures/unicast.tunnel.tmpl index d03b006ed..d849c63eb 100644 --- a/controlplane/controller/internal/controller/fixtures/unicast.tunnel.tmpl +++ b/controlplane/controller/internal/controller/fixtures/unicast.tunnel.tmpl @@ -165,6 +165,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/fixtures/unknown.peer.removal.tmpl b/controlplane/controller/internal/controller/fixtures/unknown.peer.removal.tmpl index e01a86132..442313f07 100644 --- a/controlplane/controller/internal/controller/fixtures/unknown.peer.removal.tmpl +++ b/controlplane/controller/internal/controller/fixtures/unknown.peer.removal.tmpl @@ -168,6 +168,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/controlplane/controller/internal/controller/render_test.go b/controlplane/controller/internal/controller/render_test.go index 29e39049f..dc236bd15 100644 --- a/controlplane/controller/internal/controller/render_test.go +++ b/controlplane/controller/internal/controller/render_test.go @@ -548,6 +548,61 @@ func TestRenderConfig(t *testing.T) { }, Want: "fixtures/base.config.txt", }, + { + Name: "render_drained_device_config_successfully", + Description: "render config for a drained device with BGP, MSDP, and ISIS shutdown", + Data: templateData{ + Strings: StringsHelper{}, + MulticastGroupBlock: "239.0.0.0/24", + TelemetryTWAMPListenPort: 862, + LocalASN: 65342, + Device: &Device{ + PublicIP: net.IP{7, 7, 7, 7}, + Vpn4vLoopbackIP: net.IP{14, 14, 14, 14}, + IsisNet: "49.0000.0e0e.0e0e.0000.00", + Ipv4LoopbackIP: net.IP{13, 13, 13, 13}, + ExchangeCode: "tst", + BgpCommunity: 10050, + Status: serviceability.DeviceStatusDrained, + Interfaces: []Interface{ + { + Name: "Loopback255", + InterfaceType: InterfaceTypeLoopback, + LoopbackType: LoopbackTypeVpnv4, + Ip: netip.MustParsePrefix("14.14.14.14/32"), + NodeSegmentIdx: 15, + }, + { + Name: "Ethernet1/1", + InterfaceType: InterfaceTypePhysical, + Ip: netip.MustParsePrefix("172.16.0.2/31"), + Metric: 40000, + IsLink: true, + }, + { + Name: "Ethernet1/2", + InterfaceType: InterfaceTypePhysical, + Ip: netip.MustParsePrefix("172.16.0.4/31"), + }, + }, + Vpn4vLoopbackIntfName: "Loopback255", + Ipv4LoopbackIntfName: "Loopback256", + }, + Vpnv4BgpPeers: []BgpPeer{ + { + PeerIP: net.IP{15, 15, 15, 15}, + PeerName: "remote-dzd", + }, + }, + Ipv4BgpPeers: []BgpPeer{ + { + PeerIP: net.IP{12, 12, 12, 12}, + PeerName: "remote-dzd", + }, + }, + }, + Want: "fixtures/base.config.drained.txt", + }, } for _, test := range tests { diff --git a/controlplane/controller/internal/controller/templates/tunnel.tmpl b/controlplane/controller/internal/controller/templates/tunnel.tmpl index 77f1f477b..318de41d8 100644 --- a/controlplane/controller/internal/controller/templates/tunnel.tmpl +++ b/controlplane/controller/internal/controller/templates/tunnel.tmpl @@ -108,7 +108,7 @@ interface {{ .Name }} isis circuit-type level-2 isis hello-interval 1 isis metric {{ .Metric }} - {{- if eq .LinkStatus.String "hard-drained" }} + {{- if .LinkStatus.IsHardDrained }} isis passive {{- else }} no isis passive @@ -205,6 +205,9 @@ router bgp 65342 neighbor {{ .OverlayDstIP }} route-map RM-USER-{{ .Id }}-OUT out neighbor {{ .OverlayDstIP }} maximum-routes 1 neighbor {{ .OverlayDstIP }} maximum-accepted-routes 1 + {{- if $.Device.Status.IsDrained }} + neighbor {{ .OverlayDstIP }} shutdown + {{- end }} {{- end }} {{- end }} address-family ipv4 @@ -254,6 +257,9 @@ router bgp 65342 neighbor {{ .OverlayDstIP }} route-map RM-USER-{{ .Id }}-OUT out neighbor {{ .OverlayDstIP }} maximum-routes 1 neighbor {{ .OverlayDstIP }} maximum-accepted-routes 1 + {{- if $.Device.Status.IsDrained }} + neighbor {{ .OverlayDstIP }} shutdown + {{- end }} {{- end }} {{- end }} {{- end }} @@ -270,6 +276,11 @@ router isis 1 ! segment-routing mpls no shutdown +{{- if $.Device.Status.IsDrained }} + set-overload-bit +{{- else }} + no set-overload-bit +{{- end }} ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/fixtures/ibrl/doublezero_agent_config_drained.tmpl b/e2e/fixtures/ibrl/doublezero_agent_config_drained.tmpl new file mode 100644 index 000000000..e152068f3 --- /dev/null +++ b/e2e/fixtures/ibrl/doublezero_agent_config_drained.tmpl @@ -0,0 +1,336 @@ +! +logging buffered 128000 +no logging console +logging facility local7 +! +ip name-server vrf mgmt 1.1.1.1 +ip name-server vrf mgmt 9.9.9.9 +clock timezone UTC +! +ip multicast-routing +! +router pim sparse-mode + ipv4 + rp address 10.0.0.0 233.84.178.0/24 override +! +vrf instance vrf1 +ip routing +ip routing vrf vrf1 +! +ntp server vrf mgmt 0.pool.ntp.org +ntp server vrf mgmt 1.pool.ntp.org +ntp server vrf mgmt 2.pool.ntp.org +! +no ip access-list MAIN-CONTROL-PLANE-ACL +ip access-list MAIN-CONTROL-PLANE-ACL + counters per-entry + 10 permit icmp any any + 20 permit ip any any tracked + 30 permit udp any any eq bfd ttl eq 255 + 40 permit udp any any eq bfd-echo ttl eq 254 + 50 permit udp any any eq multihop-bfd micro-bfd sbfd + 60 permit udp any eq sbfd any eq sbfd-initiator + 70 permit ospf any any + 80 permit tcp any any eq ssh telnet www snmp bgp https msdp ldp netconf-ssh gnmi + 90 permit udp any any eq bootps bootpc snmp rip ntp ldp ptp-event ptp-general + 100 permit tcp any any eq mlag ttl eq 255 + 110 permit udp any any eq mlag ttl eq 255 + 120 permit vrrp any any + 130 permit ahp any any + 140 permit pim any any + 150 permit igmp any any + 160 permit tcp any any range 5900 5910 + 170 permit tcp any any range 50000 50100 + 180 permit udp any any range 51000 51100 + 190 permit tcp any any eq 3333 + 200 permit tcp any any eq nat ttl eq 255 + 210 permit tcp any eq bgp any + 220 permit rsvp any any + 230 permit tcp any any eq 9340 + 240 permit tcp any any eq 9559 + 250 permit udp any any eq 8503 + 260 permit udp any any eq lsp-ping + 270 permit udp any eq lsp-ping any + 280 remark Permit TWAMP (UDP 862) + 290 permit udp any any eq 862 +! +system control-plane + ip access-group MAIN-CONTROL-PLANE-ACL in +! +interface Ethernet2 + mtu 2048 + no switchport + ip address 172.16.0.19/31 + pim ipv4 sparse-mode + isis enable 1 + isis circuit-type level-2 + isis hello-interval 1 + isis metric 40000 + no isis passive + isis hello padding + isis network point-to-point +! +interface Ethernet4 + mtu 2048 + no switchport + ip address 172.16.0.30/31 + pim ipv4 sparse-mode + isis enable 1 + isis circuit-type level-2 + isis hello-interval 1 + isis metric 500000 + no isis passive + isis hello padding + isis network point-to-point +! +interface Ethernet5 + mtu 2048 + no switchport + ip address 172.16.0.32/31 + pim ipv4 sparse-mode + isis enable 1 + isis circuit-type level-2 + isis hello-interval 1 + isis metric 30000 + no isis passive + isis hello padding + isis network point-to-point +! +interface Ethernet6 + mtu 2048 + no switchport + ip address 172.16.0.34/31 + pim ipv4 sparse-mode + isis enable 1 + isis circuit-type level-2 + isis hello-interval 1 + isis metric 8000 + no isis passive + isis hello padding + isis network point-to-point +! +interface Loopback255 + ip address 172.16.0.1/32 + node-segment ipv4 index 1 + isis enable 1 +! +interface Loopback256 + ip address 172.16.0.9/32 + isis enable 1 +! +interface Vlan4001 + mtu 2048 + ip address 172.16.0.20/31 + pim ipv4 sparse-mode + isis enable 1 + isis circuit-type level-2 + isis hello-interval 1 + isis metric 30000 + no isis passive + isis hello padding + isis network point-to-point +! +interface Loopback1000 + description RP Address + ip address 10.0.0.0/32 +! +mpls ip +! +mpls icmp ttl-exceeded tunneling +mpls icmp ip source-interface Loopback255 +! +{{- range $i := seq .StartTunnel .EndTunnel}} +default interface Tunnel{{$i}} +{{- end}} +router bgp 65342 + router-id 172.16.0.1 + timers bgp 1 3 + distance bgp 20 200 200 + no neighbor 172.16.0.14 + neighbor 172.16.0.14 remote-as 65342 + neighbor 172.16.0.14 next-hop-self + neighbor 172.16.0.14 update-source Loopback256 + neighbor 172.16.0.14 description ty2-dz01-ipv4 + neighbor 172.16.0.14 timers 3 9 + neighbor 172.16.0.14 send-community + no neighbor 172.16.0.11 + neighbor 172.16.0.11 remote-as 65342 + neighbor 172.16.0.11 next-hop-self + neighbor 172.16.0.11 update-source Loopback256 + neighbor 172.16.0.11 description ld4-dz01-ipv4 + neighbor 172.16.0.11 timers 3 9 + neighbor 172.16.0.11 send-community + no neighbor 172.16.0.10 + neighbor 172.16.0.10 remote-as 65342 + neighbor 172.16.0.10 next-hop-self + neighbor 172.16.0.10 update-source Loopback256 + neighbor 172.16.0.10 description la2-dz01-ipv4 + neighbor 172.16.0.10 timers 3 9 + neighbor 172.16.0.10 send-community + no neighbor 172.16.0.13 + neighbor 172.16.0.13 remote-as 65342 + neighbor 172.16.0.13 next-hop-self + neighbor 172.16.0.13 update-source Loopback256 + neighbor 172.16.0.13 description sg1-dz01-ipv4 + neighbor 172.16.0.13 timers 3 9 + neighbor 172.16.0.13 send-community + no neighbor 172.16.0.16 + neighbor 172.16.0.16 remote-as 65342 + neighbor 172.16.0.16 next-hop-self + neighbor 172.16.0.16 update-source Loopback256 + neighbor 172.16.0.16 description ams-dz001-ipv4 + neighbor 172.16.0.16 timers 3 9 + neighbor 172.16.0.16 send-community + no neighbor 172.16.0.12 + neighbor 172.16.0.12 remote-as 65342 + neighbor 172.16.0.12 next-hop-self + neighbor 172.16.0.12 update-source Loopback256 + neighbor 172.16.0.12 description frk-dz01-ipv4 + neighbor 172.16.0.12 timers 3 9 + neighbor 172.16.0.12 send-community + no neighbor 172.16.0.6 + neighbor 172.16.0.6 remote-as 65342 + neighbor 172.16.0.6 next-hop-self + neighbor 172.16.0.6 update-source Loopback255 + neighbor 172.16.0.6 description ty2-dz01-vpnv4 + neighbor 172.16.0.6 timers 3 9 + neighbor 172.16.0.6 send-community + no neighbor 172.16.0.3 + neighbor 172.16.0.3 remote-as 65342 + neighbor 172.16.0.3 next-hop-self + neighbor 172.16.0.3 update-source Loopback255 + neighbor 172.16.0.3 description ld4-dz01-vpnv4 + neighbor 172.16.0.3 timers 3 9 + neighbor 172.16.0.3 send-community + no neighbor 172.16.0.2 + neighbor 172.16.0.2 remote-as 65342 + neighbor 172.16.0.2 next-hop-self + neighbor 172.16.0.2 update-source Loopback255 + neighbor 172.16.0.2 description la2-dz01-vpnv4 + neighbor 172.16.0.2 timers 3 9 + neighbor 172.16.0.2 send-community + no neighbor 172.16.0.5 + neighbor 172.16.0.5 remote-as 65342 + neighbor 172.16.0.5 next-hop-self + neighbor 172.16.0.5 update-source Loopback255 + neighbor 172.16.0.5 description sg1-dz01-vpnv4 + neighbor 172.16.0.5 timers 3 9 + neighbor 172.16.0.5 send-community + no neighbor 172.16.0.8 + neighbor 172.16.0.8 remote-as 65342 + neighbor 172.16.0.8 next-hop-self + neighbor 172.16.0.8 update-source Loopback255 + neighbor 172.16.0.8 description ams-dz001-vpnv4 + neighbor 172.16.0.8 timers 3 9 + neighbor 172.16.0.8 send-community + no neighbor 172.16.0.4 + neighbor 172.16.0.4 remote-as 65342 + neighbor 172.16.0.4 next-hop-self + neighbor 172.16.0.4 update-source Loopback255 + neighbor 172.16.0.4 description frk-dz01-vpnv4 + neighbor 172.16.0.4 timers 3 9 + neighbor 172.16.0.4 send-community + address-family ipv4 + neighbor 172.16.0.14 activate + neighbor 172.16.0.11 activate + neighbor 172.16.0.10 activate + neighbor 172.16.0.13 activate + neighbor 172.16.0.16 activate + neighbor 172.16.0.12 activate + no neighbor 172.16.0.6 activate + no neighbor 172.16.0.3 activate + no neighbor 172.16.0.2 activate + no neighbor 172.16.0.5 activate + no neighbor 172.16.0.8 activate + no neighbor 172.16.0.4 activate + ! + address-family vpn-ipv4 + neighbor 172.16.0.6 activate + neighbor 172.16.0.3 activate + neighbor 172.16.0.2 activate + neighbor 172.16.0.5 activate + neighbor 172.16.0.8 activate + neighbor 172.16.0.4 activate + ! + vrf vrf1 + rd 65342:1 + route-target import vpn-ipv4 65342:1 + route-target export vpn-ipv4 65342:1 + router-id {{.DeviceIP}} +! +router isis 1 + net 49.0000.ac10.0001.0000.00 + router-id ipv4 172.16.0.1 + log-adjacency-changes + ! + address-family ipv4 unicast + ! + segment-routing mpls + no shutdown + set-overload-bit +! +ip community-list COMM-ALL_USERS permit 21682:1200 +ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 +ip community-list COMM-XEWR_USERS permit 21682:10001 +! +{{- range $i := seq .StartTunnel .EndTunnel}} +no route-map RM-USER-{{$i}}-OUT +! +{{- end}} +{{- range $i := seq .StartTunnel .EndTunnel}} +no route-map RM-USER-{{$i}}-IN +! +{{- end}} +{{- range $i := seq .StartTunnel .EndTunnel}} +no ip prefix-list PL-USER-{{$i}} +! +{{- end}} +{{- range $i := seq .StartTunnel .EndTunnel}} +no ip access-list SEC-USER-{{$i}}-IN +{{- end}} +{{- range $i := seq .StartTunnel .EndTunnel}} +no ip access-list standard SEC-USER-MCAST-BOUNDARY-{{$i}}-OUT +{{- end}} +no ip access-list SEC-USER-PUB-MCAST-IN +ip access-list SEC-USER-PUB-MCAST-IN + counters per-entry + permit icmp any any + permit tcp any any eq bgp + permit ip any 224.0.0.13/32 + permit ip any 233.84.178.0/24 + deny ip any any +! +no ip access-list SEC-USER-SUB-MCAST-IN +ip access-list SEC-USER-SUB-MCAST-IN + counters per-entry + permit icmp any any + permit tcp any any eq bgp + permit ip any 224.0.0.13/32 + deny ip any any +! +no router msdp +router msdp + peer 172.16.0.14 + mesh-group DZ-1 + local-interface Loopback256 + description ty2-dz01 + peer 172.16.0.11 + mesh-group DZ-1 + local-interface Loopback256 + description ld4-dz01 + peer 172.16.0.10 + mesh-group DZ-1 + local-interface Loopback256 + description la2-dz01 + peer 172.16.0.13 + mesh-group DZ-1 + local-interface Loopback256 + description sg1-dz01 + peer 172.16.0.16 + mesh-group DZ-1 + local-interface Loopback256 + description ams-dz001 + peer 172.16.0.12 + mesh-group DZ-1 + local-interface Loopback256 + description frk-dz01 diff --git a/e2e/fixtures/ibrl/doublezero_agent_config_peer_removed.tmpl b/e2e/fixtures/ibrl/doublezero_agent_config_peer_removed.tmpl index 34467a4a5..d2d1fe3d5 100644 --- a/e2e/fixtures/ibrl/doublezero_agent_config_peer_removed.tmpl +++ b/e2e/fixtures/ibrl/doublezero_agent_config_peer_removed.tmpl @@ -267,6 +267,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/fixtures/ibrl/doublezero_agent_config_user_added.tmpl b/e2e/fixtures/ibrl/doublezero_agent_config_user_added.tmpl index 0c45cab0d..ce00de034 100644 --- a/e2e/fixtures/ibrl/doublezero_agent_config_user_added.tmpl +++ b/e2e/fixtures/ibrl/doublezero_agent_config_user_added.tmpl @@ -305,6 +305,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/fixtures/ibrl/doublezero_agent_config_user_removed.tmpl b/e2e/fixtures/ibrl/doublezero_agent_config_user_removed.tmpl index 07864927f..301cb5f17 100644 --- a/e2e/fixtures/ibrl/doublezero_agent_config_user_removed.tmpl +++ b/e2e/fixtures/ibrl/doublezero_agent_config_user_removed.tmpl @@ -284,6 +284,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/fixtures/ibrl_with_allocated_addr/doublezero_agent_config_user_added.tmpl b/e2e/fixtures/ibrl_with_allocated_addr/doublezero_agent_config_user_added.tmpl index 35f5ab0cb..00dd8ce9f 100644 --- a/e2e/fixtures/ibrl_with_allocated_addr/doublezero_agent_config_user_added.tmpl +++ b/e2e/fixtures/ibrl_with_allocated_addr/doublezero_agent_config_user_added.tmpl @@ -305,6 +305,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/fixtures/ibrl_with_allocated_addr/doublezero_agent_config_user_removed.tmpl b/e2e/fixtures/ibrl_with_allocated_addr/doublezero_agent_config_user_removed.tmpl index 07864927f..301cb5f17 100644 --- a/e2e/fixtures/ibrl_with_allocated_addr/doublezero_agent_config_user_removed.tmpl +++ b/e2e/fixtures/ibrl_with_allocated_addr/doublezero_agent_config_user_removed.tmpl @@ -284,6 +284,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/fixtures/multicast_publisher/doublezero_agent_config_user_added.tmpl b/e2e/fixtures/multicast_publisher/doublezero_agent_config_user_added.tmpl index a0db23fb7..8fe33cc9f 100644 --- a/e2e/fixtures/multicast_publisher/doublezero_agent_config_user_added.tmpl +++ b/e2e/fixtures/multicast_publisher/doublezero_agent_config_user_added.tmpl @@ -309,6 +309,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/fixtures/multicast_publisher/doublezero_agent_config_user_removed.tmpl b/e2e/fixtures/multicast_publisher/doublezero_agent_config_user_removed.tmpl index 07864927f..301cb5f17 100644 --- a/e2e/fixtures/multicast_publisher/doublezero_agent_config_user_removed.tmpl +++ b/e2e/fixtures/multicast_publisher/doublezero_agent_config_user_removed.tmpl @@ -284,6 +284,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/fixtures/multicast_subscriber/doublezero_agent_config_user_added.tmpl b/e2e/fixtures/multicast_subscriber/doublezero_agent_config_user_added.tmpl index ad71b9bbc..df20b4c49 100644 --- a/e2e/fixtures/multicast_subscriber/doublezero_agent_config_user_added.tmpl +++ b/e2e/fixtures/multicast_subscriber/doublezero_agent_config_user_added.tmpl @@ -308,6 +308,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/fixtures/multicast_subscriber/doublezero_agent_config_user_removed.tmpl b/e2e/fixtures/multicast_subscriber/doublezero_agent_config_user_removed.tmpl index 07864927f..301cb5f17 100644 --- a/e2e/fixtures/multicast_subscriber/doublezero_agent_config_user_removed.tmpl +++ b/e2e/fixtures/multicast_subscriber/doublezero_agent_config_user_removed.tmpl @@ -284,6 +284,7 @@ router isis 1 ! segment-routing mpls no shutdown + no set-overload-bit ! ip community-list COMM-ALL_USERS permit 21682:1200 ip community-list COMM-ALL_MCAST_USERS permit 21682:1300 diff --git a/e2e/ibrl_test.go b/e2e/ibrl_test.go index b9de1f22a..46fd6c5e3 100644 --- a/e2e/ibrl_test.go +++ b/e2e/ibrl_test.go @@ -49,6 +49,18 @@ func TestE2E_IBRL(t *testing.T) { }) { t.Fail() } + + if !t.Run("drain_device", func(t *testing.T) { + checkDeviceDrain(t, dn, device) + }) { + t.Fail() + } + + if !t.Run("undrain_device", func(t *testing.T) { + checkDeviceUndrain(t, dn, device) + }) { + t.Fail() + } } func checkIbgpMsdpPeerRemoved(t *testing.T, dn *TestDevnet, device *devnet.Device) { @@ -72,6 +84,62 @@ func checkIbgpMsdpPeerRemoved(t *testing.T, dn *TestDevnet, device *devnet.Devic dn.log.Info("--> IBRL iBGP/MSDP peer removal requirements checked") } +func checkDeviceDrain(t *testing.T, dn *TestDevnet, device *devnet.Device) { + dn.log.Info("==> Checking that device is drained") + + if !t.Run("set_device_status_to_drained", func(t *testing.T) { + _, err := dn.Manager.Exec(t.Context(), []string{"doublezero", "device", "update", "--pubkey", device.Spec.Code, "--desired-status", "drained"}) + require.NoError(t, err) + }) { + t.Fail() + return + } + + if !t.Run("wait_for_drained_config", func(t *testing.T) { + config, err := fixtures.Render("fixtures/ibrl/doublezero_agent_config_drained.tmpl", map[string]any{ + "DeviceIP": device.CYOANetworkIP, + "StartTunnel": controllerconfig.StartUserTunnelNum, + "EndTunnel": controllerconfig.StartUserTunnelNum + controllerconfig.MaxUserTunnelSlots - 1, + }) + require.NoError(t, err, "error reading drained config fixture") + err = dn.WaitForAgentConfigMatchViaController(t, device.ID, string(config)) + require.NoError(t, err, "error waiting for drained config") + }) { + t.Fail() + } + + dn.log.Info("--> Device drain requirements checked") +} + +func checkDeviceUndrain(t *testing.T, dn *TestDevnet, device *devnet.Device) { + dn.log.Info("==> Checking that device is undrained (returned to activated)") + + if !t.Run("set_device_status_to_activated", func(t *testing.T) { + _, err := dn.Manager.Exec(t.Context(), []string{"doublezero", "device", "update", "--pubkey", device.Spec.Code, "--desired-status", "activated"}) + require.NoError(t, err) + }) { + t.Fail() + return + } + + if !t.Run("wait_for_undrained_config", func(t *testing.T) { + // After undrain, the config should return to the state before draining + // which is after peer removal (pit-dzd01 removed), with no shutdown commands + config, err := fixtures.Render("fixtures/ibrl/doublezero_agent_config_peer_removed.tmpl", map[string]any{ + "DeviceIP": device.CYOANetworkIP, + "StartTunnel": controllerconfig.StartUserTunnelNum, + "EndTunnel": controllerconfig.StartUserTunnelNum + controllerconfig.MaxUserTunnelSlots - 1, + }) + require.NoError(t, err, "error reading undrained config fixture") + err = dn.WaitForAgentConfigMatchViaController(t, device.ID, string(config)) + require.NoError(t, err, "error waiting for undrained config") + }) { + t.Fail() + } + + dn.log.Info("--> Device undrain requirements checked") +} + // checkIBRLPostConnect checks requirements after connecting a user tunnel. func checkIBRLPostConnect(t *testing.T, dn *TestDevnet, device *devnet.Device, client *devnet.Client) { // NOTE: Since we have inner parallel tests in this method, we need to wrap them in a diff --git a/smartcontract/sdk/go/serviceability/state.go b/smartcontract/sdk/go/serviceability/state.go index d37f870d6..6f1f36d6d 100644 --- a/smartcontract/sdk/go/serviceability/state.go +++ b/smartcontract/sdk/go/serviceability/state.go @@ -136,6 +136,11 @@ func (d DeviceStatus) String() string { }[d] } +// IsDrained returns true if the device status is drained +func (d DeviceStatus) IsDrained() bool { + return d == DeviceStatusDrained +} + func (d DeviceStatus) MarshalJSON() ([]byte, error) { return json.Marshal(d.String()) } @@ -459,8 +464,8 @@ const ( LinkStatusDeleted LinkStatusRejected LinkStatusRequested - LinkStatusHardDrained LinkStatusSoftDrained + LinkStatusHardDrained LinkStatusProvisioning ) @@ -472,12 +477,17 @@ func (l LinkStatus) String() string { "deleted", "rejected", "requested", - "hard-drained", "soft-drained", + "hard-drained", "provisioning", }[l] } +// IsHardDrained returns true if the link status is hard-drained +func (l LinkStatus) IsHardDrained() bool { + return l == LinkStatusHardDrained +} + func (l LinkStatus) MarshalJSON() ([]byte, error) { return json.Marshal(l.String()) }