├── 0.-planirovanie └── 0.-planirovanie.md ├── 1.-virtualnaya-set ├── 0.-virtualnaya-set.md └── 1.-osnovi-virtualizacii.md ├── 2.-dizain-seti ├── 0.-dizain-seti.md ├── 1.-dc_networks.md └── target_configs │ ├── bcn-edge-0.cfg │ ├── bcn-host-0.cfg │ ├── bcn-leaf-1.cfg │ ├── bcn-spine-0.cfg │ ├── bcn-spine-1.cfg │ ├── kzn-edge-0.cfg │ ├── kzn-host-0.cfg │ ├── kzn-leaf-0.cfg │ ├── kzn-spine-0.cfg │ ├── kzn-spine-1.cfg │ └── mgmt-switch.cfg ├── 3.-ipam ├── ipam.md └── restful.md ├── 4.-lifecycle └── article.html ├── 5.-interfaces ├── 0.-history.md ├── 1.-interfaces (for site).md └── 1.-interfaces.md ├── LICENSE.md ├── README.md ├── TODO.md ├── docs ├── Makefile ├── build │ ├── doctrees │ │ ├── 0_planning │ │ │ ├── 0_goals │ │ │ │ ├── goals.doctree │ │ │ │ ├── index.doctree │ │ │ │ ├── monitoring.doctree │ │ │ │ ├── network_as_a_being.doctree │ │ │ │ ├── testing.doctree │ │ │ │ └── versioning.doctree │ │ │ ├── 1_tools │ │ │ │ └── index.doctree │ │ │ ├── 2_conclusion │ │ │ │ └── index.doctree │ │ │ ├── conclusion.doctree │ │ │ ├── goals.doctree │ │ │ ├── index.doctree │ │ │ ├── planning.doctree │ │ │ └── tools.doctree │ │ ├── 1_virtual_network │ │ │ └── index.doctree │ │ ├── 1_virtualization │ │ │ ├── 0_virtual_network │ │ │ │ ├── conclusion.doctree │ │ │ │ ├── faq.doctree │ │ │ │ ├── index.doctree │ │ │ │ ├── motivation.doctree │ │ │ │ ├── overlay.doctree │ │ │ │ ├── terminology.doctree │ │ │ │ └── underlay.doctree │ │ │ ├── 1_virtualization_basics │ │ │ │ ├── conclusion.doctree │ │ │ │ ├── history.doctree │ │ │ │ ├── index.doctree │ │ │ │ ├── resource_types.doctree │ │ │ │ ├── tools.doctree │ │ │ │ └── vitual_switching.doctree │ │ │ └── index.doctree │ │ ├── 2_network_design │ │ │ ├── conclusion.doctree │ │ │ ├── index.doctree │ │ │ ├── ip_plan.doctree │ │ │ ├── lab.doctree │ │ │ ├── routing.doctree │ │ │ └── topology.doctree │ │ ├── 3_ipam_dcim │ │ │ ├── architecture.doctree │ │ │ ├── conclusion.doctree │ │ │ ├── index.doctree │ │ │ ├── installation.doctree │ │ │ ├── postgresql.doctree │ │ │ ├── restful │ │ │ │ ├── conclusion.doctree │ │ │ │ ├── index.doctree │ │ │ │ ├── installation.doctree │ │ │ │ ├── messages.doctree │ │ │ │ ├── methods.doctree │ │ │ │ ├── other.doctree │ │ │ │ ├── postgresql.doctree │ │ │ │ ├── rest.doctree │ │ │ │ ├── scheme.doctree │ │ │ │ └── ways.doctree │ │ │ └── scheme.doctree │ │ ├── 4_lifecycle │ │ │ ├── architecture.doctree │ │ │ ├── conclusion.doctree │ │ │ ├── iac.doctree │ │ │ ├── index.doctree │ │ │ ├── lifecycle.doctree │ │ │ ├── links.doctree │ │ │ └── scenarios.doctree │ │ ├── 5_history │ │ │ ├── api_rpc.doctree │ │ │ ├── cli.doctree │ │ │ ├── conclusion.doctree │ │ │ ├── future.doctree │ │ │ ├── grpc.doctree │ │ │ ├── horizon.doctree │ │ │ ├── index.doctree │ │ │ ├── links.doctree │ │ │ ├── models.doctree │ │ │ ├── netconf.doctree │ │ │ ├── nowdays.doctree │ │ │ ├── restconf.doctree │ │ │ └── snmp.doctree │ │ ├── 6_interfaces │ │ │ ├── callhome.doctree │ │ │ ├── cli.doctree │ │ │ ├── conclusion.doctree │ │ │ ├── grpc.doctree │ │ │ ├── index.doctree │ │ │ ├── links.doctree │ │ │ ├── model_driven.doctree │ │ │ ├── models.doctree │ │ │ ├── netconf.doctree │ │ │ ├── netconf_again.doctree │ │ │ ├── onemoretime.doctree │ │ │ ├── restconf.doctree │ │ │ ├── rpc.doctree │ │ │ ├── xml.doctree │ │ │ └── yang.doctree │ │ ├── contents.doctree │ │ ├── environment.pickle │ │ ├── index.doctree │ │ └── index_back.doctree │ └── html │ │ ├── .buildinfo │ │ ├── 0_planning │ │ ├── 0_goals │ │ │ ├── goals.html │ │ │ ├── index.html │ │ │ ├── monitoring.html │ │ │ ├── network_as_a_being.html │ │ │ ├── testing.html │ │ │ └── versioning.html │ │ ├── 1_tools │ │ │ └── index.html │ │ ├── 2_conclusion │ │ │ └── index.html │ │ ├── conclusion.html │ │ ├── goals.html │ │ ├── index.html │ │ ├── planning.html │ │ └── tools.html │ │ ├── 1_virtual_network │ │ └── index.html │ │ ├── 1_virtualization │ │ ├── 0_virtual_network │ │ │ ├── conclusion.html │ │ │ ├── faq.html │ │ │ ├── index.html │ │ │ ├── motivation.html │ │ │ ├── overlay.html │ │ │ ├── terminology.html │ │ │ └── underlay.html │ │ ├── 1_virtualization_basics │ │ │ ├── conclusion.html │ │ │ ├── history.html │ │ │ ├── index.html │ │ │ ├── resource_types.html │ │ │ ├── tools.html │ │ │ └── vitual_switching.html │ │ └── index.html │ │ ├── 2_network_design │ │ ├── conclusion.html │ │ ├── index.html │ │ ├── ip_plan.html │ │ ├── lab.html │ │ ├── routing.html │ │ └── topology.html │ │ ├── 3_ipam_dcim │ │ ├── architecture.html │ │ ├── conclusion.html │ │ ├── index.html │ │ ├── installation.html │ │ ├── postgresql.html │ │ ├── restful │ │ │ ├── conclusion.html │ │ │ ├── index.html │ │ │ ├── installation.html │ │ │ ├── messages.html │ │ │ ├── methods.html │ │ │ ├── other.html │ │ │ ├── postgresql.html │ │ │ ├── rest.html │ │ │ ├── scheme.html │ │ │ └── ways.html │ │ └── scheme.html │ │ ├── 4_lifecycle │ │ ├── architecture.html │ │ ├── conclusion.html │ │ ├── iac.html │ │ ├── index.html │ │ ├── lifecycle.html │ │ ├── links.html │ │ └── scenarios.html │ │ ├── 5_history │ │ ├── api_rpc.html │ │ ├── cli.html │ │ ├── conclusion.html │ │ ├── future.html │ │ ├── grpc.html │ │ ├── horizon.html │ │ ├── index.html │ │ ├── links.html │ │ ├── models.html │ │ ├── netconf.html │ │ ├── nowdays.html │ │ ├── restconf.html │ │ └── snmp.html │ │ ├── 6_interfaces │ │ ├── callhome.html │ │ ├── cli.html │ │ ├── conclusion.html │ │ ├── grpc.html │ │ ├── index.html │ │ ├── links.html │ │ ├── model_driven.html │ │ ├── models.html │ │ ├── netconf.html │ │ ├── netconf_again.html │ │ ├── onemoretime.html │ │ ├── restconf.html │ │ ├── rpc.html │ │ ├── xml.html │ │ └── yang.html │ │ ├── _sources │ │ ├── 0_planning │ │ │ ├── 0_goals │ │ │ │ ├── goals.rst.txt │ │ │ │ ├── index.rst.txt │ │ │ │ ├── monitoring.rst.txt │ │ │ │ ├── network_as_a_being.rst.txt │ │ │ │ ├── testing.rst.txt │ │ │ │ └── versioning.rst.txt │ │ │ ├── 1_tools │ │ │ │ └── index.rst.txt │ │ │ ├── 2_conclusion │ │ │ │ └── index.rst.txt │ │ │ ├── conclusion.rst.txt │ │ │ ├── goals.rst.txt │ │ │ ├── index.rst.txt │ │ │ ├── planning.rst.txt │ │ │ └── tools.rst.txt │ │ ├── 1_virtual_network │ │ │ └── index.rst.txt │ │ ├── 1_virtualization │ │ │ ├── 0_virtual_network │ │ │ │ ├── conclusion.rst.txt │ │ │ │ ├── faq.rst.txt │ │ │ │ ├── index.rst.txt │ │ │ │ ├── motivation.rst.txt │ │ │ │ ├── overlay.rst.txt │ │ │ │ ├── terminology.rst.txt │ │ │ │ └── underlay.rst.txt │ │ │ ├── 1_virtualization_basics │ │ │ │ ├── conclusion.rst.txt │ │ │ │ ├── history.rst.txt │ │ │ │ ├── index.rst.txt │ │ │ │ ├── resource_types.rst.txt │ │ │ │ ├── tools.rst.txt │ │ │ │ └── vitual_switching.rst.txt │ │ │ └── index.rst.txt │ │ ├── 2_network_design │ │ │ ├── conclusion.rst.txt │ │ │ ├── index.rst.txt │ │ │ ├── ip_plan.rst.txt │ │ │ ├── lab.rst.txt │ │ │ ├── routing.rst.txt │ │ │ └── topology.rst.txt │ │ ├── 3_ipam_dcim │ │ │ ├── architecture.rst.txt │ │ │ ├── conclusion.rst.txt │ │ │ ├── index.rst.txt │ │ │ ├── installation.rst.txt │ │ │ ├── postgresql.rst.txt │ │ │ ├── restful │ │ │ │ ├── conclusion.rst.txt │ │ │ │ ├── index.rst.txt │ │ │ │ ├── installation.rst.txt │ │ │ │ ├── messages.rst.txt │ │ │ │ ├── methods.rst.txt │ │ │ │ ├── other.rst.txt │ │ │ │ ├── postgresql.rst.txt │ │ │ │ ├── rest.rst.txt │ │ │ │ ├── scheme.rst.txt │ │ │ │ └── ways.rst.txt │ │ │ └── scheme.rst.txt │ │ ├── 4_lifecycle │ │ │ ├── architecture.rst.txt │ │ │ ├── conclusion.rst.txt │ │ │ ├── iac.rst.txt │ │ │ ├── index.rst.txt │ │ │ ├── lifecycle.rst.txt │ │ │ ├── links.rst.txt │ │ │ └── scenarios.rst.txt │ │ ├── 5_history │ │ │ ├── api_rpc.rst.txt │ │ │ ├── cli.rst.txt │ │ │ ├── conclusion.rst.txt │ │ │ ├── future.rst.txt │ │ │ ├── grpc.rst.txt │ │ │ ├── horizon.rst.txt │ │ │ ├── index.rst.txt │ │ │ ├── links.rst.txt │ │ │ ├── models.rst.txt │ │ │ ├── netconf.rst.txt │ │ │ ├── nowdays.rst.txt │ │ │ ├── restconf.rst.txt │ │ │ └── snmp.rst.txt │ │ ├── 6_interfaces │ │ │ ├── callhome.rst.txt │ │ │ ├── cli.rst.txt │ │ │ ├── conclusion.rst.txt │ │ │ ├── grpc.rst.txt │ │ │ ├── index.rst.txt │ │ │ ├── links.rst.txt │ │ │ ├── model_driven.rst.txt │ │ │ ├── models.rst.txt │ │ │ ├── netconf.rst.txt │ │ │ ├── netconf_again.rst.txt │ │ │ ├── onemoretime.rst.txt │ │ │ ├── restconf.rst.txt │ │ │ ├── rpc.rst.txt │ │ │ ├── xml.rst.txt │ │ │ └── yang.rst.txt │ │ ├── contents.rst.txt │ │ ├── index.rst.txt │ │ └── index_back.rst.txt │ │ ├── _static │ │ ├── _stemmer.js │ │ ├── ajax-loader.gif │ │ ├── alabaster.css │ │ ├── basic.css │ │ ├── comment-bright.png │ │ ├── comment-close.png │ │ ├── comment.png │ │ ├── css │ │ │ ├── badge_only.css │ │ │ └── theme.css │ │ ├── custom.css │ │ ├── doctools.js │ │ ├── documentation_options.js │ │ ├── down-pressed.png │ │ ├── down.png │ │ ├── file.png │ │ ├── fonts │ │ │ ├── .DS_Store │ │ │ ├── Inconsolata-Bold.ttf │ │ │ ├── Inconsolata-Regular.ttf │ │ │ ├── Inconsolata.ttf │ │ │ ├── Lato-Bold.ttf │ │ │ ├── Lato-Regular.ttf │ │ │ ├── Lato │ │ │ │ ├── lato-bold.eot │ │ │ │ ├── lato-bold.ttf │ │ │ │ ├── lato-bold.woff │ │ │ │ ├── lato-bold.woff2 │ │ │ │ ├── lato-bolditalic.eot │ │ │ │ ├── lato-bolditalic.ttf │ │ │ │ ├── lato-bolditalic.woff │ │ │ │ ├── lato-bolditalic.woff2 │ │ │ │ ├── lato-italic.eot │ │ │ │ ├── lato-italic.ttf │ │ │ │ ├── lato-italic.woff │ │ │ │ ├── lato-italic.woff2 │ │ │ │ ├── lato-regular.eot │ │ │ │ ├── lato-regular.ttf │ │ │ │ ├── lato-regular.woff │ │ │ │ └── lato-regular.woff2 │ │ │ ├── RobotoSlab-Bold.ttf │ │ │ ├── RobotoSlab-Regular.ttf │ │ │ ├── RobotoSlab │ │ │ │ ├── roboto-slab-v7-bold.eot │ │ │ │ ├── roboto-slab-v7-bold.ttf │ │ │ │ ├── roboto-slab-v7-bold.woff │ │ │ │ ├── roboto-slab-v7-bold.woff2 │ │ │ │ ├── roboto-slab-v7-regular.eot │ │ │ │ ├── roboto-slab-v7-regular.ttf │ │ │ │ ├── roboto-slab-v7-regular.woff │ │ │ │ └── roboto-slab-v7-regular.woff2 │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ ├── jquery-3.2.1.js │ │ ├── jquery-3.4.1.js │ │ ├── jquery.js │ │ ├── js │ │ │ ├── modernizr.min.js │ │ │ └── theme.js │ │ ├── language_data.js │ │ ├── minus.png │ │ ├── plus.png │ │ ├── pygments.css │ │ ├── searchtools.js │ │ ├── translations.js │ │ ├── underscore-1.3.1.js │ │ ├── underscore.js │ │ ├── up-pressed.png │ │ ├── up.png │ │ └── websupport.js │ │ ├── contents.html │ │ ├── genindex.html │ │ ├── index.html │ │ ├── index_back.html │ │ ├── objects.inv │ │ ├── search.html │ │ └── searchindex.js ├── make.bat └── source │ ├── 0_planning │ ├── conclusion.rst │ ├── goals.rst │ ├── planning.rst │ └── tools.rst │ ├── 1_virtualization │ ├── 0.-virtualnaya-set.md │ ├── 0_virtual_network │ │ ├── conclusion.rst │ │ ├── faq.rst │ │ ├── index.rst │ │ ├── motivation.rst │ │ ├── overlay.rst │ │ ├── terminology.rst │ │ └── underlay.rst │ ├── 1_virtualization_basics │ │ ├── conclusion.rst │ │ ├── history.rst │ │ ├── index.rst │ │ ├── resource_types.rst │ │ ├── tools.rst │ │ └── vitual_switching.rst │ └── index.rst │ ├── 2_network_design │ ├── conclusion.rst │ ├── index.rst │ ├── ip_plan.rst │ ├── lab.rst │ ├── routing.rst │ ├── target_configs │ │ ├── bcn-edge-0.cfg │ │ ├── bcn-host-0.cfg │ │ ├── bcn-leaf-1.cfg │ │ ├── bcn-spine-0.cfg │ │ ├── bcn-spine-1.cfg │ │ ├── kzn-edge-0.cfg │ │ ├── kzn-host-0.cfg │ │ ├── kzn-leaf-0.cfg │ │ ├── kzn-spine-0.cfg │ │ ├── kzn-spine-1.cfg │ │ └── mgmt-switch.cfg │ └── topology.rst │ ├── 3_ipam_dcim │ ├── architecture.rst │ ├── conclusion.rst │ ├── dumps │ │ ├── http_delete_device.pcapng │ │ ├── http_get_all_devices.pcapng │ │ ├── http_get_device_by_name.pcapng │ │ ├── http_get_device_with_double_conditions.pcapng │ │ ├── http_get_device_with_or_operand.pcapng │ │ ├── http_get_devices.pcapng │ │ ├── http_get_not_found.pcapng │ │ ├── http_patch_serial.pcapng │ │ ├── http_post_new_device.pcapng │ │ └── http_put_asset_tag.pcapng │ ├── index.rst │ ├── installation.rst │ ├── netbox_initial_db.sql │ ├── postgresql.rst │ ├── restful │ │ ├── conclusion.rst │ │ ├── index.rst │ │ ├── messages.rst │ │ ├── methods.rst │ │ ├── rest.rst │ │ └── ways.rst │ ├── scheme.rst │ └── scripts │ │ ├── pynetbox_get_devices.py │ │ ├── pynetbox_post_new_device.py │ │ ├── requests_get_devices.py │ │ └── requests_post_new_device.py │ ├── 4_lifecycle │ ├── architecture.rst │ ├── conclusion.rst │ ├── iac.rst │ ├── index.rst │ ├── lifecycle.rst │ ├── links.rst │ └── scenarios.rst │ ├── 5_history │ ├── api_rpc.rst │ ├── cli.rst │ ├── conclusion.rst │ ├── future.rst │ ├── grpc.rst │ ├── horizon.rst │ ├── index.rst │ ├── links.rst │ ├── models.rst │ ├── netconf.rst │ ├── nowdays.rst │ ├── restconf.rst │ └── snmp.rst │ ├── 6_interfaces │ ├── callhome.rst │ ├── cli.rst │ ├── conclusion.rst │ ├── grpc.rst │ ├── index.rst │ ├── links.rst │ ├── materials │ │ ├── dumps │ │ │ └── grpc.pcap │ │ ├── grpc-ping │ │ │ ├── go-server │ │ │ │ ├── go.mod │ │ │ │ ├── go.sum │ │ │ │ ├── ping-server │ │ │ │ │ └── main.go │ │ │ │ └── ping │ │ │ │ │ ├── ping.pb.go │ │ │ │ │ └── ping_grpc.pb.go │ │ │ ├── protos │ │ │ │ └── ping.proto │ │ │ ├── python-client │ │ │ │ ├── ping_client.py │ │ │ │ ├── ping_pb2.py │ │ │ │ └── ping_pb2_grpc.py │ │ │ └── python-server │ │ │ │ ├── ping_pb2.py │ │ │ │ ├── ping_pb2_grpc.py │ │ │ │ └── ping_server.py │ │ └── scripts │ │ │ ├── gnmiclient_capabilities.py │ │ │ ├── gnmiclient_get_addresses.py │ │ │ ├── gnmiclient_set_bgp.py │ │ │ ├── gnmiclient_set_hostname.py │ │ │ ├── netconf_edit_config.py │ │ │ ├── netconfg_get_config.py │ │ │ ├── oc_interfaces.py │ │ │ ├── pyangbind_gnmiclient_set.py │ │ │ └── scrapli_get_config.py │ ├── model_driven.rst │ ├── models.rst │ ├── netconf.rst │ ├── netconf_again.rst │ ├── onemoretime.rst │ ├── restconf.rst │ ├── rpc.rst │ ├── xml.rst │ └── yang.rst │ ├── conf.py │ ├── contents.rst │ └── index.rst └── x.-ztp └── 0.-ztp.md /2.-dizain-seti/target_configs/bcn-host-0.cfg: -------------------------------------------------------------------------------- 1 | hostname bcn-host-0 2 | ! 3 | boot-start-marker 4 | boot-end-marker 5 | ! 6 | ! 7 | ! 8 | no aaa new-model 9 | clock timezone EET 2 0 10 | mmi polling-interval 60 11 | no mmi auto-configure 12 | no mmi pvc 13 | mmi snmp-timeout 180 14 | ! 15 | ! 16 | ! 17 | ! 18 | ! 19 | ! 20 | ! 21 | ! 22 | 23 | 24 | ! 25 | ! 26 | ! 27 | ! 28 | ip cef 29 | no ipv6 cef 30 | ! 31 | multilink bundle-name authenticated 32 | ! 33 | ! 34 | ! 35 | ! 36 | ! 37 | ! 38 | ! 39 | ! 40 | ! 41 | redundancy 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | ! 49 | ! 50 | ! 51 | ! 52 | ! 53 | ! 54 | ! 55 | ! 56 | ! 57 | interface Ethernet0/0 58 | ip address 10.0.128.66 255.255.255.192 59 | ! 60 | interface Ethernet0/1 61 | no ip address 62 | shutdown 63 | ! 64 | interface Ethernet0/2 65 | no ip address 66 | shutdown 67 | ! 68 | interface Ethernet0/3 69 | no ip address 70 | shutdown 71 | ! 72 | ip forward-protocol nd 73 | ! 74 | ! 75 | no ip http server 76 | no ip http secure-server 77 | ip route 0.0.0.0 0.0.0.0 10.0.128.65 78 | ! 79 | ! 80 | ! 81 | ! 82 | control-plane 83 | ! 84 | ! 85 | ! 86 | ! 87 | ! 88 | ! 89 | ! 90 | ! 91 | line con 0 92 | logging synchronous 93 | line aux 0 94 | line vty 0 4 95 | login 96 | transport input none 97 | ! 98 | ! 99 | end -------------------------------------------------------------------------------- /2.-dizain-seti/target_configs/bcn-leaf-1.cfg: -------------------------------------------------------------------------------- 1 | hostname bcn-leaf-1 2 | ! 3 | spanning-tree mode mstp 4 | ! 5 | no aaa root 6 | ! 7 | vlan 127 8 | ! 9 | interface Ethernet1 10 | no switchport 11 | ip address 169.254.0.2/31 12 | ! 13 | interface Ethernet2 14 | no switchport 15 | ip address 169.254.1.2/31 16 | ! 17 | interface Ethernet3 18 | ! 19 | interface Ethernet4 20 | switchport access vlan 127 21 | ! 22 | interface Ethernet5 23 | ! 24 | interface Ethernet6 25 | ! 26 | interface Ethernet7 27 | ! 28 | interface Ethernet8 29 | ! 30 | interface Ethernet9 31 | ! 32 | interface Management1 33 | ip address 192.168.1.12/24 34 | ! 35 | interface Vlan127 36 | ip address 10.0.128.65/26 37 | ! 38 | ip routing 39 | ! 40 | ip community-list standard NO_REANNOUNCE permit 65535:999 41 | ! 42 | route-map EXPORT_TO_SPINES deny 5 43 | description NO_REANNOUNCE 44 | match community NO_REANNOUNCE 45 | ! 46 | route-map EXPORT_TO_SPINES permit 10 47 | description ALLOW 48 | ! 49 | route-map IMPORT_FROM_SPINES permit 5 50 | description ALLOW 51 | set community 65535:999 52 | ! 53 | route-map IMPORT_UNDERLAY permit 5 54 | match interface Vlan127 55 | ! 56 | router bgp 4228186112 57 | neighbor SPINES peer-group 58 | neighbor SPINES remote-as 64517 59 | neighbor SPINES route-map IMPORT_FROM_SPINES in 60 | neighbor SPINES route-map EXPORT_TO_SPINES out 61 | neighbor SPINES maximum-routes 12000 62 | neighbor 169.254.0.3 peer-group SPINES 63 | neighbor 169.254.1.3 peer-group SPINES 64 | redistribute connected route-map IMPORT_UNDERLAY 65 | ! 66 | ! 67 | end -------------------------------------------------------------------------------- /2.-dizain-seti/target_configs/bcn-spine-1.cfg: -------------------------------------------------------------------------------- 1 | hostname bcn-spine-1 2 | ! 3 | spanning-tree mode mstp 4 | ! 5 | no aaa root 6 | ! 7 | interface Ethernet1 8 | ! 9 | interface Ethernet2 10 | no switchport 11 | ip address 169.254.1.3/31 12 | ! 13 | interface Ethernet3 14 | no switchport 15 | ip address 169.254.101.1/31 16 | ! 17 | interface Ethernet4 18 | ! 19 | interface Ethernet5 20 | ! 21 | interface Ethernet6 22 | ! 23 | interface Ethernet7 24 | ! 25 | interface Ethernet8 26 | ! 27 | interface Ethernet9 28 | ! 29 | interface Management1 30 | ip address 192.168.1.11/24 31 | ! 32 | ip routing 33 | ! 34 | route-map ALLOW permit 5 35 | ! 36 | route-map EXPORT deny 5 37 | description NO_DIRECT 38 | match source-protocol connected 39 | ! 40 | route-map EXPORT permit 10 41 | description ALLOW 42 | ! 43 | router bgp 64517 44 | neighbor EDGES peer-group 45 | neighbor EDGES remote-as 65535 46 | neighbor EDGES route-map ALLOW in 47 | neighbor EDGES route-map EXPORT out 48 | neighbor EDGES maximum-routes 12000 49 | neighbor LEAFS peer-group 50 | neighbor LEAFS route-map ALLOW in 51 | neighbor LEAFS route-map EXPORT out 52 | neighbor LEAFS maximum-routes 12000 53 | neighbor 169.254.1.2 peer-group LEAFS 54 | neighbor 169.254.1.2 remote-as 4228186112 55 | neighbor 169.254.101.0 peer-group EDGES 56 | ! 57 | ! 58 | end -------------------------------------------------------------------------------- /2.-dizain-seti/target_configs/kzn-host-0.cfg: -------------------------------------------------------------------------------- 1 | hostname kzn-host-0 2 | ! 3 | boot-start-marker 4 | boot-end-marker 5 | ! 6 | ! 7 | ! 8 | no aaa new-model 9 | clock timezone EET 2 0 10 | mmi polling-interval 60 11 | no mmi auto-configure 12 | no mmi pvc 13 | mmi snmp-timeout 180 14 | ! 15 | ! 16 | ! 17 | ! 18 | ! 19 | ! 20 | ! 21 | ! 22 | 23 | 24 | ! 25 | ! 26 | ! 27 | ! 28 | ip cef 29 | no ipv6 cef 30 | ! 31 | multilink bundle-name authenticated 32 | ! 33 | ! 34 | ! 35 | ! 36 | ! 37 | ! 38 | ! 39 | ! 40 | ! 41 | redundancy 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | ! 49 | ! 50 | ! 51 | ! 52 | ! 53 | ! 54 | ! 55 | ! 56 | ! 57 | interface Ethernet0/0 58 | ip address 10.0.32.2 255.255.255.0 59 | ! 60 | interface Ethernet0/1 61 | no ip address 62 | shutdown 63 | ! 64 | interface Ethernet0/2 65 | no ip address 66 | shutdown 67 | ! 68 | interface Ethernet0/3 69 | no ip address 70 | shutdown 71 | ! 72 | ip forward-protocol nd 73 | ! 74 | ! 75 | no ip http server 76 | no ip http secure-server 77 | ip route 0.0.0.0 0.0.0.0 10.0.32.1 78 | ! 79 | ! 80 | ! 81 | ! 82 | control-plane 83 | ! 84 | ! 85 | ! 86 | ! 87 | ! 88 | ! 89 | ! 90 | ! 91 | line con 0 92 | logging synchronous 93 | line aux 0 94 | line vty 0 4 95 | login 96 | transport input none 97 | ! 98 | ! 99 | end -------------------------------------------------------------------------------- /2.-dizain-seti/target_configs/kzn-spine-1.cfg: -------------------------------------------------------------------------------- 1 | hostname kzn-spine-1 2 | ! 3 | spanning-tree mode mstp 4 | ! 5 | no aaa root 6 | ! 7 | interface Ethernet1 8 | no switchport 9 | ip address 169.254.1.1/31 10 | ! 11 | interface Ethernet2 12 | ! 13 | interface Ethernet3 14 | no switchport 15 | ip address 169.254.101.1/31 16 | ! 17 | interface Ethernet4 18 | ! 19 | interface Ethernet5 20 | ! 21 | interface Ethernet6 22 | ! 23 | interface Ethernet7 24 | ! 25 | interface Ethernet8 26 | ! 27 | interface Ethernet9 28 | ! 29 | interface Management1 30 | ip address 192.168.1.3/24 31 | ! 32 | ip routing 33 | ! 34 | route-map ALLOW permit 5 35 | ! 36 | route-map EXPORT deny 5 37 | description NO_DIRECT 38 | match source-protocol connected 39 | ! 40 | route-map EXPORT permit 10 41 | description ALLOW 42 | ! 43 | router bgp 64513 44 | neighbor EDGES peer-group 45 | neighbor EDGES remote-as 65535 46 | neighbor EDGES route-map ALLOW in 47 | neighbor EDGES route-map EXPORT out 48 | neighbor EDGES maximum-routes 12000 49 | neighbor LEAFS peer-group 50 | neighbor LEAFS route-map ALLOW in 51 | neighbor LEAFS route-map EXPORT out 52 | neighbor LEAFS maximum-routes 12000 53 | neighbor 169.254.1.0 peer-group LEAFS 54 | neighbor 169.254.1.0 remote-as 4227923968 55 | neighbor 169.254.101.0 peer-group EDGES 56 | ! 57 | ! 58 | end -------------------------------------------------------------------------------- /2.-dizain-seti/target_configs/mgmt-switch.cfg: -------------------------------------------------------------------------------- 1 | hostname mgmt-switch 2 | ! 3 | boot-start-marker 4 | boot-end-marker 5 | ! 6 | ! 7 | ! 8 | no aaa new-model 9 | ! 10 | ! 11 | ! 12 | ! 13 | ! 14 | ! 15 | ! 16 | ! 17 | ip cef 18 | no ipv6 cef 19 | ! 20 | ! 21 | ! 22 | spanning-tree mode rapid-pvst 23 | spanning-tree extend system-id 24 | ! 25 | vlan internal allocation policy ascending 26 | ! 27 | ! 28 | ! 29 | ! 30 | ! 31 | ! 32 | ! 33 | ! 34 | ! 35 | ! 36 | ! 37 | ! 38 | ! 39 | ! 40 | interface GigabitEthernet0/0 41 | media-type rj45 42 | negotiation auto 43 | ! 44 | interface GigabitEthernet0/1 45 | media-type rj45 46 | negotiation auto 47 | ! 48 | interface GigabitEthernet0/2 49 | media-type rj45 50 | negotiation auto 51 | ! 52 | interface GigabitEthernet0/3 53 | media-type rj45 54 | negotiation auto 55 | ! 56 | interface GigabitEthernet1/0 57 | media-type rj45 58 | negotiation auto 59 | ! 60 | interface GigabitEthernet1/1 61 | media-type rj45 62 | negotiation auto 63 | ! 64 | interface GigabitEthernet1/2 65 | media-type rj45 66 | negotiation auto 67 | ! 68 | interface GigabitEthernet1/3 69 | media-type rj45 70 | negotiation auto 71 | ! 72 | interface GigabitEthernet2/0 73 | media-type rj45 74 | negotiation auto 75 | ! 76 | interface GigabitEthernet2/1 77 | media-type rj45 78 | negotiation auto 79 | ! 80 | interface GigabitEthernet2/2 81 | media-type rj45 82 | negotiation auto 83 | ! 84 | interface GigabitEthernet2/3 85 | media-type rj45 86 | negotiation auto 87 | ! 88 | interface GigabitEthernet3/0 89 | media-type rj45 90 | negotiation auto 91 | ! 92 | interface GigabitEthernet3/1 93 | media-type rj45 94 | negotiation auto 95 | ! 96 | interface GigabitEthernet3/2 97 | media-type rj45 98 | negotiation auto 99 | ! 100 | interface GigabitEthernet3/3 101 | media-type rj45 102 | negotiation auto 103 | ! 104 | interface Vlan1 105 | ip address 192.168.1.1 255.255.255.0 106 | ! 107 | ip forward-protocol nd 108 | ! 109 | no ip http server 110 | no ip http secure-server 111 | ! 112 | ! 113 | ! 114 | ! 115 | ! 116 | ! 117 | control-plane 118 | ! 119 | line con 0 120 | line aux 0 121 | line vty 0 4 122 | login 123 | ! 124 | ! 125 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ADSM 2 | Автоматизация Для Самых Маленьких 3 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | * Дописать то, что есть 2 | * Написать про систему описания HLD/сервисов 3 | * Написать про генерацию vendor-agnostic конфигурации 4 | * Написать про генерацию vendor-specific конфигурации и методы доставки до железа -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = source 8 | BUILDDIR = build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/0_goals/goals.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/0_goals/goals.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/0_goals/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/0_goals/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/0_goals/monitoring.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/0_goals/monitoring.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/0_goals/network_as_a_being.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/0_goals/network_as_a_being.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/0_goals/testing.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/0_goals/testing.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/0_goals/versioning.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/0_goals/versioning.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/1_tools/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/1_tools/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/2_conclusion/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/2_conclusion/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/conclusion.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/conclusion.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/goals.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/goals.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/planning.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/planning.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/0_planning/tools.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/0_planning/tools.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtual_network/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtual_network/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/0_virtual_network/conclusion.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/0_virtual_network/conclusion.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/0_virtual_network/faq.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/0_virtual_network/faq.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/0_virtual_network/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/0_virtual_network/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/0_virtual_network/motivation.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/0_virtual_network/motivation.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/0_virtual_network/overlay.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/0_virtual_network/overlay.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/0_virtual_network/terminology.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/0_virtual_network/terminology.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/0_virtual_network/underlay.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/0_virtual_network/underlay.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/1_virtualization_basics/conclusion.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/1_virtualization_basics/conclusion.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/1_virtualization_basics/history.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/1_virtualization_basics/history.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/1_virtualization_basics/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/1_virtualization_basics/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/1_virtualization_basics/resource_types.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/1_virtualization_basics/resource_types.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/1_virtualization_basics/tools.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/1_virtualization_basics/tools.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/1_virtualization_basics/vitual_switching.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/1_virtualization_basics/vitual_switching.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/1_virtualization/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/1_virtualization/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/2_network_design/conclusion.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/2_network_design/conclusion.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/2_network_design/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/2_network_design/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/2_network_design/ip_plan.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/2_network_design/ip_plan.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/2_network_design/lab.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/2_network_design/lab.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/2_network_design/routing.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/2_network_design/routing.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/2_network_design/topology.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/2_network_design/topology.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/architecture.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/architecture.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/conclusion.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/conclusion.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/installation.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/installation.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/postgresql.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/postgresql.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/conclusion.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/conclusion.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/installation.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/installation.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/messages.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/messages.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/methods.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/methods.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/other.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/other.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/postgresql.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/postgresql.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/rest.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/rest.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/scheme.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/scheme.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/restful/ways.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/restful/ways.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/3_ipam_dcim/scheme.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/3_ipam_dcim/scheme.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/4_lifecycle/architecture.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/4_lifecycle/architecture.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/4_lifecycle/conclusion.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/4_lifecycle/conclusion.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/4_lifecycle/iac.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/4_lifecycle/iac.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/4_lifecycle/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/4_lifecycle/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/4_lifecycle/lifecycle.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/4_lifecycle/lifecycle.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/4_lifecycle/links.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/4_lifecycle/links.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/4_lifecycle/scenarios.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/4_lifecycle/scenarios.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/api_rpc.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/api_rpc.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/cli.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/cli.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/conclusion.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/conclusion.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/future.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/future.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/grpc.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/grpc.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/horizon.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/horizon.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/links.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/links.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/models.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/models.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/netconf.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/netconf.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/nowdays.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/nowdays.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/restconf.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/restconf.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/5_history/snmp.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/5_history/snmp.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/callhome.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/callhome.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/cli.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/cli.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/conclusion.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/conclusion.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/grpc.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/grpc.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/links.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/links.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/model_driven.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/model_driven.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/models.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/models.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/netconf.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/netconf.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/netconf_again.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/netconf_again.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/onemoretime.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/onemoretime.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/restconf.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/restconf.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/rpc.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/rpc.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/xml.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/xml.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/6_interfaces/yang.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/6_interfaces/yang.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/contents.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/contents.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/index_back.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/doctrees/index_back.doctree -------------------------------------------------------------------------------- /docs/build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: fe30ac37dbfb1ca1816c14bb8a5bf24f 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/build/html/_sources/0_planning/0_goals/monitoring.rst.txt: -------------------------------------------------------------------------------- 1 | Мониторинг и самовосстановление сервисов 2 | ======================================== -------------------------------------------------------------------------------- /docs/build/html/_sources/0_planning/0_goals/network_as_a_being.rst.txt: -------------------------------------------------------------------------------- 1 | Сеть — как единый организм 2 | ========================== -------------------------------------------------------------------------------- /docs/build/html/_sources/0_planning/0_goals/testing.rst.txt: -------------------------------------------------------------------------------- 1 | Тестирование конфигурации 2 | ========================= -------------------------------------------------------------------------------- /docs/build/html/_sources/0_planning/0_goals/versioning.rst.txt: -------------------------------------------------------------------------------- 1 | Версионирование 2 | =============== -------------------------------------------------------------------------------- /docs/build/html/_sources/0_planning/1_tools/index.rst.txt: -------------------------------------------------------------------------------- 1 | Средства 2 | ======== 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Содержание: 7 | 8 | -------------------------------------------------------------------------------- /docs/build/html/_sources/0_planning/2_conclusion/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. ADSM documentation master file, created by 2 | sphinx-quickstart on Sun May 26 17:18:39 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to ADSM's documentation! 7 | ================================ 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | -------------------------------------------------------------------------------- /docs/build/html/_sources/0_planning/conclusion.rst.txt: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | | В качестве основы я выбрал один из современных дизайнов датацентровой сети - L3 Clos Fabric с BGP в качестве протокола маршрутизации. 5 | | Строить сеть мы будем на этот раз на Juniper, потому что теперь интерфейс JunOs - это ванлав. 6 | 7 | Усложним себе жизнь использованием только Open Source инструментов и мультивендорной сетью - поэтому кроме джунипер по ходу дела выберу ещё одного счастливчика. 8 | 9 | | План ближайших публикаций примерно такой: 10 | | Сначала я расскажу про виртуальные сети. В первую очередь, потому что мне хочется, а во вторую, потому что без этого дизайн инфраструктурной сети будет не очень понятен. 11 | | Потом собственно про дизайн сети: топологию, маршрутизацию, политики. 12 | | Соберём лабораторный стенд. 13 | | Поразмышляем и, может, попрактикуемся в инициализации устройства в сети. 14 | | А дальше про каждый компонент в интимных подробностях. 15 | 16 | 17 | И да, я не обещаю изящно закончить этот цикл готовым решением. :) 18 | 19 | Полезные ссылки 20 | ~~~~~~~~~~~~~~~ 21 | 22 | * Перед тем, как углубляться в серию, стоит почитать книгу Наташи Самойленко `Python для сетевых инженеров `_. А, возможно, и пройти `курс `_. 23 | * Полезным будет также почитать `RFC `_ про дизайн датацентровых фабрик от Фейсбука за авторством Петра Лапухова. 24 | * О том, как работает Overlay'ный SDN вам даст представление документация по архитектуре `Tungsten Fabric `_. 25 | 26 | 27 | Спасибы 28 | ~~~~~~~ 29 | 30 | * Роман Горге. За комментарии и правки. 31 | * Артём Чернобай. За КДПВ. 32 | -------------------------------------------------------------------------------- /docs/build/html/_sources/0_planning/index.rst.txt: -------------------------------------------------------------------------------- 1 | Часть 0. Планирование 2 | ===================== 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Содержание: 7 | 8 | 0_goals/index.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/0_planning/planning.rst.txt: -------------------------------------------------------------------------------- 1 | Часть 0. Планирование 2 | ===================== 3 | 4 | СДСМ закончился, а бесконтрольное желание писать - осталось. 5 | 6 | .. figure:: https://fs.linkmeup.ru/images/adsm/0/kdpv.jpg 7 | :width: 800 8 | :align: center 9 | 10 | | Долгие годы наш брат страдал от выполнения рутинной работы, скрещивал пальцы перед коммитом и недосыпал из-за ночных ролбэков. 11 | | Но тёмным временам приходит конец. 12 | 13 | | Этой статьёй я начну серию о том, как *мне* видится автоматизация. 14 | | По ходу дела разберёмся с этапами автоматизации, хранением переменных, формализацией дизайна, с RestAPI, NETCONF, YANG, YDK и будем очень много программировать. 15 | | *Мне* означает, что а) это не объективная истина, б) не безоговорочно лучший подход в) мой взгляд даже в ходе движения от первой к последней статье может поменяться - честно говоря, от стадии черновика до публикации я переписывал всё полностью дважды. 16 | 17 | 18 | АДСМ я попробую вести в формате, немного отличном от СДСМ. По-прежнему будут появляться большие обстоятельные номерные статьи, а между ними я буду публиковать небольшие заметки из повседневного опыта. Постараюсь тут бороться с перфекционизмом и не вылизывать каждую из них. 19 | 20 | | Как это забавно, что во второй раз приходится проходить один и тот же путь. 21 | | Сначала пришлось писать самому статьи про сети из-за того, что их не было в рунете. 22 | | Теперь я не смог найти всесторонний документ, который систематизировал бы подходы к автоматизации и на простых практических примерах разбирал вышеперечисленные технологии. 23 | 24 | Возможно, я ошибаюсь, поэтому, кидайте ссылки на годные ресурсы. Впрочем это не изменит моей решимости писать, потому что, основная цель - это всё-таки научиться чему-то самому, а облегчить жизнь ближнему - это приятный бонус, который ласкает ген распространения опыта. 25 | 26 | | Мы попробуем взять средних размеров дата-центр LAN DC и проработать всю схему автоматизации. 27 | | Делать некоторые вещи я буду практически впервые вместе с вами. 28 | 29 | В описываемых тут идеях и инструментах я буду не оригинален. У Дмитрия Фиголя есть отличный `канал со стримами на эту тему `_. 30 | 31 | Статьи во многих аспектах будут с ними пересекаться. 32 | 33 | | В LAN DC 4 ДЦ, около 250 коммутаторов, полдюжины маршрутизаторов и пара файрволов. 34 | | Не фейсбук, но достаточно для того, чтобы глубоко задуматься об автоматизации. 35 | | Бытует, впрочем, мнение, что если у вас больше 1 устройства, уже нужна автоматизация. 36 | | На самом деле тяжело представить, что кто-то сейчас может жить без хотя бы пачки наколеночных скриптов. 37 | | Хотя я слышал, что есть такие конторы, где учёт IP-адресов ведётся в экселе, а каждое из тысяч сетевых устройств настраивается вручную и имеет свою неповторимую конфигурацию. Это, конечно, можно выдать за современное искусство, но чувства инженера точно будут оскорблены. 38 | 39 | 40 | 41 | .. toctree:: 42 | :maxdepth: 2 43 | :caption: Содержание: 44 | 45 | goals.rst 46 | tools.rst 47 | conclusion.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/1_virtual_network/index.rst.txt: -------------------------------------------------------------------------------- 1 | Часть 1. Виртуальная сеть 2 | ========================= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Содержание: 7 | 8 | ../0_goals/index.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/1_virtualization/0_virtual_network/faq.rst.txt: -------------------------------------------------------------------------------- 1 | FAQ 2 | === 3 | 4 | 5 | **Зачем ты всё время делаешь ремарку GRE/UDP?** 6 | 7 | | Ну, вообще, это, можно сказать, специфично для Tungsten Fabric - можно вообще не брать во-внимание. 8 | | Но если брать, то сам TF, ещё будучи OpenContrail'ом поддерживал обе инкапсуляции: MPLS in GRE и MPLS in UDP. 9 | | UDP хорош тем, что в Source Port в его заголовке очень легко закодировать хэш-функцию от изначальных IP+Proto+Port, что позволит делать балансировку. 10 | | В случае GRE, увы, есть только внешние заголовки IP и GRE, которые одинаковы для всего инкапсулированного трафика и речь о балансировке не идёт - мало кто может заглянуть так глубоко внутрь пакета. 11 | 12 | До некоторого времени маршрутизаторы, если и умели в динамические туннели, то только в MPLSoGRE, и только совсем недавно, научились в MPLSoUDP. Поэтому приходится делать всегда ремарку о возможности двух разных инкапсуляций. 13 | 14 | Справедливости ради, стоит отметить, что TF вполне поддерживает и L2-связность с помощью VXLAN. 15 | 16 | **Ты обещал провести параллели с OpenFlow.** 17 | 18 | | Они и правда напрашиваются. vSwitch в том же OpenStack'е делает весьма похожие вещи, используя VXLAN, у которого, кстати, тоже UDP-заголовок. 19 | | В Data Plane они работают примерно одинаково, существенно различается Control Plane. Tungsten Fabric использует XMPP для доставки информации о маршрутах на vRouter, в то время, как в OpenStack'е работает Openflow. 20 | 21 | **А можно чуть больше про vRouter?** 22 | 23 | | Он делится на две части: vRouter Agent и vRouter Forwarder. 24 | | Первый запускается в User Space хостовой ОС и общается с SDN-контроллером, обмениваясь информацией о маршрутах, VRF и ACL. 25 | | Второй реализует Data Plane - обычно в Kernel Space, но может запускаться и на SmartNIC'ах - сетевых картах с CPU и отдельным программируемым чипом коммутации, что позволяет снять нагрузку с CPU хостовой машины, а сеть сделать быстрее и более предсказуемой. 26 | | Ещё возможен сценарий, когда vRouter - это DPDK-приложение в User Space. 27 | 28 | vRouter Agent спускает настройки на vRouter Forwarder. 29 | 30 | **Что за Virtual Network?** 31 | 32 | | Я обмолвился в начале статьи о VRF, что мол каждый тенант привязывается к своему VRF. И если для поверхностного понимания работы оверлейной сети этого было достаточно, то уже на следующей итерации надо делать уточнения. 33 | | Обычно в механизмах виртуализации сущность Virtual Network (можно считать это именем собственным) вводится отдельно от клиентов/тенантов/виртуальных машин - вполне себе самостоятельная вещь. А этот Virtual Network через интерфейсы уже можно подключить в один тенант, в другой, в два, да хоть куда. Так, например, реализуется Service Chaining, когда трафик нужно пропустить через определённые ноды в нужной последовательности, просто в правильной последовательности создавая и привзявая Virtual Network'и. 34 | | Поэтому как такового прямого соответствия между Virtual Network и тенантом нет. 35 | -------------------------------------------------------------------------------- /docs/build/html/_sources/1_virtualization/0_virtual_network/index.rst.txt: -------------------------------------------------------------------------------- 1 | Виртуализация сети 2 | ================== 3 | 4 | В `предыдущем выпуске `_ я описал фреймворк сетевой автоматизации. По отзывам у некоторых людей даже этот первый подход к проблеме уже разложил некоторые вопросы по полочкам. И это очень меня радует, потому что наша цель в цикле - не обмазать питоновскими скриптами анзибль, а выстроить систему. 5 | 6 | Этот же фреймворк задаёт порядок, в котором мы будем разбираться с вопросом. 7 | И виртуализация сети, которой посвящён этот выпуск, не особо укладывается в тематику АДСМ, где мы разбираем автоматику. 8 | 9 | Но давайте взглянем на неё под другим углом. 10 | Уже давно одной сетью пользуются многие сервисы. В случае оператора связи это 2G, 3G, LTE, ШПД и B2B, например. В случае ДЦ: связность для разных клиентов, Интернет, блочное хранилище, объектное хранилище. 11 | И все сервисы требуют изоляции друг от друга. Так появились оверлейные сети. 12 | И все сервисы не хотят ждать, когда человек настроит их вручную. Так появились оркестраторы и SDN. 13 | 14 | Первый подход к систематической автоматизации сети, точнее её части, давно предпринят и много где внедрён в жизнь: VMWare, OpenStack, Google Compute Cloud, AWS, Facebook. 15 | 16 | Вот с ним сегодня и поразбираемся. 17 | 18 | .. figure:: https://fs.linkmeup.ru/images/adsm/1/kdpv.jpg 19 | :width: 800 px 20 | :align: center 21 | 22 | 23 | .. toctree:: 24 | :maxdepth: 2 25 | :caption: Содержание: 26 | 27 | motivation.rst 28 | terminology.rst 29 | underlay.rst 30 | overlay.rst 31 | faq.rst 32 | conclusion.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/1_virtualization/0_virtual_network/motivation.rst.txt: -------------------------------------------------------------------------------- 1 | Причины 2 | ======= 3 | 4 | И раз уж мы об этом заговорили, то стоит упомянуть предпосылки к виртуализации сети. На самом деле этот процесс начался не вчера. 5 | 6 | Наверно, вы не раз слышали, что сеть всегда была самой инертной частью любой системы. И это правда во всех смыслах. Сеть - это базис, на который опирается всё, и производить изменения на ней довольно сложно - сервисы не терпят, когда сеть лежит. Зачастую вывод из эксплуатации одного узла может сложить большую часть приложений и повлиять на много клиентов. Отчасти поэтому сетевая команда может сопротивляться любым изменениям - потому что сейчас оно как-то работает (*мы, возможно, даже не знаем как*), а тут надо что-то новое настроить, и неизвестно как оно повлияет на сеть. 7 | 8 | Чтобы не ждать, когда сетевики прокинут VLAN и любые сервисы не прописывать на каждом узле сети, люди придумали использовать оверлеи - наложенные сети - коих великое многообразие: GRE, IPinIP, MPLS, MPLS L2/L3VPN, VXLAN, GENEVE, MPLSoverUDP, MPLSoverGRE итд. 9 | 10 | Их привлекательность заключается в двух простых вещах: 11 | 12 | * Настраиваются только конечные узлы - транзитные трогать не приходится. Это значительно ускоряет процесс, а иногда вообще позволяет исключить отдел сетевой инфраструктуры из процесса ввода новых сервисов. 13 | * Нагрузка сокрыта глубоко внутри заголовков - транзитным узлам не нужно ничего знать о ней, об адресации на хостах, маршрутах наложенной сети. А это значит, нужно хранить меньше информации в таблицах, значит взять попроще/подешевле устройство. 14 | 15 | В этом не совсем полноценном выпуске я не планирую разбирать все возможные технологии, а скорее описать фреймворк работы оверлейных сетей в ДЦ. 16 | 17 | Вся серия будет описывать датацентр, состоящий из рядов однотипных стоек, в которых установлено одинаковое серверное оборудование. 18 | На этом оборудовании запускаются виртуальные машины/контейнеры/серверлесс, реализующие сервисы. 19 | 20 | 21 | .. figure:: https://fs.linkmeup.ru/images/adsm/1/dc.jpg 22 | :width: 800 px 23 | :align: center 24 | 25 | -------------------------------------------------------------------------------- /docs/build/html/_sources/1_virtualization/0_virtual_network/underlay.rst.txt: -------------------------------------------------------------------------------- 1 | Underlay 2 | ======== 3 | 4 | Underlay - это физическая сеть: аппаратные коммутаторы и кабели. Устройства в андерлее знают, как добраться до физических машин. 5 | 6 | .. figure:: https://fs.linkmeup.ru/images/adsm/1/underlay.png 7 | :width: 800 px 8 | :align: center 9 | 10 | Опирается он на стандартные протоколы и технологии. Не в последнюю очередь потому, что аппаратные устройства по сей день работают на проприетарном ПО, не допускающем ни программирование чипа, ни реализацию своих протоколов, соответственно, нужна совместимость с другими вендорами и стандартизация. 11 | 12 | А вот кто-нибудь вроде Гугла может себе позволить разработку собственных коммутаторов и отказ от общепринятых протоколов. Но LAN_DC не Гугл. 13 | 14 | Underlay сравнительно редко меняется, потому что его задача - базовая IP-связность между физическими машинами. Underlay ничего не знает о запущенных поверх него сервисах, клиентах, тенантах - ему нужно только доставить пакет от одной машины до другой. 15 | Underlay может быть например таким: 16 | 17 | * IPv4+OSPF 18 | * IPv6+ISIS+BGP+L3VPN 19 | * IP+EBGP 20 | * L2+TRILL 21 | * L2+STP 22 | 23 | Настраивается Underlay'ная сеть классическим образом: CLI/GUI/NETCONF. 24 | Вручную, скриптами, проприетарными утилитами. 25 | 26 | Более подробно андерлею будет посвящена следующая статья цикла. 27 | 28 | -------------------------------------------------------------------------------- /docs/build/html/_sources/1_virtualization/1_virtualization_basics/conclusion.rst.txt: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | В данной статье мы рассмотрели минимальный набор теоретических знаний, который необходим для работы с виртуальными машинами. Я намеренно не приводил практических примеров и выводов команд, поскольку таких примеров можно найти сколько угодно в Сети, и я не ставил перед собой задачу написать "step-by-step guide". Если вас заинтересовала какая-то конкретная тема или технология, оставляйте свои комментарии и пишите вопросы. 5 | 6 | Полезные ссылки 7 | --------------- 8 | 9 | * `Understanding QEMU Devices `_ 10 | * `KVM/SR-IOV `_ 11 | 12 | Спасибы 13 | ------- 14 | 15 | * `Александру Шалимову `_ - моему коллеге и эксперту в области разработки виртуальных сетей. За комментарии и правки. 16 | * Евгению Яковлеву - моему коллеге и эксперту в области виртуализации за комментарии и правки. 17 | -------------------------------------------------------------------------------- /docs/build/html/_sources/1_virtualization/1_virtualization_basics/index.rst.txt: -------------------------------------------------------------------------------- 1 | Основы виртуализации 2 | ==================== 3 | 4 | Автор этой статьи - `Роман Горге `_ - бывший ведущий linkmeup. 5 | 6 | `Предыдущая статья `_ рассматривала архитектуру виртуализированной сети, underlay-overlay, путь пакета между VM и прочее. В данной статье мы затронем (или попытаемся затронуть) вопросы а как собственно происходит виртуализация сетевых функций, как реализован backend основных продуктов, обеспечивающих запуск и управление VM, а также как работает виртуальный свитчинг (OVS и Linux bridge). 7 | 8 | Тема виртуализации широка и глубока, объяснить все детали работы гипервизора невозможно (да и не нужно). Мы ограничимся минимальным набором знаний необходимым для понимания работы любого виртуализированного решения, не обязательно Telco. 9 | 10 | .. figure:: https://fs.linkmeup.ru/images/adsm/1/1/kdpv.png 11 | :width: 800 12 | :align: center 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | :caption: Содержание: 17 | 18 | history.rst 19 | resource_types.rst 20 | vitual_switching.rst 21 | tools.rst 22 | conclusion.rst 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /docs/build/html/_sources/1_virtualization/index.rst.txt: -------------------------------------------------------------------------------- 1 | Часть 1. Виртуализация 2 | ====================== 3 | 4 | Эту часть мы разбили на две: 5 | 6 | * **Виртуализация сети**, которая рассказывает, как и зачем она появилась в виде SDN и NFV. И почему вообще мы рассматриваем её в серии статей про автоматизацию. 7 | 8 | * **Основы виртуализации**, которая охватывает более общие вопросы о виртуальных хранилищах, процессорах, памяти и сети. Автор этой части - `Роман Горге `_ - бывший ведущий подкаста linkmeup. 9 | 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | :caption: Виртуализация: 14 | 15 | 0_virtual_network/index.rst 16 | 1_virtualization_basics/index.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/2_network_design/conclusion.rst.txt: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | | Так же принято? Под каждой статьёй делать короткий вывод? 5 | | Итак мы выбрали `трёхуровневую `_ сеть Клоза внутри ДЦ, поскольку ожидаем много East-West трафика и хотим ECMP. 6 | | Разделили сеть на физическую (андерлей) и виртуальную (оверлей). При этом оверлей начинается с хоста - тем самым упростили требования к андерлею. 7 | | Выбрали BGP в качестве протокола маршрутизации анедрелейных сетей за его масштабируемость и гибкость политик. 8 | | У нас будут отдельные узлы для организации DCI - Edge-leaf. 9 | | На магистрали будет OSPF+LDP. 10 | | DCI будет реализован на основе MPLS L3VPN. 11 | | Для P2P-линков IP-адреса мы будем вычислять алгоритмически на основе имён устройств. 12 | | Лупбэки будем назначать по роли устройств и их расположению последовательно. 13 | | Андерлейные префиксы - только на Leaf-коммутаторы последовательно на основе их расположения. 14 | 15 | | Предположим, что прямо сейчас у нас ещё не установлено оборудование. 16 | | Поэтому наши следующие шаги будут - завести их в системах (IPAM, инвентарная), организовать доступ, сгенерировать конфигурацию и задеплоить её. 17 | 18 | В следующей статье разберёмся с Netbox - системой инвентаризации и управления IP-пространством в ДЦ. 19 | 20 | Спасибы 21 | ------- 22 | 23 | * Андрею Глазкову aka @glazgoo за вычитку и правки 24 | * Александру Клименко aka @v00lk за вычитку и правки 25 | * Артёму Чернобаю за КДПВ 26 | -------------------------------------------------------------------------------- /docs/build/html/_sources/2_network_design/index.rst.txt: -------------------------------------------------------------------------------- 1 | Часть 2. Дизайн сети 2 | ==================== 3 | 4 | В первых двух статьях я поднял вопрос автоматизации и набросал её фреймворк, во второй сделал отступление в виртуализацию сети, как первый подход к автоматизации настройки сервисов. 5 | А теперь пришло время нарисовать схему физической сети. 6 | 7 | Если вы не на короткой ноге с устройством сетей датацентров, то я настоятельно рекомендую начать со `статьи о них `_. 8 | 9 | 10 | Описанные в этой серии практики должны быть применимы к сети любого типа, любого масштаба с любым многообразием вендоров (нет). Однако нельзя описать универсальный пример применения этих подходов. Поэтому я остановлюсь на современной архитектуре сети ДЦ: `Фабрике Клоза `_. 11 | DCI сделаем на MPLS L3VPN. 12 | Поверх физической сети работает Overlay-сеть с хоста (это может быть VXLAN OpenStack'а или Tungsten Fabric или что угодно другое, что требует от сети только базовой IP-связности). 13 | 14 | .. figure:: https://fs.linkmeup.ru/images/adsm/2/kdpv_small.jpg 15 | :width: 800 16 | :align: center 17 | 18 | В этом случае получится сравнительно простой сценарий для автоматизации, потому что имеем много оборудования, настраивающегося одинаковым образом. 19 | Мы выберем сферический ДЦ в вакууме: 20 | 21 | * Одна версия дизайна везде 22 | * Два вендора, образующих две плоскости сети 23 | * Один ДЦ похож на другой как две капли воды 24 | 25 | Пусть наш Сервис-Провайдер LAN_DC будет, например, хостить обучающие видео о выживании в застрявших лифтах. 26 | В мегаполисах это пользуется бешенной популярностью, поэтому физических машин надо много. 27 | 28 | Сначала я опишу сеть приблизительно такой, какой бы её хотелось видеть. А потом упрощу для лабы. 29 | 30 | 31 | .. toctree:: 32 | :maxdepth: 2 33 | :caption: Дизайн сети: 34 | 35 | topology.rst 36 | routing.rst 37 | ip_plan.rst 38 | lab.rst 39 | conclusion.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/2_network_design/lab.rst.txt: -------------------------------------------------------------------------------- 1 | Лаба 2 | ==== 3 | 4 | Два вендора. Одна сеть. АДСМ. 5 | 6 | Juniper + Arista. Ubuntu. Старая добрая Ева. 7 | 8 | Количество ресурсов на нашей виртуалочке в Миране всё же ограничено, поэтому для практики мы будем использовать вот такую упрощённую до предела сеть. 9 | 10 | .. figure:: https://fs.linkmeup.ru/images/adsm/2/lab.png 11 | :width: 800 12 | :align: center 13 | 14 | * Два датацентра: Казань и Барселона. 15 | * По два спайна в каждом: Juniper и Arista. 16 | * По одному тору (Leaf'у) в каждом - Juniper и Arista, с одним подключенным хостом (возьмём легковесный Cisco IOL для этого). 17 | * По одной ноде Edge-Leaf (пока только Juniper). 18 | * One Cisco switch to rule them all. 19 | * Помимо сетевых коробок запущена виртуальная машина-управляка. Под управлением Ubuntu. 20 | Она имеет доступ ко всем устройствам, на ней будут крутиться IPAM/DCIM-системы, букет питоновских скриптов, анзибль и что угодно ещё, что нам может понадобиться. 21 | 22 | `Полная конфигурация `_ всех сетевых устройств, которую мы будем пробовать воспроизвести с помощью автоматики. -------------------------------------------------------------------------------- /docs/build/html/_sources/3_ipam_dcim/architecture.rst.txt: -------------------------------------------------------------------------------- 1 | Архитектура системы 2 | =================== 3 | 4 | * NetBox написан на Python3. Что хорошо, потому что ряд других решений написан на php и изменять их при необходимости не так уж просто. 5 | * Фреймворк для самого сайта - Django. 6 | * В качестве БД используется PostgreSQL. 7 | * WEB-frontend (HTTP-сревис) - NGINX - он проксирует запросы в Gunicron. 8 | * WSGI - Gunicorn - интерфейс между Nginx и самим приложением. 9 | * Фреймворк для документации по API - Swagger. 10 | * Чтобы демонизировать NetBox - Systemd. 11 | 12 | NetBox - проект молодой и быстро развивающийся. Например, в 2.7 отказались от supervisord и тянущегося за ним Python 2.7 в пользу systemd. Не так давно там не было ни кэширования, ни Webhooks. 13 | Поэтому меняется всё быстро и информация в статье может устареть к моменту чтения. 14 | 15 | Иными словами все компоненты зрелые и проверенные. 16 | 17 | По словам автора NetBox отражает не реальное состояние сети, а целевое. Поэтому ничего не подгружается в NetBox из сети - это сеть настраивается в соответствие с содержимым NetBox. 18 | Таким образом NetBox выступает единственным источником истины (калька с single source of truth). 19 | И изменения на сети должны быть инициированы изменениями в NetBox. 20 | А это очень неплохо ложится на идеологию, которую я исповедую в этой серии статей - хочешь сделать изменения на сети - сначала внеси их в системы. 21 | -------------------------------------------------------------------------------- /docs/build/html/_sources/3_ipam_dcim/conclusion.rst.txt: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | В этой статье я не преследовал цель рассмотреть все возможности NetBox, поэтому всё остальное отдаю вам на откуп. Разбирайтесь, пробуйте. 5 | 6 | Далее в рамках построения системы автоматизации я буду касаться только тех частей, которые нам действительно нужны. 7 | 8 | Итак, выше я коротко рассказал о том, что из себя представляет NetBox, и как в нём хранятся данные. 9 | Повторюсь, что почти все необходимые данные я туда уже внёс, и вы можете утащить себе `дамп БД `_ 10 | 11 | Всё готово к следующему этапу автоматизации: написанию системы (ахаха, просто скриптов) инициализации устройств и управления конфигурацией. 12 | 13 | Полезные ссылки 14 | --------------- 15 | 16 | * `Сам NetBox на github `_ 17 | * `Контейнерная версия `_ 18 | * `Полная инструкция по установке и вся документация по продукту `_ 19 | * `Documenting your network infrastructure in NetBox, integrating with Ansible over REST API `_ 20 | * `IPAM NetBox and its API, Docker, Postman `_ 21 | * `IPAM NetBox and its API, configuration templates with Python `_ 22 | * `SDK для работы с NetBox в Python `_ 23 | * `Документация по API `_ 24 | * `Mailing list `_ 25 | * `Канал в Slack NetworkToCode `_ 26 | * `Что такое REST `_ 27 | * `Инсталляция NetBox для нужд АДСМ `_ -------------------------------------------------------------------------------- /docs/build/html/_sources/3_ipam_dcim/installation.rst.txt: -------------------------------------------------------------------------------- 1 | Некоторые нюансы установки NetBox 2 | ================================= 3 | 4 | Я не буду описывать процесс инсталляции в деталях - он более чем классно описан в `официальной документации `_. 5 | 6 | Посмотреть на процесс запуска docker-образа NetBox и работу в GUI можно в видео Димы Фиголя (`раз `_ и `два `_) и `Эмиля Гарипова `_. 7 | 8 | | В целом, если следовать шагам установки/запуска неукоснительно, то всё получится. 9 | | Но вот какие есть нюансы, про которые случайно можно забыть. 10 | 11 | * | В файле configuration.py должен быть заполнен параметр `ALLOWED_HOSTS `_: 12 | 13 | .. code-block:: bash 14 | 15 | ALLOWED_HOSTS = ['netbox.linkmeup.ru', 'localhost'] 16 | 17 | | Тут нужно указать все возможные имена NetBox, к которым вы будете обращаться, например, может быть внешний IP-адрес или 127.0.0.1 или DNS-alias. 18 | | Если этого не будет сделано, сайт NetBox не откроется и будет показывать 400. 19 | 20 | * В этом же файле должен быть указан `SECRET_KEY `_, который можно выдумать самому или сгенерировать скриптом. 21 | * Главная страница будет показывать 502 Bad Gateway, если что-то не так с настройкой базы PostgreSQL: проверьте хост(если ставили на другую машину), порт, имя базы, имя пользователя, пароль. 22 | * | С `некоторых пор `_ NetBox по умолчанию не даёт никаких прав на чтение без авторизации. 23 | | Изменяется это всё в том же configuration.py: 24 | 25 | .. code-block:: bash 26 | 27 | EXEMPT_VIEW_PERMISSIONS = ['*'] 28 | 29 | * | А ещё API запросы будут возвращать 200 и не работать, если в API URL не будет слэша в конце. 30 | 31 | .. code-block:: bash 32 | 33 | curl -X GET "http://netbox.linkmeup.ru:45127/api/dcim/devices" -H "Accept: application/json; indent=4" 34 | -------------------------------------------------------------------------------- /docs/build/html/_sources/3_ipam_dcim/postgresql.rst.txt: -------------------------------------------------------------------------------- 1 | Немного о PostgreSQL 2 | ==================== 3 | 4 | Для подключения к серверу: 5 | 6 | .. code-block:: bash 7 | 8 | psql -U *username* -h *hostname* *db_name* 9 | 10 | Например: 11 | 12 | .. code-block:: bash 13 | 14 | psql -U netbox -h localhost netbox 15 | 16 | Для вывода всех таблиц: 17 | 18 | .. code-block:: bash 19 | 20 | /dt 21 | 22 | Для выхода: 23 | 24 | .. code-block:: bash 25 | 26 | /q 27 | 28 | Для дампа БД: 29 | 30 | .. code-block:: bash 31 | 32 | pg_dump -U *username* -h *hostname* *db_name* > netbox.sql 33 | 34 | Если не хочется каждый раз вводить пароль: 35 | 36 | .. code-block:: bash 37 | 38 | echo *:*:*:*username*:*password* > ~/.pgpass 39 | chmod 600 ~/.pgpass 40 | 41 | Если у вас есть своя инсталляция и не хочется вносить всё руками, можно просто сделать так, взяв дамп текущей БД NetBox `тут `_: 42 | 43 | .. code-block:: bash 44 | 45 | psql -U *username* -h *hostname* *db_name* < netbox_initial_db.sql 46 | 47 | Если предварительно нужно дропнуть все таблицы (а сделать это придётся), то можно подготовить заранее файл: 48 | 49 | .. code-block:: bash 50 | 51 | psql -U *username* -h *hostname* *db_name* 52 | \o drop_all_tables.sql 53 | select 'drop table ' || tablename || ' cascade;' from pg_tables; 54 | \q 55 | psql -U *username* -h *hostname* *db_name* -f drop_all_tables.sql -------------------------------------------------------------------------------- /docs/build/html/_sources/3_ipam_dcim/restful/conclusion.rst.txt: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | Не всё в том мире 2000-го года так уже радужно. REST по праву часто критикуют. 5 | Не являясь экспертом, не берусь предметно раскрывать вопрос, но дам ссылку на небесспорную `статью на хабре `_. 89 | 90 | 91 | Тело HTTP-сообщения 92 | ------------------- 93 | 94 | Тело используется для передачи собственно данных. 95 | В HTTP-ответе это может быть HTML-страничка, или в нашем случае JSON-объект. 96 | 97 | Между заголовками и телом должна быть как минимум одна пустая строка. 98 | 99 | При использовании метода GET в HTTP-запросе обычно никакого тела нет, потому что передавать нечего. Но тело есть в HTTP-ответе. 100 | А вот например, при POST уже и в запросе будет тело. Давайте о методах и поговорим теперь. 101 | -------------------------------------------------------------------------------- /docs/build/html/_sources/3_ipam_dcim/restful/other.rst.txt: -------------------------------------------------------------------------------- 1 | Критика RESTful API и альтернативы 2 | ================================== 3 | 4 | Существует и такая, да. Не всё в том мире 2000-го года так уже радужно. 5 | Не являясь экспертом, не берусь предметно раскрывать вопрос, но дам ссылку на небесспорную `статью на хабре `_, то теперь пришло время разобраться отдельными органами. 12 | 13 | .. figure:: https://fs.linkmeup.ru/images/adsm/4/kdpv.png 14 | :width: 900 15 | :align: center 16 | 17 | | В этой статье разберём жизненный цикл сетевого устройства и некоторые сценарии того, какие манипуляции с ним приходится порой делать. 18 | | Естественно, всё это интересует нас с точки зрения автоматизируемости. Поэтому ещё мы нарисуем архитектуру системы автоматизации. 19 | | Кстати, не так давно вышла просто восхихитительная `обзорная статья `_ Дмитрия Тесля о процессе и инструментах сетевой автоматизации. Он смог лаконично изложить то, вокруг чего я пляшу уже несколько выпусков АДСМ. Настоятельно рекомендую прочитать её перед тем, как преступать к этой. 20 | 21 | .. toctree:: 22 | :maxdepth: 2 23 | :caption: Содержание: 24 | 25 | lifecycle.rst 26 | iac.rst 27 | architecture.rst 28 | scenarios.rst 29 | links.rst 30 | conclusion.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/4_lifecycle/links.rst.txt: -------------------------------------------------------------------------------- 1 | Полезные ссылки 2 | =============== 3 | 4 | * `Awesome Network Automation `_ 5 | * `Статья Network Automation 101 от Дмитрия Тесля `_ 6 | * `Hands-on with NetDevOps `_ 7 | * `Scaling the Facebook backbone through Zero Touch Provisioning (ZTP) `_ 8 | -------------------------------------------------------------------------------- /docs/build/html/_sources/5_history/conclusion.rst.txt: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | | Конечно, я очень размазал последнюю часть, непонятно как это сделать, непонятно даже что я имел в виду, возможно. Но это совершенно удивительный мир не просто автоматизации сети, а новой парадигмы строительства и управления сетью. 5 | | Я думаю, что об этом я напишу ещё не одну статью. 6 | 7 | И, надеюсь, этой статьёй мне удалось немного раскрыть длинную историю сетевой автоматизации, показать, что мы живём в эпоху Кембрийского взрыва инструментов и интерфейсов. И перед нами сейчас открыты разные пути, каждый из которых сулит как минимум интересное развитие событий. 8 | 9 | Рекомендую к прочтению `шестую часть АДСМ `_. 10 | 11 | Благодарности 12 | ------------- 13 | 14 | * `Роману Додину `_ за дельные комментарии как по теоретической, так и по практической частям. А так же за полезный блог и инструменты. `GitHub `_. 15 | 16 | * `Кириллу Плетнёву `_ за наведение порядка с NETCONF и YANG - язык, модели, спецификации, форматы данных. И за уместные и остроумные замечания по языкам и библиотекам. `GitHub `_, `fb `_. 17 | 18 | * `Александру Лимонову `_ за несколько идеологических замечаний и исправлений фактических ошибок. 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/build/html/_sources/5_history/index.rst.txt: -------------------------------------------------------------------------------- 1 | Часть 5. История сетевой автоматизации 2 | ====================================== 3 | 4 | | В этой части разбираемся, как мы оказались в том месте, где мы находимся, и куда ведёт нас этот путь. 5 | | Практическую пользу вам принесут только обе прочитанные части: 5 и 6. Вторая без первой будет непонятна. Первая без второй - беллетристика. 6 | 7 | .. figure:: https://fs.linkmeup.ru/images/adsm/5/kdpv0.png 8 | :width: 800 9 | :align: center 10 | 11 | | Когда началась история сетевой автоматизации? 12 | | С Ansible в 2018? С ним она явно получила ускорение благодаря безагентной природе. 13 | | Не. До него были голые языки на букву "P": Python, Perl, PHP. 14 | 15 | С NETCONF? Точно нет, CLI ещё мой дед парсил. А уж сколько expect'ов там поработало… 16 | 17 | SNMP - вот что приходит на ум в качестве первого подхода - он родом из 90-х. 18 | 19 | Однако как насчёт перехода от коммутации каналов к коммутации пакетов? Нельзя ли назвать динамическую сеть, не требующую мгновенного ручного вмешательства при обрывах, разновидностью автоматизации? 20 | 21 | А первый декадно-шаговый искатель, разработанный Строуджером в 19-м веке и раз и навсегда избавивший мир от ручного труда телефонисток? 22 | 23 | Да и в целом даже сам факт появления телефонных станций взамен почты, курьеров и гонцов? 24 | 25 | | Весь наш мир последние лет 300 безостановочно гонится за ускорением. Людей становится всё больше (Индия вон обогнала уже Китай), но их труд всё дороже (не в Индии). И в этом помогает автоматизация. 26 | | 300 лет! Тем временем в сфере сетевых технологий сложилось мнение, что тут всё замерло, мы топчемся на месте, изобретая велосипеды. Но это лишь из-за того, что мы берём довольно короткий период времени и гораздо больший акцент делаем на текущем моменте, нежели на тенденции. 27 | | Как говорится, мы склонны переоценивать краткосрочные последствия и недооценивать долгосрочные. 28 | 29 | .. figure:: https://fs.linkmeup.ru/images/adsm/5/humor.png 30 | :width: 800 31 | :align: center 32 | 33 | Источник: `доклад на Cisco Live `_ 34 | 35 | В этой статье посмотрим, сколько всего в эти 30 лет уместилось. 36 | А уместилось немало. 37 | 38 | 39 | 40 | .. toctree:: 41 | :maxdepth: 2 42 | :caption: Содержание: 43 | 44 | cli.rst 45 | snmp.rst 46 | api_rpc.rst 47 | netconf.rst 48 | restconf.rst 49 | models.rst 50 | grpc.rst 51 | nowdays.rst 52 | future.rst 53 | horizon.rst 54 | links.rst 55 | conclusion.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/5_history/links.rst.txt: -------------------------------------------------------------------------------- 1 | Полезные ссылки 2 | =============== 3 | 4 | 5 | * Главные RFC: 6 | * `RFC1052 `_: Рекомендации IAB по инструментам управления сетью. Результаты встречи (Апрель 1988) 7 | * `RFC3535 `_: Результаты встречи IAB по инструментам управления сетью (май 2003) 8 | * NETCONF: `RFC4741 `_, `RFC6241 `_ 9 | * RESTCONF: `RFC8040 `_ 10 | * YANG: `RFC6020 `_, `RFC7950 `_ 11 | 12 | 13 | * `Репозиторий с опубликованными YANG-моделями `_ 14 | * `Слайды NANOG 2015 `_ 15 | * `Слайды IETF 98 `_ 16 | * `Слайды IETF 101 `_ 17 | * `SDK Broadcom на github `_ 18 | * Концепция RPC: `Remote Procedure Call (RPC) `_ 19 | * Сайт OpenConfig: `openconfig.net `_ 20 | * `Опубликованные модели OpenConfig `_ 21 | * Хорошая вводная в NETCONF и немного YANG: `YANG Data Modelling and NETCONF `_ 22 | * Продолжение про YANG и немного про NETCONF: `The Road to Model Driven Programmability `_ 23 | * На русском про `NETCONF. Начало `_ 24 | * Если жить не можете, хочется на русском про YANG, и вы воспринимаете художественную речь: `YANG — это имя для вождя `_ 25 | * Спецификация gNMI в его же `репозитории `_ 26 | * `RESTCONF Tutorial - Everything you need to know about RESTCONF in 2020 `_ 27 | * Серия статей про RESTCONF, но рекомендую я её из-за того, что там хорошо разобраны примеры с YANG-моделями: `RESTCONF, NETCONF and YANG `_ 28 | * `Документация по gRPC `_ 29 | * `Блог Романа Додина `_ 30 | * `Блог Антона Карнелюка `_ 31 | * `Блог Михаила Кашина `_ 32 | * `Яндекс Nextop. Про использование CLI для Configuration Management `_ 33 | 34 | -------------------------------------------------------------------------------- /docs/build/html/_sources/5_history/nowdays.rst.txt: -------------------------------------------------------------------------------- 1 | Настоящее сетевой автоматизации 2 | =============================== 3 | 4 | Ну и пришло время подводить итоги? 5 | 6 | | Итого, что же творится в мире сетевой автоматизации сейчас? 7 | | Тут на самом деле вопрос, где вопрошающий и отвечающий находятся на спектре от чед-инженера "руками фигакну тыщу свичей, хорошо, если есть Excel" до непорочного инженера, кругом обложившегося gRPC и OpenConfig'ом с сетевым CI/CD-пайплайном. 8 | | А посередине спектра и ансибль, и питон, и перл, и баш, и го. Где-то CLI, куда-то NETCONF уже внедрили, кто-то по gNMI что-то настраивает и телеметрию снимает. Да добрая половина и SNMPv2 ещё не выключила. 9 | 10 | | У многих конфигурация `Day 0 и 1 `_ плюс-минус автоматизирована - это правда легко. 11 | | Day-N у кого-то решается в полностью ручном режиме, иные раскатывают обновления скриптом или простым Ansible playbook'ом, кто-то даже готовит развесистые плейбуки, основанные на модулях, "поддерживающих" состояние. 12 | | У кого-то есть крутая `CLI-автоматизация `_ , умеющая по-настоящему поддерживать состояние. 13 | | Самые продвинутые укладывают всё в NETCONF, собрав полноценный замкнутый цикл релиза конфигурации. 14 | | А совсем оторванные от земли заставляют производителей поддерживать новую функциональность в OpenConfig. 15 | 16 | В целом описать всё многообразие проявлений автоматизаторской фантазии сегодня просто невозможно. Мы сейчас в мире, в котором чёрный параллелепипед ещё не был признан стандартом в области форм-факторов смартфонов. -------------------------------------------------------------------------------- /docs/build/html/_sources/5_history/restconf.rst.txt: -------------------------------------------------------------------------------- 1 | RESTCONF 2 | ======== 3 | 4 | *Буйные 10-е и забыли* 5 | 6 | .. code-block:: text 7 | 8 | The workshop recommends, with strong consensus from the operators 9 | and rough consensus from the protocol developers, that the 10 | IETF/IRTF should not spend resources on developing HTML-based or 11 | HTTP-based methods for configuration management. 12 | 13 | `RFC3535. Recommendation 6 `_ 14 | 15 | | SSH - это хорошо. Но на сетевую автоматизацию случился спрос, а за ним наплыв сил разработчиков. А вот эти разработчики хорошо шарят в REST, но на курле крутили все эти наши SSH и парсинг текста. 16 | | В компаниях, где начинают заниматься автоматизацией сети, обычно уже есть свой штат разработчиков, инструменты, практики. И они в лучшем случае рассматривают сеть, как ещё одни сервера, а то и ещё один сервис. 17 | | И вот REST API с CRUD им очень знаком. 18 | | Вот и решили парни из циски, джунипера и tail-f: *"а почему бы не запилить REST API в сетевые коробки?"*. Ну пошли и запилили - делов-то. И назвали RESTCONF - всё ещё отзываются боли SNMP. 19 | 20 | `Драфт был опубликован в 2014м `_, а в 2017 мир увидел `RFC8040 `_. 21 | 22 | | Это помесь RESTAPI и NETCONF, которая была призвана упростить управление сетью для WEB-приложений. 23 | | Внутри идеологически это NETCONF с его datastores и способами работать с конфигурацией, однако в качестве транспорта - HTTP с набором операций CRUD, реализованных через стандартные методы (*GET*, *POST*, *PUT*, *PATCH*, *DELETE*). 24 | 25 | | Конфигурационные данные передаются в формате JSON или XML. 26 | | В качестве модели данных используется только те, что написаны на языке YANG - тут уже никакой самодеятельности. 27 | 28 | | С самого начала RESTCONF не затевался как замена NETCONF, а только как более удобный для WEB-приложений способ работать с сетевыми устройствами. То есть они должны сожительствовать. 29 | | При этом обычно на устройстве реализуется один бэкенд, обрабатывающий запросы на работу с конфигурацией и опер.данными от разных фронтов - NETCONF или RESTCONF. То есть в основе одни и те же datastores, один и тот же движок, вычисляющий конфигурационные дельты, но сложность транзакционности и нескольких разных видов конфигураций (``running``, ``candidate``, ``saved``) от пользователя скрыта в случае NETCONF. 30 | 31 | С другой стороны отсутствие в выдаче поисковиков хоть сколько-то серьёзных работ по автоматизации с помощью RESTCONF и даже популистских статей от больших игроков говорит о том, что это всё не более чем баловство. И я намеренно не пишу слово "пока". Лично я в него не верю. 32 | 33 | При этом CRUD не очень гладко ложится на RPC-подход, да и в идее держать открытым на сетевом железе HTTP есть что-то противоестественное, согласитесь? Нет? Ну ладно. 34 | 35 | Просто жаль сил, вложенных в этот протокол. Потому что на пятки ему наступает gRPC/gNMI. -------------------------------------------------------------------------------- /docs/build/html/_sources/6_interfaces/callhome.rst.txt: -------------------------------------------------------------------------------- 1 | Call-Home 2 | ========= 3 | 4 | `RFC8071 `_. 5 | 6 | Это, что называется, звонок домой - способ инициировать соединение с NETCONF/RESTCONF-сервера к клиенту, то есть с сетевой коробки на систему управления. 7 | 8 | На устройстве настраивается IP-адрес NETCONF/RESTCONF-клиента, куда оно отсылает периодически данные по своему состоянию. Либо обращается для того, чтобы зарегистрироваться в системе и забрать свою конфигурацию. 9 | 10 | Применимо для сценариев, когда 11 | 12 | * Новое устройство должно сообщить о себе в систему управления 13 | * Устройство находится за NAT или фаерволом 14 | * Администратор считает, что безопаснее иметь закрытые порты на сетевых элементах и открывать только well-known порт на системе управления 15 | 16 | Подробно тут останавливаться не будем. -------------------------------------------------------------------------------- /docs/build/html/_sources/6_interfaces/conclusion.rst.txt: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | Думаю, что хорошее заключение было в `пятой части книги `_, к которой я и отсылаю читателя. 5 | | Путь нас ожидает неблизкий. Туман медленно рассеивается, открывая новые развилки дорожек, из которых нужно выбирать перспективную. 6 | | Но вот что следует держать в голове. Нам обо всём этом рассказывают на конференциях и пишут в длинных статьях как о свершившемся факте, в то время, как многие вещи всё ещё не работают, а в конце обычно есть приписка *"Adding support of OpenConfig gNMI paves the way for future network automation"*. 7 | 8 | Благодарности 9 | ------------- 10 | 11 | 12 | * `Роману Додину `_ за дельные комментарии как по теоретической, так и по практической частям. А так же за полезный блог и инструменты. `GitHub `_. 13 | * `Кириллу Плетнёву `_ за наведение порядка с NETCONF и YANG - язык, модели, спецификации, форматы данных. И за уместные и остроумные замечания по языкам и библиотекам. `GitHub `_, `fb `_. 14 | * `Александру Лимонову `_ за несколько идеологических замечаний и исправлений фактических ошибок. 15 | * `Александру Балезину `_ за написанную часть про Telemetry. -------------------------------------------------------------------------------- /docs/build/html/_sources/6_interfaces/index.rst.txt: -------------------------------------------------------------------------------- 1 | Часть 6. Интерфейсы взаимодействия с сетевым устройством 2 | ======================================================== 3 | 4 | | В этой части мы раскрываем дерево XML, пробуем на вкус капабилити NETCONF, шлём первые RPC и наконец уже расставим в правильном порядке буквы YANG, OpenConfig, gNMI. 5 | | Практическую пользу вам принесут только обе прочитанные статьи. Вторая без первой будет непонятна. Первая без второй - беллетристика. 6 | 7 | .. figure:: https://fs.linkmeup.ru/images/adsm/5/kdpv1.png 8 | :width: 800 9 | :align: center 10 | 11 | 12 | | Сразу предупреждаю, что это будет большая и нудная статья, потому что автор в очередной раз решил разобраться в чём-то, и опубликовать это разом. И вам, клянусь, ещё повезло, когда на двухсоттысячном символе я придумал, как её можно разделить на две части. 13 | | Тут разберём по косточкам все возможные способы взаимодействия с сетевым железом. 14 | | Лишь вскользь мы заденем CLI и SNMP, как не имеющие практической значимости в контексте этой статьи, разберёмся достаточно глубоко с NETCONF - это новый SNMP или всё же у него есть будущее хотя бы с YANG'ом, продолжим RESTCONF'ом и закончим на интригующем - gRPC. 15 | | Ну а по ходу неминуемо разберёмся с тем, за что с нашими глазами так поступает XML, с концепцией RPC, моделями данных и успеем посмотреть на OpenConfig. 16 | 17 | 18 | .. toctree:: 19 | :maxdepth: 2 20 | :caption: Содержание: 21 | 22 | cli.rst 23 | rpc.rst 24 | netconf.rst 25 | xml.rst 26 | netconf_again.rst 27 | restconf.rst 28 | callhome.rst 29 | grpc.rst 30 | models.rst 31 | yang.rst 32 | model_driven.rst 33 | onemoretime.rst 34 | links.rst 35 | conclusion.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/6_interfaces/model_driven.rst.txt: -------------------------------------------------------------------------------- 1 | Model Driven Programmability 2 | ============================ 3 | 4 | Так что же это такое? Ведомая моделью программируемость? Теперь, после двух статей, нам хватит пары минут, чтобы разобраться что это такое. 5 | 6 | Давайте вернёмся к `4-й части АДСМ `_, где я использовал позаимствованную у Дмитрия Тесля картинку. 7 | 8 | .. figure:: https://dteslya.engineer/images/2020-10-netdevops-pipeline.png 9 | 10 | `Источник: dteslya.engineer/network_automaiton_101 `_ 11 | 12 | Она ведь очень понятная? Inventory, Git с шаблонами конфигурации, рендер, валидация, применение. 13 | 14 | | Где закопаны два мешка с человеко-неделями? Под шаблонами с генераторами и под системами применения конфигурации. 15 | | Со вторым пытаются бороться NETCONF, RESTCONF, gNMI. 16 | | А с первым - модели. 17 | 18 | Проблема в том, что шаблоны мы составляем руками на основе изучения документации, интерфейса коробки и действуем методом проб и ошибок, вообще-то. Если нужна проверка типов, диапазонов, если меняется иерархия - будьте добры сами всё это написать и обработать. И, окончив, уехать в сумасшедший дом, учить друзей джинджа-программированию. 19 | 20 | Model Driven меняет картину следующим образом: 21 | 22 | 23 | .. figure:: https://fs.linkmeup.ru/images/adsm/5/model-driven.png 24 | :width: 800 25 | :align: center 26 | 27 | *Не могу найти, откуда брал эту картинку.* 28 | 29 | | Здесь шаблоны конфигурации заменяются на YANG-модель (в данном случае OpenConfig). 30 | | Из инвентарки (топологии) и этих моделей рендерится конфиг, который с помощью RPC (тут gRPC) прогружается на коробку. 31 | 32 | Model Driven означает тут, что мы 33 | 34 | | А) не думаем (или думаем меньше) про иерархию, типы данных. Перестаём мыслить тегами XML. 35 | | Б) Модель определяет, как будет выглядеть конфигурация, как с ней работать. 36 | | В) Использование точно такой же модели на устройстве гарантирует, что отправленное нами, будет принято и валидно на той стороне, коль скоро оно валидно на этой. 37 | 38 | | Иными словами именно модель управляет тем, как мы и железо будет работать с конфигурацией. 39 | | Вот и вся суть. -------------------------------------------------------------------------------- /docs/build/html/_sources/contents.rst.txt: -------------------------------------------------------------------------------- 1 | Автоматизация для самых маленьких 2 | ================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | 7 | 0_planning/planning.rst 8 | 1_virtualization/index.rst 9 | 2_network_design/index.rst 10 | 3_ipam_dcim/index.rst 11 | 4_lifecycle/index.rst 12 | 5_history/index.rst 13 | 6_interfaces/index.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | Автоматизация для самых маленьких 2 | ================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Содержание: 7 | 8 | 0_planning/planning.rst 9 | 1_virtualization/index.rst 10 | 2_network_design/index.rst 11 | 3_ipam_dcim/index.rst 12 | 4_lifecycle/index.rst 13 | 5_history/index.rst 14 | 6_interfaces/index.rst -------------------------------------------------------------------------------- /docs/build/html/_sources/index_back.rst.txt: -------------------------------------------------------------------------------- 1 | Автоматизация для самых маленьких 2 | ================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Содержание: 7 | 8 | 0_planning/planning.rst 9 | 1_virtualization/index.rst 10 | 2_network_design/index.rst -------------------------------------------------------------------------------- /docs/build/html/_static/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/ajax-loader.gif -------------------------------------------------------------------------------- /docs/build/html/_static/comment-bright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/comment-bright.png -------------------------------------------------------------------------------- /docs/build/html/_static/comment-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/comment-close.png -------------------------------------------------------------------------------- /docs/build/html/_static/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/comment.png -------------------------------------------------------------------------------- /docs/build/html/_static/css/badge_only.css: -------------------------------------------------------------------------------- 1 | .fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../fonts/fontawesome-webfont.eot");src:url("../fonts/fontawesome-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff") format("woff"),url("../fonts/fontawesome-webfont.ttf") format("truetype"),url("../fonts/fontawesome-webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} 2 | -------------------------------------------------------------------------------- /docs/build/html/_static/custom.css: -------------------------------------------------------------------------------- 1 | /* This file intentionally left blank. */ 2 | -------------------------------------------------------------------------------- /docs/build/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '0.1.0', 4 | LANGUAGE: 'ru', 5 | COLLAPSE_INDEX: false, 6 | BUILDER: 'html', 7 | FILE_SUFFIX: '.html', 8 | LINK_SUFFIX: '.html', 9 | HAS_SOURCE: true, 10 | SOURCELINK_SUFFIX: '.txt', 11 | NAVIGATION_WITH_KEYS: false 12 | }; -------------------------------------------------------------------------------- /docs/build/html/_static/down-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/down-pressed.png -------------------------------------------------------------------------------- /docs/build/html/_static/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/down.png -------------------------------------------------------------------------------- /docs/build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/file.png -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/.DS_Store -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Inconsolata-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Inconsolata-Bold.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Inconsolata-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Inconsolata-Regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Inconsolata.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Inconsolata.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato-Bold.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato-Regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-bold.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-bold.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-bold.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-bold.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bolditalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-bolditalic.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-bolditalic.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-bolditalic.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-bolditalic.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-italic.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-italic.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-italic.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-italic.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-regular.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-regular.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/Lato/lato-regular.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab-Bold.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab-Regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/build/html/_static/up-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/up-pressed.png -------------------------------------------------------------------------------- /docs/build/html/_static/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/_static/up.png -------------------------------------------------------------------------------- /docs/build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/build/html/objects.inv -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/source/0_planning/conclusion.rst: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | | В качестве основы я выбрал один из современных дизайнов датацентровой сети - L3 Clos Fabric с BGP в качестве протокола маршрутизации. 5 | | Строить сеть мы будем на этот раз на Juniper, потому что теперь интерфейс JunOs - это ванлав. 6 | 7 | Усложним себе жизнь использованием только Open Source инструментов и мультивендорной сетью - поэтому кроме джунипер по ходу дела выберу ещё одного счастливчика. 8 | 9 | | План ближайших публикаций примерно такой: 10 | | Сначала я расскажу про виртуальные сети. В первую очередь, потому что мне хочется, а во вторую, потому что без этого дизайн инфраструктурной сети будет не очень понятен. 11 | | Потом собственно про дизайн сети: топологию, маршрутизацию, политики. 12 | | Соберём лабораторный стенд. 13 | | Поразмышляем и, может, попрактикуемся в инициализации устройства в сети. 14 | | А дальше про каждый компонент в интимных подробностях. 15 | 16 | 17 | И да, я не обещаю изящно закончить этот цикл готовым решением. :) 18 | 19 | Полезные ссылки 20 | ~~~~~~~~~~~~~~~ 21 | 22 | * Перед тем, как углубляться в серию, стоит почитать книгу Наташи Самойленко `Python для сетевых инженеров `_. А, возможно, и пройти `курс `_. 23 | * Полезным будет также почитать `RFC `_ про дизайн датацентровых фабрик от Фейсбука за авторством Петра Лапухова. 24 | * О том, как работает Overlay'ный SDN вам даст представление документация по архитектуре `Tungsten Fabric `_. 25 | 26 | 27 | Спасибы 28 | ~~~~~~~ 29 | 30 | * Роман Горге. За комментарии и правки. 31 | * Артём Чернобай. За КДПВ. 32 | -------------------------------------------------------------------------------- /docs/source/0_planning/planning.rst: -------------------------------------------------------------------------------- 1 | Часть 0. Планирование 2 | ===================== 3 | 4 | СДСМ закончился, а бесконтрольное желание писать - осталось. 5 | 6 | .. figure:: https://fs.linkmeup.ru/images/adsm/0/kdpv.jpg 7 | :width: 800 8 | :align: center 9 | 10 | | Долгие годы наш брат страдал от выполнения рутинной работы, скрещивал пальцы перед коммитом и недосыпал из-за ночных ролбэков. 11 | | Но тёмным временам приходит конец. 12 | 13 | | Этой статьёй я начну серию о том, как *мне* видится автоматизация. 14 | | По ходу дела разберёмся с этапами автоматизации, хранением переменных, формализацией дизайна, с RestAPI, NETCONF, YANG, YDK и будем очень много программировать. 15 | | *Мне* означает, что а) это не объективная истина, б) не безоговорочно лучший подход в) мой взгляд даже в ходе движения от первой к последней статье может поменяться - честно говоря, от стадии черновика до публикации я переписывал всё полностью дважды. 16 | 17 | 18 | АДСМ я попробую вести в формате, немного отличном от СДСМ. По-прежнему будут появляться большие обстоятельные номерные статьи, а между ними я буду публиковать небольшие заметки из повседневного опыта. Постараюсь тут бороться с перфекционизмом и не вылизывать каждую из них. 19 | 20 | | Как это забавно, что во второй раз приходится проходить один и тот же путь. 21 | | Сначала пришлось писать самому статьи про сети из-за того, что их не было в рунете. 22 | | Теперь я не смог найти всесторонний документ, который систематизировал бы подходы к автоматизации и на простых практических примерах разбирал вышеперечисленные технологии. 23 | 24 | Возможно, я ошибаюсь, поэтому, кидайте ссылки на годные ресурсы. Впрочем это не изменит моей решимости писать, потому что, основная цель - это всё-таки научиться чему-то самому, а облегчить жизнь ближнему - это приятный бонус, который ласкает ген распространения опыта. 25 | 26 | | Мы попробуем взять средних размеров дата-центр LAN DC и проработать всю схему автоматизации. 27 | | Делать некоторые вещи я буду практически впервые вместе с вами. 28 | 29 | В описываемых тут идеях и инструментах я буду не оригинален. У Дмитрия Фиголя есть отличный `канал со стримами на эту тему `_. 30 | 31 | Статьи во многих аспектах будут с ними пересекаться. 32 | 33 | | В LAN DC 4 ДЦ, около 250 коммутаторов, полдюжины маршрутизаторов и пара файрволов. 34 | | Не фейсбук, но достаточно для того, чтобы глубоко задуматься об автоматизации. 35 | | Бытует, впрочем, мнение, что если у вас больше 1 устройства, уже нужна автоматизация. 36 | | На самом деле тяжело представить, что кто-то сейчас может жить без хотя бы пачки наколеночных скриптов. 37 | | Хотя я слышал, что есть такие конторы, где учёт IP-адресов ведётся в экселе, а каждое из тысяч сетевых устройств настраивается вручную и имеет свою неповторимую конфигурацию. Это, конечно, можно выдать за современное искусство, но чувства инженера точно будут оскорблены. 38 | 39 | 40 | 41 | .. toctree:: 42 | :maxdepth: 2 43 | :caption: Содержание: 44 | 45 | goals.rst 46 | tools.rst 47 | conclusion.rst -------------------------------------------------------------------------------- /docs/source/1_virtualization/0_virtual_network/faq.rst: -------------------------------------------------------------------------------- 1 | FAQ 2 | === 3 | 4 | 5 | **Зачем ты всё время делаешь ремарку GRE/UDP?** 6 | 7 | | Ну, вообще, это, можно сказать, специфично для Tungsten Fabric - можно вообще не брать во-внимание. 8 | | Но если брать, то сам TF, ещё будучи OpenContrail'ом поддерживал обе инкапсуляции: MPLS in GRE и MPLS in UDP. 9 | | UDP хорош тем, что в Source Port в его заголовке очень легко закодировать хэш-функцию от изначальных IP+Proto+Port, что позволит делать балансировку. 10 | | В случае GRE, увы, есть только внешние заголовки IP и GRE, которые одинаковы для всего инкапсулированного трафика и речь о балансировке не идёт - мало кто может заглянуть так глубоко внутрь пакета. 11 | 12 | До некоторого времени маршрутизаторы, если и умели в динамические туннели, то только в MPLSoGRE, и только совсем недавно, научились в MPLSoUDP. Поэтому приходится делать всегда ремарку о возможности двух разных инкапсуляций. 13 | 14 | Справедливости ради, стоит отметить, что TF вполне поддерживает и L2-связность с помощью VXLAN. 15 | 16 | **Ты обещал провести параллели с OpenFlow.** 17 | 18 | | Они и правда напрашиваются. vSwitch в том же OpenStack'е делает весьма похожие вещи, используя VXLAN, у которого, кстати, тоже UDP-заголовок. 19 | | В Data Plane они работают примерно одинаково, существенно различается Control Plane. Tungsten Fabric использует XMPP для доставки информации о маршрутах на vRouter, в то время, как в OpenStack'е работает Openflow. 20 | 21 | **А можно чуть больше про vRouter?** 22 | 23 | | Он делится на две части: vRouter Agent и vRouter Forwarder. 24 | | Первый запускается в User Space хостовой ОС и общается с SDN-контроллером, обмениваясь информацией о маршрутах, VRF и ACL. 25 | | Второй реализует Data Plane - обычно в Kernel Space, но может запускаться и на SmartNIC'ах - сетевых картах с CPU и отдельным программируемым чипом коммутации, что позволяет снять нагрузку с CPU хостовой машины, а сеть сделать быстрее и более предсказуемой. 26 | | Ещё возможен сценарий, когда vRouter - это DPDK-приложение в User Space. 27 | 28 | vRouter Agent спускает настройки на vRouter Forwarder. 29 | 30 | **Что за Virtual Network?** 31 | 32 | | Я обмолвился в начале статьи о VRF, что мол каждый тенант привязывается к своему VRF. И если для поверхностного понимания работы оверлейной сети этого было достаточно, то уже на следующей итерации надо делать уточнения. 33 | | Обычно в механизмах виртуализации сущность Virtual Network (можно считать это именем собственным) вводится отдельно от клиентов/тенантов/виртуальных машин - вполне себе самостоятельная вещь. А этот Virtual Network через интерфейсы уже можно подключить в один тенант, в другой, в два, да хоть куда. Так, например, реализуется Service Chaining, когда трафик нужно пропустить через определённые ноды в нужной последовательности, просто в правильной последовательности создавая и привзявая Virtual Network'и. 34 | | Поэтому как такового прямого соответствия между Virtual Network и тенантом нет. 35 | -------------------------------------------------------------------------------- /docs/source/1_virtualization/0_virtual_network/index.rst: -------------------------------------------------------------------------------- 1 | Виртуализация сети 2 | ================== 3 | 4 | В `предыдущем выпуске `_ я описал фреймворк сетевой автоматизации. По отзывам у некоторых людей даже этот первый подход к проблеме уже разложил некоторые вопросы по полочкам. И это очень меня радует, потому что наша цель в цикле - не обмазать питоновскими скриптами анзибль, а выстроить систему. 5 | 6 | Этот же фреймворк задаёт порядок, в котором мы будем разбираться с вопросом. 7 | И виртуализация сети, которой посвящён этот выпуск, не особо укладывается в тематику АДСМ, где мы разбираем автоматику. 8 | 9 | Но давайте взглянем на неё под другим углом. 10 | Уже давно одной сетью пользуются многие сервисы. В случае оператора связи это 2G, 3G, LTE, ШПД и B2B, например. В случае ДЦ: связность для разных клиентов, Интернет, блочное хранилище, объектное хранилище. 11 | И все сервисы требуют изоляции друг от друга. Так появились оверлейные сети. 12 | И все сервисы не хотят ждать, когда человек настроит их вручную. Так появились оркестраторы и SDN. 13 | 14 | Первый подход к систематической автоматизации сети, точнее её части, давно предпринят и много где внедрён в жизнь: VMWare, OpenStack, Google Compute Cloud, AWS, Facebook. 15 | 16 | Вот с ним сегодня и поразбираемся. 17 | 18 | .. figure:: https://fs.linkmeup.ru/images/adsm/1/kdpv.jpg 19 | :width: 800 px 20 | :align: center 21 | 22 | 23 | .. toctree:: 24 | :maxdepth: 2 25 | :caption: Содержание: 26 | 27 | motivation.rst 28 | terminology.rst 29 | underlay.rst 30 | overlay.rst 31 | faq.rst 32 | conclusion.rst -------------------------------------------------------------------------------- /docs/source/1_virtualization/0_virtual_network/motivation.rst: -------------------------------------------------------------------------------- 1 | Причины 2 | ======= 3 | 4 | И раз уж мы об этом заговорили, то стоит упомянуть предпосылки к виртуализации сети. На самом деле этот процесс начался не вчера. 5 | 6 | Наверно, вы не раз слышали, что сеть всегда была самой инертной частью любой системы. И это правда во всех смыслах. Сеть - это базис, на который опирается всё, и производить изменения на ней довольно сложно - сервисы не терпят, когда сеть лежит. Зачастую вывод из эксплуатации одного узла может сложить большую часть приложений и повлиять на много клиентов. Отчасти поэтому сетевая команда может сопротивляться любым изменениям - потому что сейчас оно как-то работает (*мы, возможно, даже не знаем как*), а тут надо что-то новое настроить, и неизвестно как оно повлияет на сеть. 7 | 8 | Чтобы не ждать, когда сетевики прокинут VLAN и любые сервисы не прописывать на каждом узле сети, люди придумали использовать оверлеи - наложенные сети - коих великое многообразие: GRE, IPinIP, MPLS, MPLS L2/L3VPN, VXLAN, GENEVE, MPLSoverUDP, MPLSoverGRE итд. 9 | 10 | Их привлекательность заключается в двух простых вещах: 11 | 12 | * Настраиваются только конечные узлы - транзитные трогать не приходится. Это значительно ускоряет процесс, а иногда вообще позволяет исключить отдел сетевой инфраструктуры из процесса ввода новых сервисов. 13 | * Нагрузка сокрыта глубоко внутри заголовков - транзитным узлам не нужно ничего знать о ней, об адресации на хостах, маршрутах наложенной сети. А это значит, нужно хранить меньше информации в таблицах, значит взять попроще/подешевле устройство. 14 | 15 | В этом не совсем полноценном выпуске я не планирую разбирать все возможные технологии, а скорее описать фреймворк работы оверлейных сетей в ДЦ. 16 | 17 | Вся серия будет описывать датацентр, состоящий из рядов однотипных стоек, в которых установлено одинаковое серверное оборудование. 18 | На этом оборудовании запускаются виртуальные машины/контейнеры/серверлесс, реализующие сервисы. 19 | 20 | 21 | .. figure:: https://fs.linkmeup.ru/images/adsm/1/dc.jpg 22 | :width: 800 px 23 | :align: center 24 | 25 | -------------------------------------------------------------------------------- /docs/source/1_virtualization/0_virtual_network/underlay.rst: -------------------------------------------------------------------------------- 1 | Underlay 2 | ======== 3 | 4 | Underlay - это физическая сеть: аппаратные коммутаторы и кабели. Устройства в андерлее знают, как добраться до физических машин. 5 | 6 | .. figure:: https://fs.linkmeup.ru/images/adsm/1/underlay.png 7 | :width: 800 px 8 | :align: center 9 | 10 | Опирается он на стандартные протоколы и технологии. Не в последнюю очередь потому, что аппаратные устройства по сей день работают на проприетарном ПО, не допускающем ни программирование чипа, ни реализацию своих протоколов, соответственно, нужна совместимость с другими вендорами и стандартизация. 11 | 12 | А вот кто-нибудь вроде Гугла может себе позволить разработку собственных коммутаторов и отказ от общепринятых протоколов. Но LAN_DC не Гугл. 13 | 14 | Underlay сравнительно редко меняется, потому что его задача - базовая IP-связность между физическими машинами. Underlay ничего не знает о запущенных поверх него сервисах, клиентах, тенантах - ему нужно только доставить пакет от одной машины до другой. 15 | Underlay может быть например таким: 16 | 17 | * IPv4+OSPF 18 | * IPv6+ISIS+BGP+L3VPN 19 | * IP+EBGP 20 | * L2+TRILL 21 | * L2+STP 22 | 23 | Настраивается Underlay'ная сеть классическим образом: CLI/GUI/NETCONF. 24 | Вручную, скриптами, проприетарными утилитами. 25 | 26 | Более подробно андерлею будет посвящена следующая статья цикла. 27 | 28 | -------------------------------------------------------------------------------- /docs/source/1_virtualization/1_virtualization_basics/conclusion.rst: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | В данной статье мы рассмотрели минимальный набор теоретических знаний, который необходим для работы с виртуальными машинами. Я намеренно не приводил практических примеров и выводов команд, поскольку таких примеров можно найти сколько угодно в Сети, и я не ставил перед собой задачу написать "step-by-step guide". Если вас заинтересовала какая-то конкретная тема или технология, оставляйте свои комментарии и пишите вопросы. 5 | 6 | Полезные ссылки 7 | --------------- 8 | 9 | * `Understanding QEMU Devices `_ 10 | * `KVM/SR-IOV `_ 11 | 12 | Спасибы 13 | ------- 14 | 15 | * `Александру Шалимову `_ - моему коллеге и эксперту в области разработки виртуальных сетей. За комментарии и правки. 16 | * Евгению Яковлеву - моему коллеге и эксперту в области виртуализации за комментарии и правки. 17 | -------------------------------------------------------------------------------- /docs/source/1_virtualization/1_virtualization_basics/index.rst: -------------------------------------------------------------------------------- 1 | Основы виртуализации 2 | ==================== 3 | 4 | Автор этой статьи - `Роман Горге `_ - бывший ведущий linkmeup. 5 | 6 | `Предыдущая статья `_ рассматривала архитектуру виртуализированной сети, underlay-overlay, путь пакета между VM и прочее. В данной статье мы затронем (или попытаемся затронуть) вопросы а как собственно происходит виртуализация сетевых функций, как реализован backend основных продуктов, обеспечивающих запуск и управление VM, а также как работает виртуальный свитчинг (OVS и Linux bridge). 7 | 8 | Тема виртуализации широка и глубока, объяснить все детали работы гипервизора невозможно (да и не нужно). Мы ограничимся минимальным набором знаний необходимым для понимания работы любого виртуализированного решения, не обязательно Telco. 9 | 10 | .. figure:: https://fs.linkmeup.ru/images/adsm/1/1/kdpv.png 11 | :width: 800 12 | :align: center 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | :caption: Содержание: 17 | 18 | history.rst 19 | resource_types.rst 20 | vitual_switching.rst 21 | tools.rst 22 | conclusion.rst 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /docs/source/1_virtualization/index.rst: -------------------------------------------------------------------------------- 1 | Часть 1. Виртуализация 2 | ====================== 3 | 4 | Эту часть мы разбили на две: 5 | 6 | * **Виртуализация сети**, которая рассказывает, как и зачем она появилась в виде SDN и NFV. И почему вообще мы рассматриваем её в серии статей про автоматизацию. 7 | 8 | * **Основы виртуализации**, которая охватывает более общие вопросы о виртуальных хранилищах, процессорах, памяти и сети. Автор этой части - `Роман Горге `_ - бывший ведущий подкаста linkmeup. 9 | 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | :caption: Виртуализация: 14 | 15 | 0_virtual_network/index.rst 16 | 1_virtualization_basics/index.rst -------------------------------------------------------------------------------- /docs/source/2_network_design/conclusion.rst: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | | Так же принято? Под каждой статьёй делать короткий вывод? 5 | | Итак мы выбрали `трёхуровневую `_ сеть Клоза внутри ДЦ, поскольку ожидаем много East-West трафика и хотим ECMP. 6 | | Разделили сеть на физическую (андерлей) и виртуальную (оверлей). При этом оверлей начинается с хоста - тем самым упростили требования к андерлею. 7 | | Выбрали BGP в качестве протокола маршрутизации анедрелейных сетей за его масштабируемость и гибкость политик. 8 | | У нас будут отдельные узлы для организации DCI - Edge-leaf. 9 | | На магистрали будет OSPF+LDP. 10 | | DCI будет реализован на основе MPLS L3VPN. 11 | | Для P2P-линков IP-адреса мы будем вычислять алгоритмически на основе имён устройств. 12 | | Лупбэки будем назначать по роли устройств и их расположению последовательно. 13 | | Андерлейные префиксы - только на Leaf-коммутаторы последовательно на основе их расположения. 14 | 15 | | Предположим, что прямо сейчас у нас ещё не установлено оборудование. 16 | | Поэтому наши следующие шаги будут - завести их в системах (IPAM, инвентарная), организовать доступ, сгенерировать конфигурацию и задеплоить её. 17 | 18 | В следующей статье разберёмся с Netbox - системой инвентаризации и управления IP-пространством в ДЦ. 19 | 20 | Спасибы 21 | ------- 22 | 23 | * Андрею Глазкову aka @glazgoo за вычитку и правки 24 | * Александру Клименко aka @v00lk за вычитку и правки 25 | * Артёму Чернобаю за КДПВ 26 | -------------------------------------------------------------------------------- /docs/source/2_network_design/index.rst: -------------------------------------------------------------------------------- 1 | Часть 2. Дизайн сети 2 | ==================== 3 | 4 | В первых двух статьях я поднял вопрос автоматизации и набросал её фреймворк, во второй сделал отступление в виртуализацию сети, как первый подход к автоматизации настройки сервисов. 5 | А теперь пришло время нарисовать схему физической сети. 6 | 7 | Если вы не на короткой ноге с устройством сетей датацентров, то я настоятельно рекомендую начать со `статьи о них `_. 8 | 9 | 10 | Описанные в этой серии практики должны быть применимы к сети любого типа, любого масштаба с любым многообразием вендоров (нет). Однако нельзя описать универсальный пример применения этих подходов. Поэтому я остановлюсь на современной архитектуре сети ДЦ: `Фабрике Клоза `_. 11 | DCI сделаем на MPLS L3VPN. 12 | Поверх физической сети работает Overlay-сеть с хоста (это может быть VXLAN OpenStack'а или Tungsten Fabric или что угодно другое, что требует от сети только базовой IP-связности). 13 | 14 | .. figure:: https://fs.linkmeup.ru/images/adsm/2/kdpv_small.jpg 15 | :width: 800 16 | :align: center 17 | 18 | В этом случае получится сравнительно простой сценарий для автоматизации, потому что имеем много оборудования, настраивающегося одинаковым образом. 19 | Мы выберем сферический ДЦ в вакууме: 20 | 21 | * Одна версия дизайна везде 22 | * Два вендора, образующих две плоскости сети 23 | * Один ДЦ похож на другой как две капли воды 24 | 25 | Пусть наш Сервис-Провайдер LAN_DC будет, например, хостить обучающие видео о выживании в застрявших лифтах. 26 | В мегаполисах это пользуется бешенной популярностью, поэтому физических машин надо много. 27 | 28 | Сначала я опишу сеть приблизительно такой, какой бы её хотелось видеть. А потом упрощу для лабы. 29 | 30 | 31 | .. toctree:: 32 | :maxdepth: 2 33 | :caption: Дизайн сети: 34 | 35 | topology.rst 36 | routing.rst 37 | ip_plan.rst 38 | lab.rst 39 | conclusion.rst -------------------------------------------------------------------------------- /docs/source/2_network_design/lab.rst: -------------------------------------------------------------------------------- 1 | Лаба 2 | ==== 3 | 4 | Два вендора. Одна сеть. АДСМ. 5 | 6 | Juniper + Arista. Ubuntu. Старая добрая Ева. 7 | 8 | Количество ресурсов на нашей виртуалочке в Миране всё же ограничено, поэтому для практики мы будем использовать вот такую упрощённую до предела сеть. 9 | 10 | .. figure:: https://fs.linkmeup.ru/images/adsm/2/lab.png 11 | :width: 800 12 | :align: center 13 | 14 | * Два датацентра: Казань и Барселона. 15 | * По два спайна в каждом: Juniper и Arista. 16 | * По одному тору (Leaf'у) в каждом - Juniper и Arista, с одним подключенным хостом (возьмём легковесный Cisco IOL для этого). 17 | * По одной ноде Edge-Leaf (пока только Juniper). 18 | * One Cisco switch to rule them all. 19 | * Помимо сетевых коробок запущена виртуальная машина-управляка. Под управлением Ubuntu. 20 | Она имеет доступ ко всем устройствам, на ней будут крутиться IPAM/DCIM-системы, букет питоновских скриптов, анзибль и что угодно ещё, что нам может понадобиться. 21 | 22 | `Полная конфигурация `_ всех сетевых устройств, которую мы будем пробовать воспроизвести с помощью автоматики. -------------------------------------------------------------------------------- /docs/source/2_network_design/target_configs/bcn-host-0.cfg: -------------------------------------------------------------------------------- 1 | hostname bcn-host-0 2 | ! 3 | boot-start-marker 4 | boot-end-marker 5 | ! 6 | ! 7 | ! 8 | no aaa new-model 9 | clock timezone EET 2 0 10 | mmi polling-interval 60 11 | no mmi auto-configure 12 | no mmi pvc 13 | mmi snmp-timeout 180 14 | ! 15 | ! 16 | ! 17 | ! 18 | ! 19 | ! 20 | ! 21 | ! 22 | 23 | 24 | ! 25 | ! 26 | ! 27 | ! 28 | ip cef 29 | no ipv6 cef 30 | ! 31 | multilink bundle-name authenticated 32 | ! 33 | ! 34 | ! 35 | ! 36 | ! 37 | ! 38 | ! 39 | ! 40 | ! 41 | redundancy 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | ! 49 | ! 50 | ! 51 | ! 52 | ! 53 | ! 54 | ! 55 | ! 56 | ! 57 | interface Ethernet0/0 58 | ip address 10.0.128.66 255.255.255.192 59 | ! 60 | interface Ethernet0/1 61 | no ip address 62 | shutdown 63 | ! 64 | interface Ethernet0/2 65 | no ip address 66 | shutdown 67 | ! 68 | interface Ethernet0/3 69 | no ip address 70 | shutdown 71 | ! 72 | ip forward-protocol nd 73 | ! 74 | ! 75 | no ip http server 76 | no ip http secure-server 77 | ip route 0.0.0.0 0.0.0.0 10.0.128.65 78 | ! 79 | ! 80 | ! 81 | ! 82 | control-plane 83 | ! 84 | ! 85 | ! 86 | ! 87 | ! 88 | ! 89 | ! 90 | ! 91 | line con 0 92 | logging synchronous 93 | line aux 0 94 | line vty 0 4 95 | login 96 | transport input none 97 | ! 98 | ! 99 | end -------------------------------------------------------------------------------- /docs/source/2_network_design/target_configs/bcn-leaf-1.cfg: -------------------------------------------------------------------------------- 1 | hostname bcn-leaf-1 2 | ! 3 | spanning-tree mode mstp 4 | ! 5 | no aaa root 6 | ! 7 | vlan 127 8 | ! 9 | interface Ethernet1 10 | no switchport 11 | ip address 169.254.0.2/31 12 | ! 13 | interface Ethernet2 14 | no switchport 15 | ip address 169.254.1.2/31 16 | ! 17 | interface Ethernet3 18 | ! 19 | interface Ethernet4 20 | switchport access vlan 127 21 | ! 22 | interface Ethernet5 23 | ! 24 | interface Ethernet6 25 | ! 26 | interface Ethernet7 27 | ! 28 | interface Ethernet8 29 | ! 30 | interface Ethernet9 31 | ! 32 | interface Management1 33 | ip address 192.168.1.12/24 34 | ! 35 | interface Vlan127 36 | ip address 10.0.128.65/26 37 | ! 38 | ip routing 39 | ! 40 | ip community-list standard NO_REANNOUNCE permit 65535:999 41 | ! 42 | route-map EXPORT_TO_SPINES deny 5 43 | description NO_REANNOUNCE 44 | match community NO_REANNOUNCE 45 | ! 46 | route-map EXPORT_TO_SPINES permit 10 47 | description ALLOW 48 | ! 49 | route-map IMPORT_FROM_SPINES permit 5 50 | description ALLOW 51 | set community 65535:999 52 | ! 53 | route-map IMPORT_UNDERLAY permit 5 54 | match interface Vlan127 55 | ! 56 | router bgp 4228186112 57 | neighbor SPINES peer-group 58 | neighbor SPINES remote-as 64517 59 | neighbor SPINES route-map IMPORT_FROM_SPINES in 60 | neighbor SPINES route-map EXPORT_TO_SPINES out 61 | neighbor SPINES maximum-routes 12000 62 | neighbor 169.254.0.3 peer-group SPINES 63 | neighbor 169.254.1.3 peer-group SPINES 64 | redistribute connected route-map IMPORT_UNDERLAY 65 | ! 66 | ! 67 | end -------------------------------------------------------------------------------- /docs/source/2_network_design/target_configs/bcn-spine-1.cfg: -------------------------------------------------------------------------------- 1 | hostname bcn-spine-1 2 | ! 3 | spanning-tree mode mstp 4 | ! 5 | no aaa root 6 | ! 7 | interface Ethernet1 8 | ! 9 | interface Ethernet2 10 | no switchport 11 | ip address 169.254.1.3/31 12 | ! 13 | interface Ethernet3 14 | no switchport 15 | ip address 169.254.101.1/31 16 | ! 17 | interface Ethernet4 18 | ! 19 | interface Ethernet5 20 | ! 21 | interface Ethernet6 22 | ! 23 | interface Ethernet7 24 | ! 25 | interface Ethernet8 26 | ! 27 | interface Ethernet9 28 | ! 29 | interface Management1 30 | ip address 192.168.1.11/24 31 | ! 32 | ip routing 33 | ! 34 | route-map ALLOW permit 5 35 | ! 36 | route-map EXPORT deny 5 37 | description NO_DIRECT 38 | match source-protocol connected 39 | ! 40 | route-map EXPORT permit 10 41 | description ALLOW 42 | ! 43 | router bgp 64517 44 | neighbor EDGES peer-group 45 | neighbor EDGES remote-as 65535 46 | neighbor EDGES route-map ALLOW in 47 | neighbor EDGES route-map EXPORT out 48 | neighbor EDGES maximum-routes 12000 49 | neighbor LEAFS peer-group 50 | neighbor LEAFS route-map ALLOW in 51 | neighbor LEAFS route-map EXPORT out 52 | neighbor LEAFS maximum-routes 12000 53 | neighbor 169.254.1.2 peer-group LEAFS 54 | neighbor 169.254.1.2 remote-as 4228186112 55 | neighbor 169.254.101.0 peer-group EDGES 56 | ! 57 | ! 58 | end -------------------------------------------------------------------------------- /docs/source/2_network_design/target_configs/kzn-host-0.cfg: -------------------------------------------------------------------------------- 1 | hostname kzn-host-0 2 | ! 3 | boot-start-marker 4 | boot-end-marker 5 | ! 6 | ! 7 | ! 8 | no aaa new-model 9 | clock timezone EET 2 0 10 | mmi polling-interval 60 11 | no mmi auto-configure 12 | no mmi pvc 13 | mmi snmp-timeout 180 14 | ! 15 | ! 16 | ! 17 | ! 18 | ! 19 | ! 20 | ! 21 | ! 22 | 23 | 24 | ! 25 | ! 26 | ! 27 | ! 28 | ip cef 29 | no ipv6 cef 30 | ! 31 | multilink bundle-name authenticated 32 | ! 33 | ! 34 | ! 35 | ! 36 | ! 37 | ! 38 | ! 39 | ! 40 | ! 41 | redundancy 42 | ! 43 | ! 44 | ! 45 | ! 46 | ! 47 | ! 48 | ! 49 | ! 50 | ! 51 | ! 52 | ! 53 | ! 54 | ! 55 | ! 56 | ! 57 | interface Ethernet0/0 58 | ip address 10.0.32.2 255.255.255.0 59 | ! 60 | interface Ethernet0/1 61 | no ip address 62 | shutdown 63 | ! 64 | interface Ethernet0/2 65 | no ip address 66 | shutdown 67 | ! 68 | interface Ethernet0/3 69 | no ip address 70 | shutdown 71 | ! 72 | ip forward-protocol nd 73 | ! 74 | ! 75 | no ip http server 76 | no ip http secure-server 77 | ip route 0.0.0.0 0.0.0.0 10.0.32.1 78 | ! 79 | ! 80 | ! 81 | ! 82 | control-plane 83 | ! 84 | ! 85 | ! 86 | ! 87 | ! 88 | ! 89 | ! 90 | ! 91 | line con 0 92 | logging synchronous 93 | line aux 0 94 | line vty 0 4 95 | login 96 | transport input none 97 | ! 98 | ! 99 | end -------------------------------------------------------------------------------- /docs/source/2_network_design/target_configs/kzn-spine-1.cfg: -------------------------------------------------------------------------------- 1 | hostname kzn-spine-1 2 | ! 3 | spanning-tree mode mstp 4 | ! 5 | no aaa root 6 | ! 7 | interface Ethernet1 8 | no switchport 9 | ip address 169.254.1.1/31 10 | ! 11 | interface Ethernet2 12 | ! 13 | interface Ethernet3 14 | no switchport 15 | ip address 169.254.101.1/31 16 | ! 17 | interface Ethernet4 18 | ! 19 | interface Ethernet5 20 | ! 21 | interface Ethernet6 22 | ! 23 | interface Ethernet7 24 | ! 25 | interface Ethernet8 26 | ! 27 | interface Ethernet9 28 | ! 29 | interface Management1 30 | ip address 192.168.1.3/24 31 | ! 32 | ip routing 33 | ! 34 | route-map ALLOW permit 5 35 | ! 36 | route-map EXPORT deny 5 37 | description NO_DIRECT 38 | match source-protocol connected 39 | ! 40 | route-map EXPORT permit 10 41 | description ALLOW 42 | ! 43 | router bgp 64513 44 | neighbor EDGES peer-group 45 | neighbor EDGES remote-as 65535 46 | neighbor EDGES route-map ALLOW in 47 | neighbor EDGES route-map EXPORT out 48 | neighbor EDGES maximum-routes 12000 49 | neighbor LEAFS peer-group 50 | neighbor LEAFS route-map ALLOW in 51 | neighbor LEAFS route-map EXPORT out 52 | neighbor LEAFS maximum-routes 12000 53 | neighbor 169.254.1.0 peer-group LEAFS 54 | neighbor 169.254.1.0 remote-as 4227923968 55 | neighbor 169.254.101.0 peer-group EDGES 56 | ! 57 | ! 58 | end -------------------------------------------------------------------------------- /docs/source/2_network_design/target_configs/mgmt-switch.cfg: -------------------------------------------------------------------------------- 1 | hostname mgmt-switch 2 | ! 3 | boot-start-marker 4 | boot-end-marker 5 | ! 6 | ! 7 | ! 8 | no aaa new-model 9 | ! 10 | ! 11 | ! 12 | ! 13 | ! 14 | ! 15 | ! 16 | ! 17 | ip cef 18 | no ipv6 cef 19 | ! 20 | ! 21 | ! 22 | spanning-tree mode rapid-pvst 23 | spanning-tree extend system-id 24 | ! 25 | vlan internal allocation policy ascending 26 | ! 27 | ! 28 | ! 29 | ! 30 | ! 31 | ! 32 | ! 33 | ! 34 | ! 35 | ! 36 | ! 37 | ! 38 | ! 39 | ! 40 | interface GigabitEthernet0/0 41 | media-type rj45 42 | negotiation auto 43 | ! 44 | interface GigabitEthernet0/1 45 | media-type rj45 46 | negotiation auto 47 | ! 48 | interface GigabitEthernet0/2 49 | media-type rj45 50 | negotiation auto 51 | ! 52 | interface GigabitEthernet0/3 53 | media-type rj45 54 | negotiation auto 55 | ! 56 | interface GigabitEthernet1/0 57 | media-type rj45 58 | negotiation auto 59 | ! 60 | interface GigabitEthernet1/1 61 | media-type rj45 62 | negotiation auto 63 | ! 64 | interface GigabitEthernet1/2 65 | media-type rj45 66 | negotiation auto 67 | ! 68 | interface GigabitEthernet1/3 69 | media-type rj45 70 | negotiation auto 71 | ! 72 | interface GigabitEthernet2/0 73 | media-type rj45 74 | negotiation auto 75 | ! 76 | interface GigabitEthernet2/1 77 | media-type rj45 78 | negotiation auto 79 | ! 80 | interface GigabitEthernet2/2 81 | media-type rj45 82 | negotiation auto 83 | ! 84 | interface GigabitEthernet2/3 85 | media-type rj45 86 | negotiation auto 87 | ! 88 | interface GigabitEthernet3/0 89 | media-type rj45 90 | negotiation auto 91 | ! 92 | interface GigabitEthernet3/1 93 | media-type rj45 94 | negotiation auto 95 | ! 96 | interface GigabitEthernet3/2 97 | media-type rj45 98 | negotiation auto 99 | ! 100 | interface GigabitEthernet3/3 101 | media-type rj45 102 | negotiation auto 103 | ! 104 | interface Vlan1 105 | ip address 192.168.1.1 255.255.255.0 106 | ! 107 | ip forward-protocol nd 108 | ! 109 | no ip http server 110 | no ip http secure-server 111 | ! 112 | ! 113 | ! 114 | ! 115 | ! 116 | ! 117 | control-plane 118 | ! 119 | line con 0 120 | line aux 0 121 | line vty 0 4 122 | login 123 | ! 124 | ! 125 | end -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/architecture.rst: -------------------------------------------------------------------------------- 1 | Архитектура системы 2 | =================== 3 | 4 | * NetBox написан на Python3. Что хорошо, потому что ряд других решений написан на php и изменять их при необходимости не так уж просто. 5 | * Фреймворк для самого сайта - Django. 6 | * В качестве БД используется PostgreSQL. 7 | * WEB-frontend (HTTP-сревис) - NGINX - он проксирует запросы в Gunicron. 8 | * WSGI - Gunicorn - интерфейс между Nginx и самим приложением. 9 | * Фреймворк для документации по API - Swagger. 10 | * Чтобы демонизировать NetBox - Systemd. 11 | 12 | NetBox - проект молодой и быстро развивающийся. Например, в 2.7 отказались от supervisord и тянущегося за ним Python 2.7 в пользу systemd. Не так давно там не было ни кэширования, ни Webhooks. 13 | Поэтому меняется всё быстро и информация в статье может устареть к моменту чтения. 14 | 15 | Иными словами все компоненты зрелые и проверенные. 16 | 17 | По словам автора NetBox отражает не реальное состояние сети, а целевое. Поэтому ничего не подгружается в NetBox из сети - это сеть настраивается в соответствие с содержимым NetBox. 18 | Таким образом NetBox выступает единственным источником истины (калька с single source of truth). 19 | И изменения на сети должны быть инициированы изменениями в NetBox. 20 | А это очень неплохо ложится на идеологию, которую я исповедую в этой серии статей - хочешь сделать изменения на сети - сначала внеси их в системы. 21 | -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/conclusion.rst: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | В этой статье я не преследовал цель рассмотреть все возможности NetBox, поэтому всё остальное отдаю вам на откуп. Разбирайтесь, пробуйте. 5 | 6 | Далее в рамках построения системы автоматизации я буду касаться только тех частей, которые нам действительно нужны. 7 | 8 | Итак, выше я коротко рассказал о том, что из себя представляет NetBox, и как в нём хранятся данные. 9 | Повторюсь, что почти все необходимые данные я туда уже внёс, и вы можете утащить себе `дамп БД `_ 10 | 11 | Всё готово к следующему этапу автоматизации: написанию системы (ахаха, просто скриптов) инициализации устройств и управления конфигурацией. 12 | 13 | Полезные ссылки 14 | --------------- 15 | 16 | * `Сам NetBox на github `_ 17 | * `Контейнерная версия `_ 18 | * `Полная инструкция по установке и вся документация по продукту `_ 19 | * `Documenting your network infrastructure in NetBox, integrating with Ansible over REST API `_ 20 | * `IPAM NetBox and its API, Docker, Postman `_ 21 | * `IPAM NetBox and its API, configuration templates with Python `_ 22 | * `SDK для работы с NetBox в Python `_ 23 | * `Документация по API `_ 24 | * `Mailing list `_ 25 | * `Канал в Slack NetworkToCode `_ 26 | * `Что такое REST `_ 27 | * `Инсталляция NetBox для нужд АДСМ `_ -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_delete_device.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_delete_device.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_get_all_devices.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_get_all_devices.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_get_device_by_name.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_get_device_by_name.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_get_device_with_double_conditions.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_get_device_with_double_conditions.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_get_device_with_or_operand.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_get_device_with_or_operand.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_get_devices.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_get_devices.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_get_not_found.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_get_not_found.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_patch_serial.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_patch_serial.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_post_new_device.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_post_new_device.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/dumps/http_put_asset_tag.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/3_ipam_dcim/dumps/http_put_asset_tag.pcapng -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/installation.rst: -------------------------------------------------------------------------------- 1 | Некоторые нюансы установки NetBox 2 | ================================= 3 | 4 | Я не буду описывать процесс инсталляции в деталях - он более чем классно описан в `официальной документации `_. 5 | 6 | Посмотреть на процесс запуска docker-образа NetBox и работу в GUI можно в видео Димы Фиголя (`раз `_ и `два `_) и `Эмиля Гарипова `_. 7 | 8 | | В целом, если следовать шагам установки/запуска неукоснительно, то всё получится. 9 | | Но вот какие есть нюансы, про которые случайно можно забыть. 10 | 11 | * | В файле configuration.py должен быть заполнен параметр `ALLOWED_HOSTS `_: 12 | 13 | .. code-block:: bash 14 | 15 | ALLOWED_HOSTS = ['netbox.linkmeup.ru', 'localhost'] 16 | 17 | | Тут нужно указать все возможные имена NetBox, к которым вы будете обращаться, например, может быть внешний IP-адрес или 127.0.0.1 или DNS-alias. 18 | | Если этого не будет сделано, сайт NetBox не откроется и будет показывать 400. 19 | 20 | * В этом же файле должен быть указан `SECRET_KEY `_, который можно выдумать самому или сгенерировать скриптом. 21 | * Главная страница будет показывать 502 Bad Gateway, если что-то не так с настройкой базы PostgreSQL: проверьте хост(если ставили на другую машину), порт, имя базы, имя пользователя, пароль. 22 | * | С `некоторых пор `_ NetBox по умолчанию не даёт никаких прав на чтение без авторизации. 23 | | Изменяется это всё в том же configuration.py: 24 | 25 | .. code-block:: bash 26 | 27 | EXEMPT_VIEW_PERMISSIONS = ['*'] 28 | 29 | * | А ещё API запросы будут возвращать 200 и не работать, если в API URL не будет слэша в конце. 30 | 31 | .. code-block:: bash 32 | 33 | curl -X GET "http://netbox.linkmeup.ru:45127/api/dcim/devices" -H "Accept: application/json; indent=4" 34 | -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/postgresql.rst: -------------------------------------------------------------------------------- 1 | Немного о PostgreSQL 2 | ==================== 3 | 4 | Для подключения к серверу: 5 | 6 | .. code-block:: bash 7 | 8 | psql -U *username* -h *hostname* *db_name* 9 | 10 | Например: 11 | 12 | .. code-block:: bash 13 | 14 | psql -U netbox -h localhost netbox 15 | 16 | Для вывода всех таблиц: 17 | 18 | .. code-block:: bash 19 | 20 | /dt 21 | 22 | Для выхода: 23 | 24 | .. code-block:: bash 25 | 26 | /q 27 | 28 | Для дампа БД: 29 | 30 | .. code-block:: bash 31 | 32 | pg_dump -U *username* -h *hostname* *db_name* > netbox.sql 33 | 34 | Если не хочется каждый раз вводить пароль: 35 | 36 | .. code-block:: bash 37 | 38 | echo *:*:*:*username*:*password* > ~/.pgpass 39 | chmod 600 ~/.pgpass 40 | 41 | Если у вас есть своя инсталляция и не хочется вносить всё руками, можно просто сделать так, взяв дамп текущей БД NetBox `тут `_: 42 | 43 | .. code-block:: bash 44 | 45 | psql -U *username* -h *hostname* *db_name* < netbox_initial_db.sql 46 | 47 | Если предварительно нужно дропнуть все таблицы (а сделать это придётся), то можно подготовить заранее файл: 48 | 49 | .. code-block:: bash 50 | 51 | psql -U *username* -h *hostname* *db_name* 52 | \o drop_all_tables.sql 53 | select 'drop table ' || tablename || ' cascade;' from pg_tables; 54 | \q 55 | psql -U *username* -h *hostname* *db_name* -f drop_all_tables.sql -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/restful/conclusion.rst: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | Не всё в том мире 2000-го года так уже радужно. REST по праву часто критикуют. 5 | Не являясь экспертом, не берусь предметно раскрывать вопрос, но дам ссылку на небесспорную `статью на хабре `_. 89 | 90 | 91 | Тело HTTP-сообщения 92 | ------------------- 93 | 94 | Тело используется для передачи собственно данных. 95 | В HTTP-ответе это может быть HTML-страничка, или в нашем случае JSON-объект. 96 | 97 | Между заголовками и телом должна быть как минимум одна пустая строка. 98 | 99 | При использовании метода GET в HTTP-запросе обычно никакого тела нет, потому что передавать нечего. Но тело есть в HTTP-ответе. 100 | А вот например, при POST уже и в запросе будет тело. Давайте о методах и поговорим теперь. 101 | -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/scripts/pynetbox_get_devices.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import pynetbox 4 | 5 | API_TOKEN = "a9aae70d65c928a554f9a038b9d4703a1583594f" 6 | NB_URL = "http://netbox.linkmeup.ru:45127" 7 | 8 | nb = pynetbox.api( 9 | NB_URL, 10 | token = API_TOKEN 11 | ) 12 | 13 | devices = nb.dcim.devices.all() 14 | print(devices) -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/scripts/pynetbox_post_new_device.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import pynetbox 4 | 5 | API_TOKEN = "a9aae70d65c928a554f9a038b9d4703a1583594f" 6 | NB_URL = "http://netbox.linkmeup.ru:45127" 7 | 8 | nb = pynetbox.api( 9 | NB_URL, 10 | token = API_TOKEN 11 | ) 12 | 13 | device_parameters = { 14 | "name": "just a simple PYNETBOX girl", 15 | "device_type": 1, 16 | "device_role": 1, 17 | "site": 3, 18 | } 19 | new_device = nb.dcim.devices.create(**device_parameters) 20 | print(new_device) -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/scripts/requests_get_devices.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | API_TOKEN = "a9aae70d65c928a554f9a038b9d4703a1583594f" 4 | HEADERS = {'Authorization': f'Token {API_TOKEN}', 'Content-Type': 'application/json', 'Accept': 'application/json'} 5 | NB_URL = "http://netbox.linkmeup.ru:45127" 6 | 7 | request_url = f"{NB_URL}/api/dcim/devices/" 8 | devices = requests.get(request_url, headers = HEADERS) 9 | print(devices.json()) -------------------------------------------------------------------------------- /docs/source/3_ipam_dcim/scripts/requests_post_new_device.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import requests 4 | 5 | API_TOKEN = "a9aae70d65c928a554f9a038b9d4703a1583594f" 6 | HEADERS = {'Authorization': f'Token {API_TOKEN}', 'Content-Type': 'application/json', 'Accept': 'application/json'} 7 | NB_URL = "http://netbox.linkmeup.ru:45127" 8 | 9 | request_url = f"{NB_URL}/api/dcim/devices/" 10 | 11 | device_parameters = { 12 | "name": "just a simple russian girl", 13 | "device_type": 1, 14 | "device_role": 1, 15 | "site": 3, 16 | } 17 | new_device = requests.post(request_url, headers = HEADERS, json=device_parameters) 18 | print(new_device.json()) -------------------------------------------------------------------------------- /docs/source/4_lifecycle/conclusion.rst: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | Итак, скромной задачей этой статьи было спуститься на один уровень абстракции ниже по сравнению с `нулевой публикацией `_ и попытаться декомпозировать жизненный цикл оборудования на понятные блоки. 5 | 6 | .. figure:: https://fs.linkmeup.ru/images/adsm/4/dasha.png 7 | :width: 600 8 | :align: center 9 | 10 | | Повторюсь в очередной раз, что это лишь один из возможных подходов, который просто пришёл в голову мне. Он не только не претендует на оптимальность и проработанность, но и, хуже того, скорее всего, даже на таком описательном уровне уже местами переусложнён. 11 | 12 | | И ещё хуже то, что в рамках этой серии крайне маловероятно, что я сделаю что-то практическое, хотя бы отдалённое напоминающее описанную схему. 13 | | Хотя зарекаться не буду. 14 | 15 | | В следующих статьях мы поразбираемся с ZTP и какими-то базовыми скриптами автоматизации. А ещё рано или поздно углубимся в интерфейсы взаимодействия с сетевыми коробками: NETCONF/YANG, gNMI, GRPC. 16 | 17 | Спасибы 18 | ------- 19 | 20 | * `Роману Горге `_ - бывшему ведущему подкаста linkmeup, а ныне эксперту в области облачных платформ - за комментарии про подход IaC и концепцию ACID применительно к сети. 21 | * `Михаилу Арефьеву `_ - руководителю проектов по сетевой автоматизации в Яндексе - за анализ и критику архитектуры решения и сценариев. 22 | * `Дмитрию Фиголю `_ - Network Automation Architect at Cisco Global Demo Engineering - за острые замечания и дискуссию. 23 | * `Никите Асташенко `_ - моему другу и классному разработчику - за поездку на Алтай и долгие разговоры у костра, без которых эта идея не вызрела бы. 24 | 25 | Особо благодарных просим задержаться и пройти на `Патреон `_. 26 | 27 | .. figure:: https://fs.linkmeup.ru/images/patreon.jpg 28 | :width: 400 29 | :align: center 30 | -------------------------------------------------------------------------------- /docs/source/4_lifecycle/index.rst: -------------------------------------------------------------------------------- 1 | Часть 4. Архитектура системы автоматизации 2 | ========================================== 3 | 4 | | Продолжаем наш `забег по сетевой автоматизации `_. 5 | | Итак, сеть спроектирована, IPAM запущен. И вот-вот начнут съезжаться миллионы наших стоек. Будем готовиться к этому. 6 | | Мы всё дальше от фантазий и абстрактных разговоров и ближе к практике. 7 | | И всё же снова сделаем отступление. Большое дело начинается с большого перекура. 8 | 9 | | Сеть полезно представлять, как некое единое целое, которое мы переводим из одного состояния в другое. Сервис мы внедряем на всей сети. Не может быть такого, что он работает только на 3 устройствах из 4 необходимых. **Вся** сеть должна обеспечивать отказоустойчивость и достаточную полосу. 10 | | Однако рано или поздно всё равно любая задача декомпозируется до уровня отдельных сетевых коробок. 11 | | И если про сеть как единый организм мы уже поговорили в `0-й статье `_, то теперь пришло время разобраться отдельными органами. 12 | 13 | .. figure:: https://fs.linkmeup.ru/images/adsm/4/kdpv.png 14 | :width: 900 15 | :align: center 16 | 17 | | В этой статье разберём жизненный цикл сетевого устройства и некоторые сценарии того, какие манипуляции с ним приходится порой делать. 18 | | Естественно, всё это интересует нас с точки зрения автоматизируемости. Поэтому ещё мы нарисуем архитектуру системы автоматизации. 19 | | Кстати, не так давно вышла просто восхихитительная `обзорная статья `_ Дмитрия Тесля о процессе и инструментах сетевой автоматизации. Он смог лаконично изложить то, вокруг чего я пляшу уже несколько выпусков АДСМ. Настоятельно рекомендую прочитать её перед тем, как преступать к этой. 20 | 21 | .. toctree:: 22 | :maxdepth: 2 23 | :caption: Содержание: 24 | 25 | lifecycle.rst 26 | iac.rst 27 | architecture.rst 28 | scenarios.rst 29 | links.rst 30 | conclusion.rst -------------------------------------------------------------------------------- /docs/source/4_lifecycle/links.rst: -------------------------------------------------------------------------------- 1 | Полезные ссылки 2 | =============== 3 | 4 | * `Awesome Network Automation `_ 5 | * `Статья Network Automation 101 от Дмитрия Тесля `_ 6 | * `Hands-on with NetDevOps `_ 7 | * `Scaling the Facebook backbone through Zero Touch Provisioning (ZTP) `_ 8 | -------------------------------------------------------------------------------- /docs/source/5_history/conclusion.rst: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | | Конечно, я очень размазал последнюю часть, непонятно как это сделать, непонятно даже что я имел в виду, возможно. Но это совершенно удивительный мир не просто автоматизации сети, а новой парадигмы строительства и управления сетью. 5 | | Я думаю, что об этом я напишу ещё не одну статью. 6 | 7 | И, надеюсь, этой статьёй мне удалось немного раскрыть длинную историю сетевой автоматизации, показать, что мы живём в эпоху Кембрийского взрыва инструментов и интерфейсов. И перед нами сейчас открыты разные пути, каждый из которых сулит как минимум интересное развитие событий. 8 | 9 | Рекомендую к прочтению `шестую часть АДСМ `_. 10 | 11 | Благодарности 12 | ------------- 13 | 14 | * `Роману Додину `_ за дельные комментарии как по теоретической, так и по практической частям. А так же за полезный блог и инструменты. `GitHub `_. 15 | 16 | * `Кириллу Плетнёву `_ за наведение порядка с NETCONF и YANG - язык, модели, спецификации, форматы данных. И за уместные и остроумные замечания по языкам и библиотекам. `GitHub `_, `fb `_. 17 | 18 | * `Александру Лимонову `_ за несколько идеологических замечаний и исправлений фактических ошибок. 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/source/5_history/index.rst: -------------------------------------------------------------------------------- 1 | Часть 5. История сетевой автоматизации 2 | ====================================== 3 | 4 | | В этой части разбираемся, как мы оказались в том месте, где мы находимся, и куда ведёт нас этот путь. 5 | | Практическую пользу вам принесут только обе прочитанные части: 5 и 6. Вторая без первой будет непонятна. Первая без второй - беллетристика. 6 | 7 | .. figure:: https://fs.linkmeup.ru/images/adsm/5/kdpv0.png 8 | :width: 800 9 | :align: center 10 | 11 | | Когда началась история сетевой автоматизации? 12 | | С Ansible в 2018? С ним она явно получила ускорение благодаря безагентной природе. 13 | | Не. До него были голые языки на букву "P": Python, Perl, PHP. 14 | 15 | С NETCONF? Точно нет, CLI ещё мой дед парсил. А уж сколько expect'ов там поработало… 16 | 17 | SNMP - вот что приходит на ум в качестве первого подхода - он родом из 90-х. 18 | 19 | Однако как насчёт перехода от коммутации каналов к коммутации пакетов? Нельзя ли назвать динамическую сеть, не требующую мгновенного ручного вмешательства при обрывах, разновидностью автоматизации? 20 | 21 | А первый декадно-шаговый искатель, разработанный Строуджером в 19-м веке и раз и навсегда избавивший мир от ручного труда телефонисток? 22 | 23 | Да и в целом даже сам факт появления телефонных станций взамен почты, курьеров и гонцов? 24 | 25 | | Весь наш мир последние лет 300 безостановочно гонится за ускорением. Людей становится всё больше (Индия вон обогнала уже Китай), но их труд всё дороже (не в Индии). И в этом помогает автоматизация. 26 | | 300 лет! Тем временем в сфере сетевых технологий сложилось мнение, что тут всё замерло, мы топчемся на месте, изобретая велосипеды. Но это лишь из-за того, что мы берём довольно короткий период времени и гораздо больший акцент делаем на текущем моменте, нежели на тенденции. 27 | | Как говорится, мы склонны переоценивать краткосрочные последствия и недооценивать долгосрочные. 28 | 29 | .. figure:: https://fs.linkmeup.ru/images/adsm/5/humor.png 30 | :width: 800 31 | :align: center 32 | 33 | Источник: `доклад на Cisco Live `_ 34 | 35 | В этой статье посмотрим, сколько всего в эти 30 лет уместилось. 36 | А уместилось немало. 37 | 38 | 39 | 40 | .. toctree:: 41 | :maxdepth: 2 42 | :caption: Содержание: 43 | 44 | cli.rst 45 | snmp.rst 46 | api_rpc.rst 47 | netconf.rst 48 | restconf.rst 49 | models.rst 50 | grpc.rst 51 | nowdays.rst 52 | future.rst 53 | horizon.rst 54 | links.rst 55 | conclusion.rst -------------------------------------------------------------------------------- /docs/source/5_history/links.rst: -------------------------------------------------------------------------------- 1 | Полезные ссылки 2 | =============== 3 | 4 | 5 | * Главные RFC: 6 | * `RFC1052 `_: Рекомендации IAB по инструментам управления сетью. Результаты встречи (Апрель 1988) 7 | * `RFC3535 `_: Результаты встречи IAB по инструментам управления сетью (май 2003) 8 | * NETCONF: `RFC4741 `_, `RFC6241 `_ 9 | * RESTCONF: `RFC8040 `_ 10 | * YANG: `RFC6020 `_, `RFC7950 `_ 11 | 12 | 13 | * `Репозиторий с опубликованными YANG-моделями `_ 14 | * `Слайды NANOG 2015 `_ 15 | * `Слайды IETF 98 `_ 16 | * `Слайды IETF 101 `_ 17 | * `SDK Broadcom на github `_ 18 | * Концепция RPC: `Remote Procedure Call (RPC) `_ 19 | * Сайт OpenConfig: `openconfig.net `_ 20 | * `Опубликованные модели OpenConfig `_ 21 | * Хорошая вводная в NETCONF и немного YANG: `YANG Data Modelling and NETCONF `_ 22 | * Продолжение про YANG и немного про NETCONF: `The Road to Model Driven Programmability `_ 23 | * На русском про `NETCONF. Начало `_ 24 | * Если жить не можете, хочется на русском про YANG, и вы воспринимаете художественную речь: `YANG — это имя для вождя `_ 25 | * Спецификация gNMI в его же `репозитории `_ 26 | * `RESTCONF Tutorial - Everything you need to know about RESTCONF in 2020 `_ 27 | * Серия статей про RESTCONF, но рекомендую я её из-за того, что там хорошо разобраны примеры с YANG-моделями: `RESTCONF, NETCONF and YANG `_ 28 | * `Документация по gRPC `_ 29 | * `Блог Романа Додина `_ 30 | * `Блог Антона Карнелюка `_ 31 | * `Блог Михаила Кашина `_ 32 | * `Яндекс Nextop. Про использование CLI для Configuration Management `_ 33 | 34 | -------------------------------------------------------------------------------- /docs/source/5_history/nowdays.rst: -------------------------------------------------------------------------------- 1 | Настоящее сетевой автоматизации 2 | =============================== 3 | 4 | Ну и пришло время подводить итоги? 5 | 6 | | Итого, что же творится в мире сетевой автоматизации сейчас? 7 | | Тут на самом деле вопрос, где вопрошающий и отвечающий находятся на спектре от чед-инженера "руками фигакну тыщу свичей, хорошо, если есть Excel" до непорочного инженера, кругом обложившегося gRPC и OpenConfig'ом с сетевым CI/CD-пайплайном. 8 | | А посередине спектра и ансибль, и питон, и перл, и баш, и го. Где-то CLI, куда-то NETCONF уже внедрили, кто-то по gNMI что-то настраивает и телеметрию снимает. Да добрая половина и SNMPv2 ещё не выключила. 9 | 10 | | У многих конфигурация `Day 0 и 1 `_ плюс-минус автоматизирована - это правда легко. 11 | | Day-N у кого-то решается в полностью ручном режиме, иные раскатывают обновления скриптом или простым Ansible playbook'ом, кто-то даже готовит развесистые плейбуки, основанные на модулях, "поддерживающих" состояние. 12 | | У кого-то есть крутая `CLI-автоматизация `_ , умеющая по-настоящему поддерживать состояние. 13 | | Самые продвинутые укладывают всё в NETCONF, собрав полноценный замкнутый цикл релиза конфигурации. 14 | | А совсем оторванные от земли заставляют производителей поддерживать новую функциональность в OpenConfig. 15 | 16 | В целом описать всё многообразие проявлений автоматизаторской фантазии сегодня просто невозможно. Мы сейчас в мире, в котором чёрный параллелепипед ещё не был признан стандартом в области форм-факторов смартфонов. -------------------------------------------------------------------------------- /docs/source/5_history/restconf.rst: -------------------------------------------------------------------------------- 1 | RESTCONF 2 | ======== 3 | 4 | *Буйные 10-е и забыли* 5 | 6 | .. code-block:: text 7 | 8 | The workshop recommends, with strong consensus from the operators 9 | and rough consensus from the protocol developers, that the 10 | IETF/IRTF should not spend resources on developing HTML-based or 11 | HTTP-based methods for configuration management. 12 | 13 | `RFC3535. Recommendation 6 `_ 14 | 15 | | SSH - это хорошо. Но на сетевую автоматизацию случился спрос, а за ним наплыв сил разработчиков. А вот эти разработчики хорошо шарят в REST, но на курле крутили все эти наши SSH и парсинг текста. 16 | | В компаниях, где начинают заниматься автоматизацией сети, обычно уже есть свой штат разработчиков, инструменты, практики. И они в лучшем случае рассматривают сеть, как ещё одни сервера, а то и ещё один сервис. 17 | | И вот REST API с CRUD им очень знаком. 18 | | Вот и решили парни из циски, джунипера и tail-f: *"а почему бы не запилить REST API в сетевые коробки?"*. Ну пошли и запилили - делов-то. И назвали RESTCONF - всё ещё отзываются боли SNMP. 19 | 20 | `Драфт был опубликован в 2014м `_, а в 2017 мир увидел `RFC8040 `_. 21 | 22 | | Это помесь RESTAPI и NETCONF, которая была призвана упростить управление сетью для WEB-приложений. 23 | | Внутри идеологически это NETCONF с его datastores и способами работать с конфигурацией, однако в качестве транспорта - HTTP с набором операций CRUD, реализованных через стандартные методы (*GET*, *POST*, *PUT*, *PATCH*, *DELETE*). 24 | 25 | | Конфигурационные данные передаются в формате JSON или XML. 26 | | В качестве модели данных используется только те, что написаны на языке YANG - тут уже никакой самодеятельности. 27 | 28 | | С самого начала RESTCONF не затевался как замена NETCONF, а только как более удобный для WEB-приложений способ работать с сетевыми устройствами. То есть они должны сожительствовать. 29 | | При этом обычно на устройстве реализуется один бэкенд, обрабатывающий запросы на работу с конфигурацией и опер.данными от разных фронтов - NETCONF или RESTCONF. То есть в основе одни и те же datastores, один и тот же движок, вычисляющий конфигурационные дельты, но сложность транзакционности и нескольких разных видов конфигураций (``running``, ``candidate``, ``saved``) от пользователя скрыта в случае NETCONF. 30 | 31 | С другой стороны отсутствие в выдаче поисковиков хоть сколько-то серьёзных работ по автоматизации с помощью RESTCONF и даже популистских статей от больших игроков говорит о том, что это всё не более чем баловство. И я намеренно не пишу слово "пока". Лично я в него не верю. 32 | 33 | При этом CRUD не очень гладко ложится на RPC-подход, да и в идее держать открытым на сетевом железе HTTP есть что-то противоестественное, согласитесь? Нет? Ну ладно. 34 | 35 | Просто жаль сил, вложенных в этот протокол. Потому что на пятки ему наступает gRPC/gNMI. -------------------------------------------------------------------------------- /docs/source/6_interfaces/callhome.rst: -------------------------------------------------------------------------------- 1 | Call-Home 2 | ========= 3 | 4 | `RFC8071 `_. 5 | 6 | Это, что называется, звонок домой - способ инициировать соединение с NETCONF/RESTCONF-сервера к клиенту, то есть с сетевой коробки на систему управления. 7 | 8 | На устройстве настраивается IP-адрес NETCONF/RESTCONF-клиента, куда оно отсылает периодически данные по своему состоянию. Либо обращается для того, чтобы зарегистрироваться в системе и забрать свою конфигурацию. 9 | 10 | Применимо для сценариев, когда 11 | 12 | * Новое устройство должно сообщить о себе в систему управления 13 | * Устройство находится за NAT или фаерволом 14 | * Администратор считает, что безопаснее иметь закрытые порты на сетевых элементах и открывать только well-known порт на системе управления 15 | 16 | Подробно тут останавливаться не будем. -------------------------------------------------------------------------------- /docs/source/6_interfaces/conclusion.rst: -------------------------------------------------------------------------------- 1 | Заключение 2 | ========== 3 | 4 | Думаю, что хорошее заключение было в `пятой части книги `_, к которой я и отсылаю читателя. 5 | | Путь нас ожидает неблизкий. Туман медленно рассеивается, открывая новые развилки дорожек, из которых нужно выбирать перспективную. 6 | | Но вот что следует держать в голове. Нам обо всём этом рассказывают на конференциях и пишут в длинных статьях как о свершившемся факте, в то время, как многие вещи всё ещё не работают, а в конце обычно есть приписка *"Adding support of OpenConfig gNMI paves the way for future network automation"*. 7 | 8 | Благодарности 9 | ------------- 10 | 11 | 12 | * `Роману Додину `_ за дельные комментарии как по теоретической, так и по практической частям. А так же за полезный блог и инструменты. `GitHub `_. 13 | * `Кириллу Плетнёву `_ за наведение порядка с NETCONF и YANG - язык, модели, спецификации, форматы данных. И за уместные и остроумные замечания по языкам и библиотекам. `GitHub `_, `fb `_. 14 | * `Александру Лимонову `_ за несколько идеологических замечаний и исправлений фактических ошибок. 15 | * `Александру Балезину `_ за написанную часть про Telemetry. -------------------------------------------------------------------------------- /docs/source/6_interfaces/index.rst: -------------------------------------------------------------------------------- 1 | Часть 6. Интерфейсы взаимодействия с сетевым устройством 2 | ======================================================== 3 | 4 | | В этой части мы раскрываем дерево XML, пробуем на вкус капабилити NETCONF, шлём первые RPC и наконец уже расставим в правильном порядке буквы YANG, OpenConfig, gNMI. 5 | | Практическую пользу вам принесут только обе прочитанные статьи. Вторая без первой будет непонятна. Первая без второй - беллетристика. 6 | 7 | .. figure:: https://fs.linkmeup.ru/images/adsm/5/kdpv1.png 8 | :width: 800 9 | :align: center 10 | 11 | 12 | | Сразу предупреждаю, что это будет большая и нудная статья, потому что автор в очередной раз решил разобраться в чём-то, и опубликовать это разом. И вам, клянусь, ещё повезло, когда на двухсоттысячном символе я придумал, как её можно разделить на две части. 13 | | Тут разберём по косточкам все возможные способы взаимодействия с сетевым железом. 14 | | Лишь вскользь мы заденем CLI и SNMP, как не имеющие практической значимости в контексте этой статьи, разберёмся достаточно глубоко с NETCONF - это новый SNMP или всё же у него есть будущее хотя бы с YANG'ом, продолжим RESTCONF'ом и закончим на интригующем - gRPC. 15 | | Ну а по ходу неминуемо разберёмся с тем, за что с нашими глазами так поступает XML, с концепцией RPC, моделями данных и успеем посмотреть на OpenConfig. 16 | 17 | 18 | .. toctree:: 19 | :maxdepth: 2 20 | :caption: Содержание: 21 | 22 | cli.rst 23 | rpc.rst 24 | netconf.rst 25 | xml.rst 26 | netconf_again.rst 27 | restconf.rst 28 | callhome.rst 29 | grpc.rst 30 | models.rst 31 | yang.rst 32 | model_driven.rst 33 | onemoretime.rst 34 | links.rst 35 | conclusion.rst -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/dumps/grpc.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eucariot/ADSM/4675c76792b95e4cef758e49d858c7e8151f2a38/docs/source/6_interfaces/materials/dumps/grpc.pcap -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/grpc-ping/go-server/go.mod: -------------------------------------------------------------------------------- 1 | module ping-server 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/golang/protobuf v1.4.3 // indirect 7 | golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect 8 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect 9 | golang.org/x/text v0.3.0 // indirect 10 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect 11 | google.golang.org/grpc v1.44.0 // indirect 12 | google.golang.org/protobuf v1.25.0 // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/grpc-ping/go-server/ping-server/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2015 gRPC authors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | // Package main implements a server for Greeter service. 20 | package main 21 | 22 | import ( 23 | "context" 24 | "flag" 25 | "fmt" 26 | "log" 27 | "net" 28 | 29 | "google.golang.org/grpc" 30 | pb "ping-server/ping" 31 | ) 32 | 33 | var ( 34 | port = flag.Int("port", 12345, "The server port") 35 | ) 36 | 37 | // server is used to implement helloworld.GreeterServer. 38 | type server struct { 39 | pb.UnimplementedPingServer 40 | } 41 | 42 | // SayHello implements helloworld.GreeterServer 43 | func (s *server) SendPingReply(ctx context.Context, in *pb.PingRequest) (*pb.PingReply, error) { 44 | log.Printf("Received: %v", in.GetPayload()) 45 | return &pb.PingReply{Message: in.GetPayload() + "-pong"}, nil 46 | } 47 | 48 | func main() { 49 | flag.Parse() 50 | lis, err := net.Listen("tcp", fmt.Sprintf("10.128.0.6:%d", *port)) 51 | if err != nil { 52 | log.Fatalf("failed to listen: %v", err) 53 | } 54 | s := grpc.NewServer() 55 | pb.RegisterPingServer(s, &server{}) 56 | log.Printf("server listening at %v", lis.Addr()) 57 | if err := s.Serve(lis); err != nil { 58 | log.Fatalf("failed to serve: %v", err) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/grpc-ping/protos/ping.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package ping; 4 | 5 | // The ping service definition. 6 | service Ping { 7 | // Sends a ping reply 8 | rpc SendPingReply (PingRequest) returns (PingReply) {} 9 | } 10 | 11 | // The request message containing the ping payload. 12 | message PingRequest { 13 | string payload = 1; 14 | } 15 | 16 | // The response message containing the ping replay 17 | message PingReply { 18 | string message = 1; 19 | } -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/grpc-ping/python-client/ping_client.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from datetime import datetime 4 | 5 | import grpc 6 | 7 | import ping_pb2 8 | import ping_pb2_grpc 9 | 10 | server = "84.201.157.17:12345" 11 | # server = "localhost:12345" 12 | 13 | 14 | def run(payload) -> None: 15 | with grpc.insecure_channel(server) as channel: 16 | stub = ping_pb2_grpc.PingStub(channel) 17 | start_time = datetime.now() 18 | response = stub.SendPingReply(ping_pb2.PingRequest(payload=payload)) 19 | rtt = round((datetime.now() - start_time).total_seconds()*1000, 2) 20 | print(f"Ping response received: {response.message} time={rtt}ms") 21 | 22 | 23 | if __name__ == "__main__": 24 | payload = sys.argv[1] 25 | 26 | while True: 27 | run(payload) 28 | time.sleep(1) 29 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/grpc-ping/python-client/ping_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | """Client and server classes corresponding to protobuf-defined services.""" 3 | import grpc 4 | 5 | import ping_pb2 as ping__pb2 6 | 7 | 8 | class PingStub(object): 9 | """The ping service definition. 10 | """ 11 | 12 | def __init__(self, channel): 13 | """Constructor. 14 | 15 | Args: 16 | channel: A grpc.Channel. 17 | """ 18 | self.SendPingReply = channel.unary_unary( 19 | '/ping.Ping/SendPingReply', 20 | request_serializer=ping__pb2.PingRequest.SerializeToString, 21 | response_deserializer=ping__pb2.PingReply.FromString, 22 | ) 23 | 24 | 25 | class PingServicer(object): 26 | """The ping service definition. 27 | """ 28 | 29 | def SendPingReply(self, request, context): 30 | """Sends a ping reply 31 | """ 32 | context.set_code(grpc.StatusCode.UNIMPLEMENTED) 33 | context.set_details('Method not implemented!') 34 | raise NotImplementedError('Method not implemented!') 35 | 36 | 37 | def add_PingServicer_to_server(servicer, server): 38 | rpc_method_handlers = { 39 | 'SendPingReply': grpc.unary_unary_rpc_method_handler( 40 | servicer.SendPingReply, 41 | request_deserializer=ping__pb2.PingRequest.FromString, 42 | response_serializer=ping__pb2.PingReply.SerializeToString, 43 | ), 44 | } 45 | generic_handler = grpc.method_handlers_generic_handler( 46 | 'ping.Ping', rpc_method_handlers) 47 | server.add_generic_rpc_handlers((generic_handler,)) 48 | 49 | 50 | # This class is part of an EXPERIMENTAL API. 51 | class Ping(object): 52 | """The ping service definition. 53 | """ 54 | 55 | @staticmethod 56 | def SendPingReply(request, 57 | target, 58 | options=(), 59 | channel_credentials=None, 60 | call_credentials=None, 61 | insecure=False, 62 | compression=None, 63 | wait_for_ready=None, 64 | timeout=None, 65 | metadata=None): 66 | return grpc.experimental.unary_unary(request, target, '/ping.Ping/SendPingReply', 67 | ping__pb2.PingRequest.SerializeToString, 68 | ping__pb2.PingReply.FromString, 69 | options, channel_credentials, 70 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata) 71 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/grpc-ping/python-server/ping_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | """Client and server classes corresponding to protobuf-defined services.""" 3 | import grpc 4 | 5 | import ping_pb2 as ping__pb2 6 | 7 | 8 | class PingStub(object): 9 | """The ping service definition. 10 | """ 11 | 12 | def __init__(self, channel): 13 | """Constructor. 14 | 15 | Args: 16 | channel: A grpc.Channel. 17 | """ 18 | self.SendPingReply = channel.unary_unary( 19 | '/ping.Ping/SendPingReply', 20 | request_serializer=ping__pb2.PingRequest.SerializeToString, 21 | response_deserializer=ping__pb2.PingReply.FromString, 22 | ) 23 | 24 | 25 | class PingServicer(object): 26 | """The ping service definition. 27 | """ 28 | 29 | def SendPingReply(self, request, context): 30 | """Sends a ping reply 31 | """ 32 | context.set_code(grpc.StatusCode.UNIMPLEMENTED) 33 | context.set_details('Method not implemented!') 34 | raise NotImplementedError('Method not implemented!') 35 | 36 | 37 | def add_PingServicer_to_server(servicer, server): 38 | rpc_method_handlers = { 39 | 'SendPingReply': grpc.unary_unary_rpc_method_handler( 40 | servicer.SendPingReply, 41 | request_deserializer=ping__pb2.PingRequest.FromString, 42 | response_serializer=ping__pb2.PingReply.SerializeToString, 43 | ), 44 | } 45 | generic_handler = grpc.method_handlers_generic_handler( 46 | 'ping.Ping', rpc_method_handlers) 47 | server.add_generic_rpc_handlers((generic_handler,)) 48 | 49 | 50 | # This class is part of an EXPERIMENTAL API. 51 | class Ping(object): 52 | """The ping service definition. 53 | """ 54 | 55 | @staticmethod 56 | def SendPingReply(request, 57 | target, 58 | options=(), 59 | channel_credentials=None, 60 | call_credentials=None, 61 | insecure=False, 62 | compression=None, 63 | wait_for_ready=None, 64 | timeout=None, 65 | metadata=None): 66 | return grpc.experimental.unary_unary(request, target, '/ping.Ping/SendPingReply', 67 | ping__pb2.PingRequest.SerializeToString, 68 | ping__pb2.PingReply.FromString, 69 | options, channel_credentials, 70 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata) 71 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/grpc-ping/python-server/ping_server.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import logging 3 | 4 | import grpc 5 | 6 | import ping_pb2 7 | import ping_pb2_grpc 8 | 9 | 10 | class Ping(ping_pb2_grpc.PingServicer): 11 | 12 | async def SendPingReply(self, request,context): 13 | return ping_pb2.PingReply(message=f"{request.payload}-pong") 14 | 15 | 16 | async def serve(): 17 | server = grpc.aio.server() 18 | ping_pb2_grpc.add_PingServicer_to_server(Ping(), server) 19 | listen_addr = "10.128.0.6:12345" 20 | server.add_insecure_port(listen_addr) 21 | logging.info(f"Now listening for ping on {listen_addr}") 22 | await server.start() 23 | await server.wait_for_termination() 24 | 25 | 26 | if __name__ == "__main__": 27 | logging.basicConfig(level=logging.INFO) 28 | asyncio.run(serve()) 29 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/scripts/gnmiclient_capabilities.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from pygnmi.client import gNMIclient 4 | import json 5 | 6 | host = { 7 | "ip_address": "bcn-spine-1.arista", 8 | "nos": "arista-eos", 9 | "port": 6030, 10 | "username": "Bescheidenheit und", 11 | "password": "Pflichttreue" 12 | } 13 | 14 | if __name__ == "__main__": 15 | with gNMIclient(target=(host["ip_address"], host["port"]), username=host["username"], 16 | password=host["password"], insecure=True) as gc: 17 | 18 | result = gc.capabilities() 19 | 20 | print(json.dumps(result)) 21 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/scripts/gnmiclient_get_addresses.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from pygnmi.client import gNMIclient 4 | import json 5 | 6 | host = { 7 | "ip_address": "bcn-spine-1.arista", 8 | "nos": "arista-eos", 9 | "port": 6030, 10 | "username": "werden nur", 11 | "password": "in Romanen belohnt" 12 | } 13 | 14 | if __name__ == "__main__": 15 | paths = ['openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/ipv4/addresses/address/config'] 16 | 17 | with gNMIclient(target=(host["ip_address"], host["port"]), username=host["username"], 18 | password=host["password"], insecure=True) as gc: 19 | 20 | result = gc.get(path=paths, encoding='json') 21 | 22 | print(json.dumps(result)) 23 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/scripts/gnmiclient_set_bgp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from pygnmi.client import gNMIclient 4 | import json 5 | 6 | host = ("bcn-spine-1.arista", 6030) 7 | 8 | set_config = [ 9 | ( 10 | "/network-instances/network-instance[name=default]/protocols/protocol[name=BGP]/bgp/neighbors/neighbor[neighbor-address=169.254.1.2]", 11 | { 12 | "config": { 13 | "peer-as": "4228186112" 14 | } 15 | } 16 | ) 17 | ] 18 | 19 | 20 | if __name__ == "__main__": 21 | print(set_config) 22 | with gNMIclient(target=host, username="Im Leben", 23 | password="werden", insecure=True) as gc: 24 | 25 | result = gc.set(update=set_config) 26 | 27 | print(json.dumps(result)) 28 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/scripts/gnmiclient_set_hostname.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from pygnmi.client import gNMIclient 4 | import json 5 | 6 | host = ("bcn-spine-1.arista", 6030) 7 | 8 | set_config = [ 9 | ( 10 | "openconfig-system:system", 11 | { 12 | "config": { 13 | "hostname": "bcn-spine-1.barista-karatista" 14 | } 15 | } 16 | ) 17 | ] 18 | if __name__ == "__main__": 19 | 20 | with gNMIclient(target=host, username="sie", 21 | password="ausgenutzt", insecure=True) as gc: 22 | 23 | result = gc.set(update=set_config) 24 | 25 | print(json.dumps(result)) 26 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/scripts/netconf_edit_config.py: -------------------------------------------------------------------------------- 1 | from ncclient import manager 2 | import xmltodict 3 | 4 | rpc = """ 5 | 6 | 7 | 8 | 9 | ge-0/0/0 10 | Mit der Dummheit kämpfen Götter selbst vergebens. 11 | 12 | 13 | 14 | 15 | """ 16 | 17 | if __name__ == "__main__": 18 | with manager.connect( 19 | host="kzn-spine-0.juniper", 20 | ssh_config=True, 21 | hostkey_verify=False, 22 | device_params={"name": "junos"} 23 | ) as m: 24 | result = m.edit_config(target="candidate", config=rpc).data_xml 25 | m.commit() 26 | result_dict = xmltodict.parse(result) 27 | print(result_dict) 28 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/scripts/netconfg_get_config.py: -------------------------------------------------------------------------------- 1 | from ncclient import manager 2 | import xmltodict 3 | 4 | rpc = """ 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | """ 13 | 14 | if __name__ == "__main__": 15 | with manager.connect( 16 | host="kzn-spine-0.juniper", 17 | ssh_config=True, 18 | hostkey_verify=False, 19 | device_params={"name": "junos"} 20 | ) as m: 21 | result = m.get_config("running", rpc).data_xml 22 | result_dict = xmltodict.parse(result) 23 | print(f'hostname is {result_dict["rpc-reply"]["data"]["configuration"]["system"]["host-name"]}') 24 | 25 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/scripts/pyangbind_gnmiclient_set.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from pygnmi.client import gNMIclient 3 | from oc_interfaces import openconfig_interfaces as oc_if 4 | import json 5 | 6 | host = ("bcn-spine-1.arista", 6030) 7 | 8 | 9 | model = oc_if() 10 | a = model.get() 11 | a = model.interfaces.interface.add("GigabitEthernet2") 12 | a.config.name = "GigabitEthernet2" 13 | print(json.dumps(a.get()['config'])) 14 | 15 | 16 | set_config = [ 17 | ( 18 | "openconfig-interfaces:interfaces", 19 | { 20 | "config": a.get()['config'] 21 | } 22 | ) 23 | ] 24 | if __name__ == "__main__": 25 | 26 | with gNMIclient(target=host, username="und dann", 27 | password="beiseite geschoben", insecure=True) as gc: 28 | 29 | result = gc.set(update=set_config) 30 | 31 | print(json.dumps(result)) 32 | 33 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/materials/scripts/scrapli_get_config.py: -------------------------------------------------------------------------------- 1 | from scrapli_netconf.driver import NetconfDriver 2 | 3 | rpc = """ 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | """ 12 | 13 | device = { 14 | "host": "kzn-spine-0.juniper", 15 | "auth_strict_key": False, 16 | "port": 22 17 | } 18 | 19 | if __name__ == "__main__": 20 | with NetconfDriver(**device) as conn: 21 | response = conn.get_config("running", rpc) 22 | 23 | print(response.result) 24 | -------------------------------------------------------------------------------- /docs/source/6_interfaces/model_driven.rst: -------------------------------------------------------------------------------- 1 | Model Driven Programmability 2 | ============================ 3 | 4 | Так что же это такое? Ведомая моделью программируемость? Теперь, после двух статей, нам хватит пары минут, чтобы разобраться что это такое. 5 | 6 | Давайте вернёмся к `4-й части АДСМ `_, где я использовал позаимствованную у Дмитрия Тесля картинку. 7 | 8 | .. figure:: https://dteslya.engineer/images/2020-10-netdevops-pipeline.png 9 | 10 | `Источник: dteslya.engineer/network_automaiton_101 `_ 11 | 12 | Она ведь очень понятная? Inventory, Git с шаблонами конфигурации, рендер, валидация, применение. 13 | 14 | | Где закопаны два мешка с человеко-неделями? Под шаблонами с генераторами и под системами применения конфигурации. 15 | | Со вторым пытаются бороться NETCONF, RESTCONF, gNMI. 16 | | А с первым - модели. 17 | 18 | Проблема в том, что шаблоны мы составляем руками на основе изучения документации, интерфейса коробки и действуем методом проб и ошибок, вообще-то. Если нужна проверка типов, диапазонов, если меняется иерархия - будьте добры сами всё это написать и обработать. И, окончив, уехать в сумасшедший дом, учить друзей джинджа-программированию. 19 | 20 | Model Driven меняет картину следующим образом: 21 | 22 | 23 | .. figure:: https://fs.linkmeup.ru/images/adsm/5/model-driven.png 24 | :width: 800 25 | :align: center 26 | 27 | *Не могу найти, откуда брал эту картинку.* 28 | 29 | | Здесь шаблоны конфигурации заменяются на YANG-модель (в данном случае OpenConfig). 30 | | Из инвентарки (топологии) и этих моделей рендерится конфиг, который с помощью RPC (тут gRPC) прогружается на коробку. 31 | 32 | Model Driven означает тут, что мы 33 | 34 | | А) не думаем (или думаем меньше) про иерархию, типы данных. Перестаём мыслить тегами XML. 35 | | Б) Модель определяет, как будет выглядеть конфигурация, как с ней работать. 36 | | В) Использование точно такой же модели на устройстве гарантирует, что отправленное нами, будет принято и валидно на той стороне, коль скоро оно валидно на этой. 37 | 38 | | Иными словами именно модель управляет тем, как мы и железо будет работать с конфигурацией. 39 | | Вот и вся суть. -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # http://www.sphinx-doc.org/en/master/config 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'ADSM' 21 | copyright = '2021, eucariot' 22 | author = 'eucariot' 23 | 24 | # The full version, including alpha/beta/rc tags 25 | release = '0.1.0' 26 | 27 | 28 | # -- General configuration --------------------------------------------------- 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = [ 34 | ] 35 | 36 | # Add any paths that contain templates here, relative to this directory. 37 | templates_path = ['_templates'] 38 | 39 | # The language for content autogenerated by Sphinx. Refer to documentation 40 | # for a list of supported languages. 41 | # 42 | # This is also used if you do content translation via gettext catalogs. 43 | # Usually you set "language" from the command line for these cases. 44 | language = 'ru' 45 | 46 | # List of patterns, relative to source directory, that match files and 47 | # directories to ignore when looking for source files. 48 | # This pattern also affects html_static_path and html_extra_path. 49 | exclude_patterns = [] 50 | 51 | 52 | # -- Options for HTML output ------------------------------------------------- 53 | 54 | # The theme to use for HTML and HTML Help pages. See the documentation for 55 | # a list of builtin themes. 56 | # 57 | # html_theme = 'alabaster' 58 | html_theme = 'sphinx_rtd_theme' 59 | 60 | # Add any paths that contain custom static files (such as style sheets) here, 61 | # relative to this directory. They are copied after the builtin static files, 62 | # so a file named "default.css" will overwrite the builtin "default.css". 63 | html_static_path = ['_static'] 64 | -------------------------------------------------------------------------------- /docs/source/contents.rst: -------------------------------------------------------------------------------- 1 | Автоматизация для самых маленьких 2 | ================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | 7 | 0_planning/planning.rst 8 | 1_virtualization/index.rst 9 | 2_network_design/index.rst 10 | 3_ipam_dcim/index.rst 11 | 4_lifecycle/index.rst 12 | 5_history/index.rst 13 | 6_interfaces/index.rst -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Автоматизация для самых маленьких 2 | ================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Содержание: 7 | 8 | 0_planning/planning.rst 9 | 1_virtualization/index.rst 10 | 2_network_design/index.rst 11 | 3_ipam_dcim/index.rst 12 | 4_lifecycle/index.rst 13 | 5_history/index.rst 14 | 6_interfaces/index.rst -------------------------------------------------------------------------------- /x.-ztp/0.-ztp.md: -------------------------------------------------------------------------------- 1 | Существует несколько подходов к ZTP. 2 | --------------------------------------------------------------------------------