From 1b1cc7986813c65b608ace38bf497622eb74f1cf Mon Sep 17 00:00:00 2001 From: Trae Santiago Date: Wed, 10 Jan 2024 11:13:38 -0600 Subject: added new NPTv6/DHCPv6 example --- docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.png | Bin 0 -> 349078 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.png (limited to 'docs/_static') diff --git a/docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.png b/docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.png new file mode 100644 index 00000000..297fdd11 Binary files /dev/null and b/docs/_static/images/vyos_1_5_nat66_dhcpv6_wdummy.png differ -- cgit v1.2.3 From cfb7e8186d83e45092f361f9717c9542bfad053b Mon Sep 17 00:00:00 2001 From: aapostoliuk Date: Fri, 19 Jan 2024 12:39:38 +0200 Subject: Updated DPD and close-action values in IPSEC Changed from 'hold' to 'trap' and from 'restart' to 'start' in close-action. Changed from 'hold' to 'trap' in DPD action. --- docs/_static/images/IPSec_close_action_settings.jpg | Bin 62330 -> 70253 bytes docs/configuration/vpn/ipsec.rst | 12 +++++++----- docs/configuration/vpn/site2site_ipsec.rst | 12 ++++++------ 3 files changed, 13 insertions(+), 11 deletions(-) (limited to 'docs/_static') diff --git a/docs/_static/images/IPSec_close_action_settings.jpg b/docs/_static/images/IPSec_close_action_settings.jpg index 6996f857..a4e258cc 100644 Binary files a/docs/_static/images/IPSec_close_action_settings.jpg and b/docs/_static/images/IPSec_close_action_settings.jpg differ diff --git a/docs/configuration/vpn/ipsec.rst b/docs/configuration/vpn/ipsec.rst index b6ee86af..fad69bc3 100644 --- a/docs/configuration/vpn/ipsec.rst +++ b/docs/configuration/vpn/ipsec.rst @@ -49,9 +49,9 @@ VyOS IKE group has the next options: * ``none`` set action to none (default); - * ``hold`` set action to hold; + * ``trap`` installs a trap policy for the CHILD_SA; - * ``restart`` set action to restart; + * ``start`` tries to immediately re-create the CHILD_SA; * ``dead-peer-detection`` controls the use of the Dead Peer Detection protocol (DPD, RFC 3706) where R_U_THERE notification messages (IKEv1) or empty @@ -60,11 +60,13 @@ VyOS IKE group has the next options: * ``action`` keep-alive failure action: - * ``hold`` set action to hold (default) + * ``trap`` installs a trap policy, which will catch matching traffic + and tries to re-negotiate the tunnel on-demand; - * ``clear`` set action to clear; + * ``clear`` closes the CHILD_SA and does not take further action (default); - * ``restart`` set action to restart; + * ``restart`` immediately tries to re-negotiate the CHILD_SA + under a fresh IKE_SA; * ``interval`` keep-alive interval in seconds <2-86400> (default 30); diff --git a/docs/configuration/vpn/site2site_ipsec.rst b/docs/configuration/vpn/site2site_ipsec.rst index 23df1b76..78cadfb5 100644 --- a/docs/configuration/vpn/site2site_ipsec.rst +++ b/docs/configuration/vpn/site2site_ipsec.rst @@ -317,7 +317,7 @@ Imagine the following topology set vpn ipsec esp-group ESP_DEFAULT proposal 10 encryption 'aes256gcm128' set vpn ipsec esp-group ESP_DEFAULT proposal 10 hash 'sha256' set vpn ipsec ike-group IKEv2_DEFAULT close-action 'none' - set vpn ipsec ike-group IKEv2_DEFAULT dead-peer-detection action 'hold' + set vpn ipsec ike-group IKEv2_DEFAULT dead-peer-detection action 'trap' set vpn ipsec ike-group IKEv2_DEFAULT dead-peer-detection interval '30' set vpn ipsec ike-group IKEv2_DEFAULT dead-peer-detection timeout '120' set vpn ipsec ike-group IKEv2_DEFAULT disable-mobike @@ -357,7 +357,7 @@ Imagine the following topology set vpn ipsec esp-group ESP_DEFAULT proposal 10 encryption 'aes256gcm128' set vpn ipsec esp-group ESP_DEFAULT proposal 10 hash 'sha256' set vpn ipsec ike-group IKEv2_DEFAULT close-action 'none' - set vpn ipsec ike-group IKEv2_DEFAULT dead-peer-detection action 'hold' + set vpn ipsec ike-group IKEv2_DEFAULT dead-peer-detection action 'trap' set vpn ipsec ike-group IKEv2_DEFAULT dead-peer-detection interval '30' set vpn ipsec ike-group IKEv2_DEFAULT dead-peer-detection timeout '120' set vpn ipsec ike-group IKEv2_DEFAULT disable-mobike @@ -397,18 +397,18 @@ Key Parameters: routes installed in the default table 220 for site-to-site ipsec. It is mostly used with VTI configuration. -* ``dead-peer-detection action = clear | hold | restart`` - R_U_THERE +* ``dead-peer-detection action = clear | trap | restart`` - R_U_THERE notification messages(IKEv1) or empty INFORMATIONAL messages (IKEv2) are periodically sent in order to check the liveliness of the IPsec peer. The - values clear, hold, and restart all activate DPD and determine the action to + values clear, trap, and restart all activate DPD and determine the action to perform on a timeout. With ``clear`` the connection is closed with no further actions taken. - ``hold`` installs a trap policy, which will catch matching traffic and tries + ``trap`` installs a trap policy, which will catch matching traffic and tries to re-negotiate the connection on demand. ``restart`` will immediately trigger an attempt to re-negotiate the connection. -* ``close-action = none | clear | hold | restart`` - defines the action to take +* ``close-action = none | clear | trap | start`` - defines the action to take if the remote peer unexpectedly closes a CHILD_SA (see above for meaning of values). A closeaction should not be used if the peer uses reauthentication or uniqueids. -- cgit v1.2.3 From ac4f69bed71398a278b40b4206a2c993b908cc28 Mon Sep 17 00:00:00 2001 From: mkorobeinikov <92354771+mkorobeinikov@users.noreply.github.com> Date: Sat, 13 Jan 2024 08:09:42 +0300 Subject: the article about Terraform the article about Terraform+AWS+Azure+Ansible+VMware --- docs/_static/images/aws.png | Bin 0 -> 150759 bytes docs/automation/index.rst | 1 + docs/automation/vyos-terraform.rst | 1036 ++++++++++++++++++++++++++++++++++++ 3 files changed, 1037 insertions(+) create mode 100644 docs/_static/images/aws.png create mode 100644 docs/automation/vyos-terraform.rst (limited to 'docs/_static') diff --git a/docs/_static/images/aws.png b/docs/_static/images/aws.png new file mode 100644 index 00000000..c1c111bb Binary files /dev/null and b/docs/_static/images/aws.png differ diff --git a/docs/automation/index.rst b/docs/automation/index.rst index ee8282ac..ecabff7a 100644 --- a/docs/automation/index.rst +++ b/docs/automation/index.rst @@ -12,6 +12,7 @@ VyOS Automation vyos-api vyos-ansible + vyos-terraform vyos-napalm vyos-netmiko vyos-salt diff --git a/docs/automation/vyos-terraform.rst b/docs/automation/vyos-terraform.rst new file mode 100644 index 00000000..75967202 --- /dev/null +++ b/docs/automation/vyos-terraform.rst @@ -0,0 +1,1036 @@ +:lastproofread: 2024-01-11 + +.. _vyos-terraform: + +Terraform +========= + +VyOS supports develop infrastructia via Terraform and provisioning via ansible. +Need to install ``Terraform`` + +Structure of files + +.. code-block:: none + + . + ├── main.tf + ├── version.tf + ├── variables.tf + └── terraform.tfvars + +Run Terraform +------------- + +.. code-block:: none + + #cd /your folder + #terraform init + #terraform plan + #terraform apply + #yes + + +Deploying vyos in the AWS cloud +------------------------------- +With the help of terraforms, you can quickly deploy Vyos-based infrastructure in the AWS cloud. If necessary, the infrastructure can be removed using terraform. +Also we will make provisioning using Ansible. + +Structure of files Terrafom + +.. code-block:: none + + . + ├── vyos.tf + └── var.tf + +File contents +------------- + +vyos.tf + +.. code-block:: none + + terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } + } + + provider "aws" { + access_key = var.access + secret_key = var.secret + region = var.region + } + + variable "region" { + default = "us-east-1" + description = "AWS Region" + } + + variable "ami" { + default = "ami-**************" # ami image please enter your details + description = "Amazon Machine Image ID for VyOS" + } + + variable "type" { + default = "t2.micro" + description = "Size of VM" + } + + # my resource for VyOS + + resource "aws_instance" "myVyOSec2" { + ami = var.ami + key_name = "mykeyname" # Please enter your details + security_groups = ["my_sg"] # Please enter your details + instance_type = var.type + tags = { + name = "VyOS System" + } + } + + output "my_IP"{ + value = aws_instance.myVyOSec2.public_ip + } + + + #IP of aws instance copied to a file ip.txt in local system Terraform + + resource "local_file" "ip" { + content = aws_instance.myVyOSec2.public_ip + filename = "ip.txt" + } + + #connecting to the Ansible control node using SSH connection + + resource "null_resource" "SSHconnection1" { + depends_on = [aws_instance.myVyOSec2] + connection { + type = "ssh" + user = "root" + password = var.password + host = var.host + } + #copying the ip.txt file to the Ansible control node from local system + provisioner "file" { + source = "ip.txt" + destination = "/root/aws/ip.txt" # The folder of your Ansible project + } + } + + resource "null_resource" "SSHconnection2" { + depends_on = [aws_instance.myVyOSec2] + connection { + type = "ssh" + user = "root" + password = var.password + host = var.host + } + #command to run Ansible playbook on remote Linux OS + provisioner "remote-exec" { + inline = [ + "cd /root/aws/", + "ansible-playbook instance.yml" + ] + } + } + + +var.tf + +.. code-block:: none + + variable "password" { + description = "pass for Ansible" + type = string + sensitive = true + } + variable "host"{ + description = "The IP of my Ansible" + } + variable "access" { + description = "my access_key for AWS" + type = string + sensitive = true + } + variable "secret" { + description = "my secret_key for AWS" + type = string + sensitive = true + } + + +Structure of files Ansible + +.. code-block:: none + + . + ├── group_vars + └── all + ├── ansible.cfg + ├── mykey.pem + └── instance.yml + + +File contents +------------- + +ansible.cfg + +.. code-block:: none + + [defaults] + inventory = /root/aws/ip.txt + host_key_checking= False + private_key_file = /root/aws/mykey.pem + remote_user=vyos + +mykey.pem + +.. code-block:: none + + -----BEGIN OPENSSH PRIVATE KEY----- + + Copy your key.pem from AWS + + -----END OPENSSH PRIVATE KEY----- + +instance.yml + +.. code-block:: none + + - name: integration of terraform and ansible + hosts: all + gather_facts: 'no' + + tasks: + + - name: "Wait 300 seconds, but only start checking after 60 seconds" + wait_for_connection: + delay: 60 + timeout: 300 + + - name: "Configure general settings for the vyos hosts group" + vyos_config: + lines: + - set system name-server 8.8.8.8 + save: + true + + +all + +.. code-block:: none + + ansible_connection: ansible.netcommon.network_cli + ansible_network_os: vyos.vyos.vyos + ansible_user: vyos + +AWS_terraform_ansible_single_vyos_instance +------------------------------------------ + +How to create a single instance and install your configuration using Terraform+Ansible+AWS +Step by step: + +AWS +--- + +1.1 Create an account with AWS and get your "access_key", "secret key" + +1.2 Create a key pair and download your .pem key + +1.3 Create a security group for the new VyOS instance + +Terraform +--------- + +2.1 Create a UNIX or Windows instance + +2.2 Download and install Terraform + +2.3 Create the folder for example ../awsvyos/ + +2.4 Copy all files into your Terraform project (vyos.tf, var.tf) +2.4.1 Please type the information into the strings 22, 35, 36 of file "vyos.tf" + +2.5 Type the commands : + + #cd /your folder + + #terraform init + +Ansible +------- + +3.1 Create a UNIX instance + +3.2 Download and install Ansible + +3.3 Create the folder for example /root/aws/ + +3.4 Copy all files from my folder /Ansible into your Ansible project (ansible.cfg, instance.yml, mykey.pem) + +mykey.pem you have to get using step 1.2 + +Start +----- + +4.1 Type the commands on your Terrafom instance: + + #cd /your folder + + #terraform plan + + #terraform apply + + #yes + +.. image:: /_static/images/aws.png + :width: 80% + :align: center + :alt: Network Topology Diagram + + + +Deploying vyos in the Azure cloud +--------------------------------- +With the help of terraforms, you can quickly deploy Vyos-based infrastructure in the Azure cloud. If necessary, the infrastructure can be removed using terraform. + +Structure of files Terrafom + +.. code-block:: none + + . + ├── main.tf + └── variables.tf + +File contents +------------- + +main.tf + +.. code-block:: none + + ############################################################################## + # HashiCorp Guide to Using Terraform on Azure + # This Terraform configuration will create the following: + # Resource group with a virtual network and subnet + # An VyOS server without ssh key (only login+password) + ############################################################################## + + # Chouse a provider + + provider "azurerm" { + features {} + } + + # Create a resource group. In Azure every resource belongs to a + # resource group. + + resource "azurerm_resource_group" "azure_vyos" { + name = "${var.resource_group}" + location = "${var.location}" + } + + # The next resource is a Virtual Network. + + resource "azurerm_virtual_network" "vnet" { + name = "${var.virtual_network_name}" + location = "${var.location}" + address_space = ["${var.address_space}"] + resource_group_name = "${var.resource_group}" + } + + # Build a subnet to run our VMs in. + + resource "azurerm_subnet" "subnet" { + name = "${var.prefix}subnet" + virtual_network_name = "${azurerm_virtual_network.vnet.name}" + resource_group_name = "${var.resource_group}" + address_prefixes = ["${var.subnet_prefix}"] + } + + ############################################################################## + # Build an VyOS VM from the Marketplace + # To finde nessesery image use the command: + # + # az vm image list --offer vyos --all + # + # Now that we have a network, we'll deploy an VyOS server. + # An Azure Virtual Machine has several components. In this example we'll build + # a security group, a network interface, a public ip address, a storage + # account and finally the VM itself. Terraform handles all the dependencies + # automatically, and each resource is named with user-defined variables. + ############################################################################## + + + # Security group to allow inbound access on port 22 (ssh) + + resource "azurerm_network_security_group" "vyos-sg" { + name = "${var.prefix}-sg" + location = "${var.location}" + resource_group_name = "${var.resource_group}" + + security_rule { + name = "SSH" + priority = 100 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "${var.source_network}" + destination_address_prefix = "*" + } + } + + # A network interface. + + resource "azurerm_network_interface" "vyos-nic" { + name = "${var.prefix}vyos-nic" + location = "${var.location}" + resource_group_name = "${var.resource_group}" + + ip_configuration { + name = "${var.prefix}ipconfig" + subnet_id = "${azurerm_subnet.subnet.id}" + private_ip_address_allocation = "Dynamic" + public_ip_address_id = "${azurerm_public_ip.vyos-pip.id}" + } + } + + # Add a public IP address. + + resource "azurerm_public_ip" "vyos-pip" { + name = "${var.prefix}-ip" + location = "${var.location}" + resource_group_name = "${var.resource_group}" + allocation_method = "Dynamic" + } + + # Build a virtual machine. This is a standard VyOS instance from Marketplace. + + resource "azurerm_virtual_machine" "vyos" { + name = "${var.hostname}-vyos" + location = "${var.location}" + resource_group_name = "${var.resource_group}" + vm_size = "${var.vm_size}" + + network_interface_ids = ["${azurerm_network_interface.vyos-nic.id}"] + delete_os_disk_on_termination = "true" + + # To finde an information about the plan use the command: + # az vm image list --offer vyos --all + + plan { + publisher = "sentriumsl" + name = "vyos-1-3" + product = "vyos-1-2-lts-on-azure" + } + + storage_image_reference { + publisher = "${var.image_publisher}" + offer = "${var.image_offer}" + sku = "${var.image_sku}" + version = "${var.image_version}" + } + + storage_os_disk { + name = "${var.hostname}-osdisk" + managed_disk_type = "Standard_LRS" + caching = "ReadWrite" + create_option = "FromImage" + } + + os_profile { + computer_name = "${var.hostname}" + admin_username = "${var.admin_username}" + admin_password = "${var.admin_password}" + } + + os_profile_linux_config { + disable_password_authentication = false + } + } + + data "azurerm_public_ip" "example" { + depends_on = ["azurerm_virtual_machine.vyos"] + name = "vyos-ip" + resource_group_name = "${var.resource_group}" + } + output "public_ip_address" { + value = data.azurerm_public_ip.example.ip_address + } + + # IP of AZ instance copied to a file ip.txt in local system + + resource "local_file" "ip" { + content = data.azurerm_public_ip.example.ip_address + filename = "ip.txt" + } + + #Connecting to the Ansible control node using SSH connection + + resource "null_resource" "nullremote1" { + depends_on = ["azurerm_virtual_machine.vyos"] + connection { + type = "ssh" + user = "root" + password = var.password + host = var.host + } + + # Copying the ip.txt file to the Ansible control node from local system + + provisioner "file" { + source = "ip.txt" + destination = "/root/az/ip.txt" + } + } + + resource "null_resource" "nullremote2" { + depends_on = ["azurerm_virtual_machine.vyos"] + connection { + type = "ssh" + user = "root" + password = var.password + host = var.host + } + + # Command to run ansible playbook on remote Linux OS + + provisioner "remote-exec" { + + inline = [ + "cd /root/az/", + "ansible-playbook instance.yml" + ] + } + } + + + +variables.tf + +.. code-block:: none + + ############################################################################## + # Variables File + # + # Here is where we store the default values for all the variables used in our + # Terraform code. + ############################################################################## + + variable "resource_group" { + description = "The name of your Azure Resource Group." + default = "my_resource_group" + } + + variable "prefix" { + description = "This prefix will be included in the name of some resources." + default = "vyos" + } + + variable "hostname" { + description = "Virtual machine hostname. Used for local hostname, DNS, and storage-related names." + default = "vyos_terraform" + } + + variable "location" { + description = "The region where the virtual network is created." + default = "centralus" + } + + variable "virtual_network_name" { + description = "The name for your virtual network." + default = "vnet" + } + + variable "address_space" { + description = "The address space that is used by the virtual network. You can supply more than one address space. Changing this forces a new resource to be created." + default = "10.0.0.0/16" + } + + variable "subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.0.10.0/24" + } + + variable "storage_account_tier" { + description = "Defines the storage tier. Valid options are Standard and Premium." + default = "Standard" + } + + variable "storage_replication_type" { + description = "Defines the replication type to use for this storage account. Valid options include LRS, GRS etc." + default = "LRS" + } + + # The most chippers size + + variable "vm_size" { + description = "Specifies the size of the virtual machine." + default = "Standard_B1s" + } + + variable "image_publisher" { + description = "Name of the publisher of the image (az vm image list)" + default = "sentriumsl" + } + + variable "image_offer" { + description = "Name of the offer (az vm image list)" + default = "vyos-1-2-lts-on-azure" + } + + variable "image_sku" { + description = "Image SKU to apply (az vm image list)" + default = "vyos-1-3" + } + + variable "image_version" { + description = "Version of the image to apply (az vm image list)" + default = "1.3.3" + } + + variable "admin_username" { + description = "Administrator user name" + default = "vyos" + } + + variable "admin_password" { + description = "Administrator password" + default = "Vyos0!" + } + + variable "source_network" { + description = "Allow access from this network prefix. Defaults to '*'." + default = "*" + } + + variable "password" { + description = "pass for Ansible" + type = string + sensitive = true + } + variable "host"{ + description = "IP of my Ansible" + } + + +Structure of files Ansible + +.. code-block:: none + + . + ├── group_vars + └── all + ├── ansible.cfg + └── instance.yml + + +File contents +------------- + +ansible.cfg + +.. code-block:: none + + [defaults] + inventory = /root/az/ip.txt + host_key_checking= False + remote_user=vyos + + +instance.yml + +.. code-block:: none + + - name: integration of terraform and ansible + hosts: all + gather_facts: 'no' + + tasks: + + - name: "Wait 300 seconds, but only start checking after 60 seconds" + wait_for_connection: + delay: 60 + timeout: 300 + + - name: "Configure general settings for the vyos hosts group" + vyos_config: + lines: + - set system name-server 8.8.8.8 + save: + true + + +all + +.. code-block:: none + + ansible_connection: ansible.netcommon.network_cli + ansible_network_os: vyos.vyos.vyos + + # user and password gets from terraform variables "admin_username" and "admin_password" + ansible_user: vyos + ansible_ssh_pass: Vyos0! + + +Azure_terraform_ansible_single_vyos_instance +-------------------------------------------- + +How to create a single instance and install your configuration using Terraform+Ansible+Azure +Step by step: + +Azure +----- + +1.1 Create an account with Azure + +Terraform +--------- + +2.1 Create a UNIX or Windows instance + +2.2 Download and install Terraform + +2.3 Create the folder for example ../azvyos/ + +2.4 Copy all files from my folder /Terraform into your Terraform project (main.tf, variables.tf) + +2.5 Login with Azure using the command + + #az login + +2.6 Type the commands : + + #cd /your folder + + #terraform init + +Ansible +------- + +3.1 Create a UNIX instance + +3.2 Download and install Ansible + +3.3 Create the folder for example /root/az/ + +3.4 Copy all files from my folder /Ansible into your Ansible project (ansible.cfg, instance.yml and /group_vars) + +Start +----- + +4.1 Type the commands on your Terrafom instance: + + #cd /your folder + + #terraform plan + + #terraform apply + + #yes + + + +Deploying vyos in the Vsphere infrastructia +------------------------------------------- +With the help of terraforms, you can quickly deploy Vyos-based infrastructure in the vSphere. + +Structure of files Terrafom + +.. code-block:: none + + . + ├── main.tf + ├── versions.tf + ├── variables.tf + └── terraform.tfvars + +File contents +------------- + +main.tf + +.. code-block:: none + + provider "vsphere" { + user = var.vsphere_user + password = var.vsphere_password + vsphere_server = var.vsphere_server + allow_unverified_ssl = true + } + + data "vsphere_datacenter" "datacenter" { + name = var.datacenter + } + + data "vsphere_datastore" "datastore" { + name = var.datastore + datacenter_id = data.vsphere_datacenter.datacenter.id + } + + data "vsphere_compute_cluster" "cluster" { + name = var.cluster + datacenter_id = data.vsphere_datacenter.datacenter.id + } + + data "vsphere_resource_pool" "default" { + name = format("%s%s", data.vsphere_compute_cluster.cluster.name, "/Resources/terraform") # set as you need + datacenter_id = data.vsphere_datacenter.datacenter.id + } + + data "vsphere_host" "host" { + name = var.host + datacenter_id = data.vsphere_datacenter.datacenter.id + } + + data "vsphere_network" "network" { + name = var.network_name + datacenter_id = data.vsphere_datacenter.datacenter.id + } + + ## Deployment of VM from Remote OVF + resource "vsphere_virtual_machine" "vmFromRemoteOvf" { + name = var.remotename + datacenter_id = data.vsphere_datacenter.datacenter.id + datastore_id = data.vsphere_datastore.datastore.id + host_system_id = data.vsphere_host.host.id + resource_pool_id = data.vsphere_resource_pool.default.id + network_interface { + network_id = data.vsphere_network.network.id + } + wait_for_guest_net_timeout = 2 + wait_for_guest_ip_timeout = 2 + + ovf_deploy { + allow_unverified_ssl_cert = true + remote_ovf_url = var.url_ova + disk_provisioning = "thin" + ip_protocol = "IPv4" + ip_allocation_policy = "dhcpPolicy" + ovf_network_map = { + "Network 1" = data.vsphere_network.network.id + "Network 2" = data.vsphere_network.network.id + } + } + vapp { + properties = { + "password" = "12345678", + "local-hostname" = "terraform_vyos" + } + } + } + + output "ip" { + description = "default ip address of the deployed VM" + value = vsphere_virtual_machine.vmFromRemoteOvf.default_ip_address + } + + # IP of AZ instance copied to a file ip.txt in local system + + resource "local_file" "ip" { + content = vsphere_virtual_machine.vmFromRemoteOvf.default_ip_address + filename = "ip.txt" + } + + #Connecting to the Ansible control node using SSH connection + + resource "null_resource" "nullremote1" { + depends_on = ["vsphere_virtual_machine.vmFromRemoteOvf"] + connection { + type = "ssh" + user = "root" + password = var.ansiblepassword + host = var.ansiblehost + + } + + # Copying the ip.txt file to the Ansible control node from local system + + provisioner "file" { + source = "ip.txt" + destination = "/root/vsphere/ip.txt" + } + } + + resource "null_resource" "nullremote2" { + depends_on = ["vsphere_virtual_machine.vmFromRemoteOvf"] + connection { + type = "ssh" + user = "root" + password = var.ansiblepassword + host = var.ansiblehost + } + + # Command to run ansible playbook on remote Linux OS + + provisioner "remote-exec" { + + inline = [ + "cd /root/vsphere/", + "ansible-playbook instance.yml" + ] + } + } + + +versions.tf + +.. code-block:: none + + # Copyright (c) HashiCorp, Inc. + # SPDX-License-Identifier: MPL-2.0 + + terraform { + required_providers { + vsphere = { + source = "hashicorp/vsphere" + version = "2.4.0" + } + } + } + +variables.tf + +.. code-block:: none + + # Copyright (c) HashiCorp, Inc. + # SPDX-License-Identifier: MPL-2.0 + + variable "vsphere_server" { + description = "vSphere server" + type = string + } + + variable "vsphere_user" { + description = "vSphere username" + type = string + } + + variable "vsphere_password" { + description = "vSphere password" + type = string + sensitive = true + } + + variable "datacenter" { + description = "vSphere data center" + type = string + } + + variable "cluster" { + description = "vSphere cluster" + type = string + } + + variable "datastore" { + description = "vSphere datastore" + type = string + } + + variable "network_name" { + description = "vSphere network name" + type = string + } + + variable "host" { + description = "name if yor host" + type = string + } + + variable "remotename" { + description = "the name of you VM" + type = string + } + + variable "url_ova" { + description = "the URL to .OVA file or cloude store" + type = string + } + + variable "ansiblepassword" { + description = "Ansible password" + type = string + } + + variable "ansiblehost" { + description = "Ansible host name or IP" + type = string + } + +terraform.tfvars + +.. code-block:: none + + vsphere_user = "" + vsphere_password = "" + vsphere_server = "" + datacenter = "" + datastore = "" + cluster = "" + network_name = "" + host = "" + url_ova = "" + ansiblepassword = "" + ansiblehost = "" + remotename = "" + +Azure_terraform_ansible_single_vyos_instance +-------------------------------------------- + +How to create a single instance and install your configuration using Terraform+Ansible+Vsphere +Step by step: + +Vsphere +------- + +1.1 Collect all data in to file "terraform.tfvars" and create resources fo example "terraform" + +Terraform +--------- + +2.1 Create a UNIX or Windows instance + +2.2 Download and install Terraform + +2.3 Create the folder for example ../vsphere/ + +2.4 Copy all files from my folder /Terraform into your Terraform project + +2.5 Type the commands : + + #cd /your folder + + #terraform init + + +Ansible +------- + +3.1 Create a UNIX instance + +3.2 Download and install Ansible + +3.3 Create the folder for example /root/vsphere/ + +3.4 Copy all files from my folder /Ansible into your Ansible project (ansible.cfg, instance.yml and /group_vars) + +Start +----- + +4.1 Type the commands on your Terrafom instance: + + #cd /your folder + + #terraform plan + + #terraform apply + + #yes + -- cgit v1.2.3 From 54cb31c8e76515b3245bf90ffb3735ae31918b9e Mon Sep 17 00:00:00 2001 From: bogdankol <68349689+bogdankol@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:53:51 +0200 Subject: Styles refactoring (#1278) --- docs/_locale/de/copyright.pot | 4 +- docs/_locale/es/copyright.pot | 4 +- docs/_locale/ja/copyright.pot | 4 +- docs/_locale/pt/copyright.pot | 4 +- docs/_locale/uk/copyright.pot | 4 +- docs/_static/css/breadcrumbs.css | 165 ++++++ docs/_static/css/code-snippets.css | 229 ++++++++ docs/_static/css/configuration/index.css | 23 + docs/_static/css/custom.css | 650 +++++++++++++++------ docs/_static/css/headers.css | 134 +++++ docs/_static/css/hints.css | 123 ++++ .../css/installation/running-on-bare-metal.css | 11 + docs/_static/css/leftSidebar.css | 371 ++++++++++++ docs/_static/css/linkButtons.css | 57 ++ docs/_static/css/lists.css | 56 ++ docs/_static/css/scrolls.css | 20 + docs/_static/css/separate-commands.css | 116 ++++ docs/_static/css/tables.css | 231 ++++++++ docs/_static/css/text.css | 120 ++++ .../_static/images/IPSec_close_action_settings.jpg | Bin 70253 -> 62330 bytes docs/_static/images/VyOS_Dual-Hub_DMVPN.png | Bin 0 -> 67747 bytes docs/_static/images/arrow-left.svg | 3 + docs/_static/images/arrow-right.svg | 3 + docs/_static/images/breadcrumbs-icon.svg | 3 + docs/_static/images/check.svg | 3 + docs/_static/images/close-sidebar-icon.svg | 3 + docs/_static/images/cmnd-link-dollar-icon.svg | 3 + docs/_static/images/cmnd-link-icon.svg | 3 + docs/_static/images/copy-code-icon.svg | 4 + docs/_static/images/github.svg | 10 + docs/_static/images/hamburger-icon.svg | 3 + docs/_static/images/note-icon.svg | 5 + .../_static/images/wireguard_site2site_diagram.jpg | Bin 21630 -> 19987 bytes docs/_static/images/zone-policy-diagram.png | Bin 126116 -> 113618 bytes docs/_static/js/codecopier.js | 67 +++ docs/_static/js/footer.js | 92 +++ docs/_static/js/sidebar.js | 162 +++++ docs/_templates/layout.html | 28 +- docs/conf.py | 4 +- docs/copyright.md | 2 +- 40 files changed, 2542 insertions(+), 182 deletions(-) create mode 100644 docs/_static/css/breadcrumbs.css create mode 100644 docs/_static/css/code-snippets.css create mode 100644 docs/_static/css/configuration/index.css create mode 100644 docs/_static/css/headers.css create mode 100644 docs/_static/css/hints.css create mode 100644 docs/_static/css/installation/running-on-bare-metal.css create mode 100644 docs/_static/css/leftSidebar.css create mode 100644 docs/_static/css/linkButtons.css create mode 100644 docs/_static/css/lists.css create mode 100644 docs/_static/css/scrolls.css create mode 100644 docs/_static/css/separate-commands.css create mode 100644 docs/_static/css/tables.css create mode 100644 docs/_static/css/text.css create mode 100644 docs/_static/images/VyOS_Dual-Hub_DMVPN.png create mode 100644 docs/_static/images/arrow-left.svg create mode 100644 docs/_static/images/arrow-right.svg create mode 100644 docs/_static/images/breadcrumbs-icon.svg create mode 100644 docs/_static/images/check.svg create mode 100644 docs/_static/images/close-sidebar-icon.svg create mode 100644 docs/_static/images/cmnd-link-dollar-icon.svg create mode 100644 docs/_static/images/cmnd-link-icon.svg create mode 100644 docs/_static/images/copy-code-icon.svg create mode 100644 docs/_static/images/github.svg create mode 100644 docs/_static/images/hamburger-icon.svg create mode 100644 docs/_static/images/note-icon.svg create mode 100644 docs/_static/js/codecopier.js create mode 100644 docs/_static/js/footer.js create mode 100644 docs/_static/js/sidebar.js (limited to 'docs/_static') diff --git a/docs/_locale/de/copyright.pot b/docs/_locale/de/copyright.pot index d5d53a50..be71d158 100644 --- a/docs/_locale/de/copyright.pot +++ b/docs/_locale/de/copyright.pot @@ -13,8 +13,8 @@ msgid "Copyright Notice" msgstr "Copyright Notice" #: ../../copyright.md:3 -msgid "Copyright (C) 2018-2023 VyOS maintainers and contributors" -msgstr "Copyright (C) 2018-2023 VyOS maintainers and contributors" +msgid "Copyright (C) 2018-2024 VyOS maintainers and contributors" +msgstr "Copyright (C) 2018-2024 VyOS maintainers and contributors" #: ../../copyright.md:9 msgid "Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one." diff --git a/docs/_locale/es/copyright.pot b/docs/_locale/es/copyright.pot index b4dcfb4e..c7befa5e 100644 --- a/docs/_locale/es/copyright.pot +++ b/docs/_locale/es/copyright.pot @@ -13,8 +13,8 @@ msgid "Copyright Notice" msgstr "Aviso de copyright" #: ../../copyright.md:3 -msgid "Copyright (C) 2018-2023 VyOS maintainers and contributors" -msgstr "Copyright (C) 2018-2023 Mantenedores y colaboradores de VyOS" +msgid "Copyright (C) 2018-2024 VyOS maintainers and contributors" +msgstr "Copyright (C) 2018-2024 Mantenedores y colaboradores de VyOS" #: ../../copyright.md:9 msgid "Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one." diff --git a/docs/_locale/ja/copyright.pot b/docs/_locale/ja/copyright.pot index 53078f45..d64e38c0 100644 --- a/docs/_locale/ja/copyright.pot +++ b/docs/_locale/ja/copyright.pot @@ -13,8 +13,8 @@ msgid "Copyright Notice" msgstr "Copyright Notice" #: ../../copyright.md:3 -msgid "Copyright (C) 2018-2023 VyOS maintainers and contributors" -msgstr "Copyright (C) 2018-2023 VyOS maintainers and contributors" +msgid "Copyright (C) 2018-2024 VyOS maintainers and contributors" +msgstr "Copyright (C) 2018-2024 VyOS maintainers and contributors" #: ../../copyright.md:9 msgid "Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one." diff --git a/docs/_locale/pt/copyright.pot b/docs/_locale/pt/copyright.pot index 63b2984b..6f47ee66 100644 --- a/docs/_locale/pt/copyright.pot +++ b/docs/_locale/pt/copyright.pot @@ -13,8 +13,8 @@ msgid "Copyright Notice" msgstr "Copyright Notice" #: ../../copyright.md:3 -msgid "Copyright (C) 2018-2023 VyOS maintainers and contributors" -msgstr "Copyright (C) 2018-2023 VyOS maintainers and contributors" +msgid "Copyright (C) 2018-2024 VyOS maintainers and contributors" +msgstr "Copyright (C) 2018-2024 VyOS maintainers and contributors" #: ../../copyright.md:9 msgid "Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one." diff --git a/docs/_locale/uk/copyright.pot b/docs/_locale/uk/copyright.pot index 1e83545b..c2e88942 100644 --- a/docs/_locale/uk/copyright.pot +++ b/docs/_locale/uk/copyright.pot @@ -13,8 +13,8 @@ msgid "Copyright Notice" msgstr "Copyright Notice" #: ../../copyright.md:3 -msgid "Copyright (C) 2018-2023 VyOS maintainers and contributors" -msgstr "Copyright (C) 2018-2023 VyOS maintainers and contributors" +msgid "Copyright (C) 2018-2024 VyOS maintainers and contributors" +msgstr "Copyright (C) 2018-2024 VyOS maintainers and contributors" #: ../../copyright.md:9 msgid "Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one." diff --git a/docs/_static/css/breadcrumbs.css b/docs/_static/css/breadcrumbs.css new file mode 100644 index 00000000..bdc91993 --- /dev/null +++ b/docs/_static/css/breadcrumbs.css @@ -0,0 +1,165 @@ +.wy-breadcrumbs { + + & > li, + & > li a { + color: #636A6D; + font-family: 'Roboto', sans-serif; + font-weight: 500; + letter-spacing: -0.5px; + height: 26px; + } + + & > li a { + padding: 0 5px 0 0; + } + + & > li:nth-child(1) { + visibility: hidden; + position: relative; + padding-left: 0; + } + + & > li > .icon-home::after { + content: url('../images/breadcrumbs-icon.svg'); + visibility: visible; + top: 6px; + position: absolute; + } + + & > li > .icon-home::before { + padding-right: 0; + content: 'Home'; + visibility: visible; + font-family: 'Roboto', sans-serif; + letter-spacing: -0.5px; + font-weight: 500; + } + + & > li:nth-child(n + 1) { + font-weight: 500; + position: relative; + } + + & > li:nth-child(n + 1)::before { + display: none; + } + + & > li:nth-last-child(2) { + color: #121010; + } + + & > li:nth-last-child(2)::after, + & > li:nth-last-child(1)::after { + display: none !important + } + + & > li:nth-child(n + 1)::after { + content: url('../images/breadcrumbs-icon.svg'); + top: 0; + position: absolute; + width: 20px; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-color: #fff; + } + + & > li:last-of-type:has(a), + & > li:last-of-type:has(a) a { + font-family: 'Archivo', sans-serif; + font-size: 14px; + font-weight: 700; + letter-spacing: -0.02em; + color: #fff; + background-color: #121010; + display: flex; + align-items: center; + } + + & > li:last-of-type:has(a) { + padding: 7px 10px; + border-radius: 4px; + height: 30px; + } + + & > li:last-of-type:has(a) a { + max-height: 100%; + } + + & > li:last-of-type:has(a) a::before { + content: url('../images/github.svg'); + margin-right: 4px; + display: flex; + align-items: center; + } + + & > li:last-of-type::before { + display: none; + } +} + +@media screen and (max-width: 375px) { + + .wy-breadcrumbs { + & > li > .icon-home::after { + right: -2px; + } + + & > li:nth-child(n + 1)::after { + right: -13px; + } + } + + .wy-breadcrumbs > li { + padding: 5px 5px 5px 0; + } + + .wy-breadcrumbs > li, + .wy-breadcrumbs > li a { + font-size: 14px; + } + + .wy-breadcrumbs > li > .icon-home::before { + font-size: 14px; + } +} + +@media screen and (min-width: 376px) { + .wy-breadcrumbs { + & > li > .icon-home::after { + right: -8px; + } + + & > li:nth-child(n + 1)::after { + right: -13px; + } + } + + .wy-breadcrumbs > li { + padding: 5px 5px 5px 10px; + } + + .wy-breadcrumbs > li, + .wy-breadcrumbs > li a { + font-size: 16px; + } + + .wy-breadcrumbs > li > .icon-home::before { + font-size: 16px; + } +} + +@media screen and (max-width: 991px) { + li.wy-breadcrumbs-aside { + display: none !important; + } +} + +@media screen and (max-width: 1200px) { + ul.wy-breadcrumbs:has(li + li + li + li) li.wy-breadcrumbs-aside { + margin: 24px 0 16px; + max-width: 140px; + float: none; + } +} diff --git a/docs/_static/css/code-snippets.css b/docs/_static/css/code-snippets.css new file mode 100644 index 00000000..0ae5464d --- /dev/null +++ b/docs/_static/css/code-snippets.css @@ -0,0 +1,229 @@ +.rst-content { + & div[class^=highlight], + & pre.literal-block { + border: none; + background: linear-gradient(#FF9000, #FFBF12); + border-radius: 8px; + padding-left: 5px; + } + + & div[class^=highlight] div[class^=highlight], + & pre.literal-block div[class^=highlight] { + background: #525659 !important; + border-radius: 0; + border: none; + padding: 0; + position: relative; + } + + & .linenodiv pre, + & div[class^=highlight] pre, + & pre.literal-block { + font-size: 16px; + font-family: 'Roboto Mono', monospace; + font-weight: 400; + letter-spacing: -0.04em; + color: #fff; + line-height: 1.2; + overflow-x: scroll; + scroll-behavior: smooth; + } + + & .linenodiv pre::-webkit-scrollbar, + & div[class^=highlight] pre::-webkit-scrollbar, + & pre.literal-block::-webkit-scrollbar { + height: 3px; + color: #99A0A5 transparent; + } + + & .linenodiv pre::-webkit-scrollbar-track, + & div[class^=highlight] pre::-webkit-scrollbar-track, + & pre.literal-block::-webkit-scrollbar-track { + background-color: transparent; + border-radius: 8px; + margin: 0 18px; + } + + & .linenodiv pre::-webkit-scrollbar-thumb, + & div[class^=highlight] pre::-webkit-scrollbar-thumb, + & pre.literal-block::-webkit-scrollbar-thumb { + background-color: #99A0A5; + border-radius: 8px; + margin: 0 10px; + } + +} + +/* copy code div */ +.highlight > .copyDiv { + display: flex; + align-items: center; + transition: transform linear 250ms, width linear 250ms; + bottom: 0; + right: 0; + width: 100%; + padding: 5px 12px; + justify-content: end; + background-color: #393C3F; + height: 32px; + margin-top: 4px; +} + +.copiedNotifier > span { + font-size: 14px !important; + color: #fff !important; + text-align: center; + margin-bottom: 0; +} + +.highlight { + + & .kn { + color: #ccffda; + } + + & .nn { + color: #d0eefb; + } + + & .o { + color: #e6e6e6; + } + + & .s2 { + color: #dbe6f0; + } + + & .s1 { + color: #dbe6f0; + } + + & .nb { + color: #ccffda; + } + + & .c1 { + color: #dcebef; + font-style: italic; + } + + & .nt { + color: #8db1fe; + font-weight: bold; + } + + & .k { + color: #ccffda; + font-weight: bold; + } + + & .se { + color: #dbe6f0; + font-weight: bold; + } + + & .nv { + color: #eed7f4; + } + + & .gh { + color: #ccccff; + font-weight: bold; + } + + & .gd { + color: #ffcccc; + } + + & .gi { + color: #ccffcc; + } + + & .gu { + color: #ffc2ff; + font-weight: bold; + } + + & .na { + color: #81c0ff; + } + + & .s { + color: #dbe6f0; + } + + & .ni { + color: #f4d4cd; + font-weight: bold; + } + + & .cm { + color: #d5e7ec; + font-style: italic; + } + + & .cp { + color: #c2ffd3; + } + + & .mi { + color: #cef3e0; + } + + & .nf { + color: #c5d4fc; + } + + & .kc { + color: #c2ffd3; + font-weight: bold; + } + + & .ch { + color: #d5e7ec; + font-style: italic; + } + + & .mf { + color: #d6f5e6; + } + + & .go { + color: #e6e6e6; + } + + & .m { + color: #d6f5e6; + } +} + +.rst-content blockquote { + margin: 0 +} + +@media screen and (max-width: 991px) { + .rst-content .linenodiv pre, + .rst-content div[class^=highlight] pre, + .rst-content pre.literal-block { + padding: 16px 20px; + } + + .copyDiv > p { + margin: 0 10px 0 0; + color: #fff; + font-family: 'Roboto', sans-serif; + font-size: 14px; + } +} + +@media screen and (min-width: 992px) { + .rst-content .linenodiv pre, + .rst-content div[class^=highlight] pre, + .rst-content pre.literal-block { + padding: 24px 36px 18px; + } + + .copyDiv > p { + display: none; + } +} diff --git a/docs/_static/css/configuration/index.css b/docs/_static/css/configuration/index.css new file mode 100644 index 00000000..a759ea45 --- /dev/null +++ b/docs/_static/css/configuration/index.css @@ -0,0 +1,23 @@ +#configuration-guide > div > ul > li { + list-style: none !important; + position: relative; +} + +#configuration-guide > div > ul > li::before { + content: ''; + position: absolute; + top: 9px; + left: -15px; + width: 6px; + height: 6px; + background-color: #000; + border-radius: 50%; +} + +#configuration-guide .toctree-l1 > a { + color: #FD8F01; + font-family: 'Roboto', sans-serif; + font-size: 16px; + font-weight: 400; + letter-spacing: -0.5px; +} \ No newline at end of file diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index e934fb54..cdb036d2 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -1,215 +1,535 @@ -div.card-header { - font-weight: bold; - background: #fdab10; -} - -span.opcmd, -span.cfgcmd { - font-weight: bold; - background-color: transparent; - border: none; - padding: 0; - font-size: 100% !important; - max-width: 100%; - color: #000; - font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace; -} - -span.cfgcmd:before { - content: "#"; - margin-right: 0px; -} - -td a.cmdlink span.cfgcmd:before, -td a.cmdlink span.opcmd:before { - content: ""; +p.devwarning { + top: 10px; + position: sticky; + margin: 10px 10px 10px 310px; + padding: 5px 10px; + border-radius: 4px; + letter-spacing: 1px; + color: #000; + text-align: center; + background: #d40 + repeating-linear-gradient( + 135deg, + transparent, + transparent 56px, + rgba(255, 255, 255, 0.2) 56px, + rgba(255, 255, 255, 0.2) 112px + ); + background-color: #fdab10; +} + +/* main page */ +.wy-body-for-nav { + background: #fff; + overflow-y: hidden +} + +.wy-grid-for-nav { + margin: 0 auto; + position: relative; + padding-top: 80px; + display: flex; + + &:has(nav.wy-nav-side.shift) { + background: #E7E7E7; + } + + &:not(:has(nav.shift)) > section > div.overlay { + background-color: transparent + } + + &:not(:has(nav.shift)) section > div.overlay > div .wy-breadcrumbs > li a::before, + &:not(:has(nav.shift)) section > div.overlay > div .wy-breadcrumbs > li a::after, + &:not(:has(nav.shift)) section > div.overlay > div .wy-breadcrumbs > li::before, + &:not(:has(nav.shift)) section > div.overlay > div .wy-breadcrumbs > li::after { + background-color: #fff; + } +} + +.wy-nav-content-wrap { + width: 100%; + margin-left: auto; + background-color: transparent; } -td a.cmdlink, -td a.cmdlink { - margin-left: 0px; -} +.wy-nav-content { + max-width: 100%; + background-color: transparent; + + &.overlay > div > div[role=navigation] .wy-breadcrumbs > li a::before, + &.overlay > div > div[role=navigation] .wy-breadcrumbs > li a::after, + &.overlay > div > div[role=navigation] .wy-breadcrumbs > li::before, + &.overlay > div > div[role=navigation] .wy-breadcrumbs > li::after, + &.overlay > div > div.document div.sd-card, + &.overlay > div > div.document div.sd-card-title { + background-color: #E7E7E7; + } + + &.overlay > div.rst-content > footer > .rst-footer-buttons > a { + background-color: #E7E7E7 !important; + } + +} + +/* main-page content */ +#vyos-user-guide { + & .sd-container-fluid { + padding-left: 0; + padding-right: 0; + } + + & .sd-container-fluid > .docutils > .sd-col { + max-width: 387px; + box-shadow: none; + flex: none; + width: 100% !important; + padding: 0 !important; + margin-top: 0 !important; + + & .sd-card-body .sd-card-text { + min-height: 120px; + } + } + + & > div.sd-container-fluid { + margin-top: 30px; + + & > div.docutils { + margin: 0; + display: grid; + } + } + + & > .pb-4 { + padding-bottom: 1.4rem !important; + } +} + +div.sd-card-title { + font-weight: bold; + background: #fff; + border: none; + font-family: 'Archivo', sans-serif; +} + +.sd-card { + background: #fff; + border: none; + border-bottom: 1px solid #ffae12; + border-radius: 0; + box-shadow: none !important; +} + +.sd-card-body { + padding: 0; +} + +.sd-card-title, +.sd-card-text { + padding: 0; +} + +.internal > .std-ref, +.line > .external { + color: #fd8f01; + font-family: 'Roboto', sans-serif; + font-size: 16px; + letter-spacing: -0.5px; + font-weight: 400; +} + +img { + height: auto !important; + border: 1px solid #C4C9CC; + margin-bottom: 20px !important; + border-radius: 8px; +} + +footer { + text-align: center; + font-family: 'Roboto', sans-serif; + font-size: 16px; + font-weight: 400; + letter-spacing: -0.5px; + color: #636a6d; + + & > a { + color: #fd8f01; + font-family: 'Roboto', sans-serif; + font-size: 16px; + letter-spacing: -0.5px; + font-weight: 400; + } + + & > hr { + display: none; + } + + & p { + margin-top: 105px; + text-align: center; + font-family: 'Roboto', sans-serif; + font-size: 16px; + font-weight: 400; + letter-spacing: -0.5px; + color: #636a6d; + + &:has(a) > a, + &:has(a) > a:visited { + color: #636a6d; + } + } + +} + +.rst-versions { + position: static; + background: transparent; + width: 262px; + display: block; + + &.shift-up { + background: #525659; + z-index: 100; + position: absolute; + left: 19px; + bottom: 30px; + border-radius: 6px; + overflow: hidden; + } + + & .rst-current-version { + background-color: #525659; + color: #01D38E; + border-radius: 6px; + width: 264px; + font-family: 'Roboto', sans-serif; + letter-spacing: -0.5px; + } + + & .rst-current-version span.fa-book { + color: #fff !important; + font-family: 'Roboto', sans-serif; + letter-spacing: -0.5px; + } +} + +.rst-other-versions { + & dt { + color: #808080; + font-family: 'Roboto', sans-serif; + font-size: 16px; + letter-spacing: -0.5px; + } + + & small { + font-family: 'Roboto', sans-serif; + color: #fff; + + & a { + font-family: 'Roboto', sans-serif; + letter-spacing: -0.5px; + color: #fd8f01; + } + } + +} + +div#rtd-sidebar { + display: none; +} + +.wy-nav-content-opened-sidebar { + padding: 25px 0 27px 40px; +} + +.wy-nav-content-wrap-opened-sidebar { + max-width: calc(100% - 294px); + margin-left: 294px; +} + +.wy-nav-content-closed-sidebar { + padding: 26px 0 !important; +} + +.wy-nav-content-wrap-closed-sidebar { + max-width: 100% !important; + width: 100% !important; +} + +html { + scroll-padding-top: 90px !important; +} + +.overlayDiv { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + width: 100%; + height: 100%; + z-index: 111; + background-color: #121010; + opacity: 0.1; +} + +.iframe-container { + position: relative; + width: 100%; + background-color: #f0f0f0; + z-index: 201; + overflow: hidden; + + &::-webkit-scrollbar { + display: none; + } + + & iframe { + width: 100%; + height: 100%; + border: none; + overflow: hidden; + + &::-webkit-scrollbar { + display: none; + } + } + +} + +@media screen and (min-width: 320px) and (max-width: 575px) { + #vyos-user-guide .container > .row { + grid-gap: 0px 15px + } +} + +@media screen and (max-width: 575px) { + .wy-nav-content-wrap, + .wy-nav-content-wrap.shift { + max-width: 100%; + width: 100% + } + + .wy-nav-content-wrap.shift { + padding: 70px 15px 0; + overflow: auto; + } + + .wy-nav-side { + display: none; + min-height: unset; + } + + .wy-nav-side.shift { + display: inherit; + width: 100%; + max-width: 320px; + } -tr td p { - margin-bottom:0px - } + #vyos-user-guide .container > .docutils > .p-2 { + max-width: 100%; + &:nth-child(2n) { + margin-left: 0; + } -span.opcmd:before { - content: "$"; - margin-right: 0px; -} + & .card-body .card-text { + min-height: 80px; + } + } -.cfgcmd-heading { - display: inline-block; - margin: 6px 0; - font-size: 90%; - line-height: normal; - background: #f0d481; - color: #2980B9; - border-top: solid 3px #6ab0de; - border-top-width: 3px; - border-top-style: solid; - border-top-color: #FF9302; - padding: 6px; -} + .wy-nav-content-wrap-opened-sidebar { + max-width: 100%; + margin-left: unset; + } -.opcmd-heading { - display: inline-block; - margin: 6px 0; - font-size: 90%; - line-height: normal; - background: #e7f2fa; - color: #2980B9; - border-top: solid 3px #6ab0de; - border-top-width: 3px; - border-top-style: solid; - border-top-color: rgb(106, 176, 222); - padding: 6px; -} + dl.footnote > dt { + padding-left: 0 !important; + } -.opcmd-body, -.cfgcmd-body { - margin: 6px 0; - padding-left: 12px; + .wy-grid-for-nav { + padding: 80px 20px 0; + max-width: 738px; + } +} + +@media screen and (min-width: 575px) and (max-width: 768px) { + .wy-nav-content-wrap, + .wy-nav-content-wrap.shift { + max-width: 100%; + width: 100% + } + + .wy-nav-content-wrap.shift { + padding: 70px 15px 0; + overflow: auto; + width: calc(100% - 294px); + + } + + .wy-nav-side { + display: none; + min-height: unset; + } + + .wy-nav-side.shift { + display: inherit; + width: 294px; + } +} + +@media screen and (min-width: 575px) { + #vyos-user-guide div.sd-container-fluid > div.docutils { + grid-gap: 30px; + grid-template-columns: 1fr 1fr; + } } +@media screen and (max-width: 767px) { + .wy-nav-content-wrap, + .wy-nav-content-wrap.shift { + margin: 0 auto; + } + .wy-nav-top { + background-color: #fdab10; + } -.cfgcmd-heading .cmdlink:after, -.opcmd-heading .cmdlink:after{ - content: ""; - font-family: FontAwesome -} - + p.devwarning { + margin: 10px 10px 10px 10px; + } -.cfgcmd-heading:not(:hover) .cmdlink, -.opcmd-heading:not(:hover) .cmdlink { - display: none; -} + #vyos-user-guide .container { + max-width: none; + } -.defaultvalue{ - font-size: 90%; - color: gray; - margin-bottom: 5px; + .wy-nav-content-wrap .wy-nav-content { + padding: 0 0 26px 0; + } -} + .wy-grid-for-nav { + padding: 80px 15px 0; + max-width: 738px; + } -a.cmdlink { - font-size: 80%; - margin-left: 6px; + .rst-content > div > hr { + display: none; + } } -a.cmdlink span{ - color: #2980B9; -} +@media screen and (min-width: 768px) { + .wy-nav-content-wrap { + width: calc(100% - 292px); + } -a.cmdlink span:hover{ - color: #3091d1; + .rst-content > div > hr { + margin: 16px 0 26px 0; + } } -.wy-nav-content { - max-width : none; -} +@media screen and (min-width: 768px) and (max-width: 991px) { + .wy-nav-content { + padding: 25px 0 27px 40px; + } -.wy-tray-container li.wy-tray-item-info { - background : #409ad5; -} + .wy-nav-content-wrap { + max-width: calc(100% - 294px); + } -.wy-table-responsive { - overflow : visible !important; + .wy-grid-for-nav { + max-width: 738px; + padding: 70px 15px 0; + } } -.wy-table-responsive table td { - white-space : normal !important; -} +@media screen and (min-width: 992px) and (max-width: 1266px) { + .wy-nav-content { + padding: 25px 0 27px 40px; + } -.wy-menu-vertical header, -.wy-menu-vertical p.caption { - color : #ffcc00 !important; -} + .wy-nav-content-wrap { + max-width: calc(100% - 294px); + } -.wy-menu-vertical li.current a { - color : #040077 !important; + .wy-grid-for-nav { + max-width: calc(100% - 130px); + } } -.wy-menu-vertical li ul li a { - color : #ffffff !important; -} +@media screen and (min-width: 1266px) { + .wy-nav-content { + padding: 25px 0 27px 40px; + } -.wy-menu-vertical a { - color : #ffffff !important; -} + .wy-nav-content-wrap { + max-width: calc(100% - 294px); + } -.wy-menu-vertical a:active { - background-color : #409ad5 !important; + .wy-grid-for-nav { + max-width: 1140px; + } } -.wy-side-nav-search { - background-color : #ffffff !important; -} +@media screen and (min-width: 1500px) { + .wy-nav-content { + padding: 25px 0 27px 40px; + } -.wy-side-nav-search img { - background-color : #ffffff !important; -} + .wy-nav-content-wrap { + max-width: calc(100% - 294px); + } -.wy-side-nav-search > div.version { - color : #000000 !important; + .wy-grid-for-nav { + max-width: 1340px; + } } -.wy-side-nav-search>a, -.wy-side-nav-search .wy-dropdown>a { - color:#000000; - font-size:100%; - font-weight:bold; - display:inline-block; - padding:4px 6px; - margin-bottom:.809em -} +@media screen and (max-height: 500px) { + .rst-versions { + margin-top: 10px; + } -.wy-nav-top { - background-color : #ffffff; + .closeButtonDivLine { + bottom: 45px; + } } -.wy-nav-top img { - background-color : #000000 !important; -} +@media screen and (min-height: 501px) and (max-height: 1000px) { + .rst-versions { + margin-top: 10px; + } -.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td.coverage-ok, -.rst-content table.docutils td.coverage-ok { - color: green; - text-align: center; + .closeButtonDivLine { + bottom: 55px; + } } -.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td.coverage-fail, -.rst-content table.docutils td.coverage-fail { - color: red; - text-align: center; +@media screen and (min-height: 1001px) and (max-height: 1300px) { + .rst-versions { + margin-top: 10px; + } + .closeButtonDivLine { + bottom: 60px; + } } +@media screen and (min-height: 1301px) and (max-height: 1600px) { + .rst-versions { + margin-top: 25px; + } -p.devwarning { - top: 10px; - position: sticky; - margin: 10px 10px 10px 310px; - padding: 5px 10px; - border-radius: 4px; - letter-spacing: 1px; - color: #000; - text-align: center; - background: #d40 repeating-linear-gradient( 135deg, transparent, transparent 56px, rgba(255, 255, 255, 0.2) 56px, rgba(255, 255, 255, 0.2) 112px ); - background-color: #fdab10; + .closeButtonDivLine { + bottom: 75px; + } } +@media screen and (min-height: 1601px) { + .rst-versions { + margin-top: 35px; + } -@media screen and (max-width: 768px) { - .wy-nav-top{ - background-color: #fdab10; - } -} - -@media screen and (max-width: 768px) { - p.devwarning { - margin: 10px 10px 10px 10px; - } + .closeButtonDivLine { + bottom: 85px; + } } \ No newline at end of file diff --git a/docs/_static/css/headers.css b/docs/_static/css/headers.css new file mode 100644 index 00000000..48b78a41 --- /dev/null +++ b/docs/_static/css/headers.css @@ -0,0 +1,134 @@ +h1, +h2, +h3, +h4, +h5 { + font-family: 'Archivo', sans-serif !important; + font-weight: 700 !important; + letter-spacing: -0.02em !important; + display: flex; + color: #121010; + margin-bottom: 15px !important; +} + +h2, +h3, +h4, +h5 { + margin-top: 15px !important; +} + +h1:has(a) > a, +h2:has(a) > a, +h3:has(a) > a, +h4:has(a) > a, +h5:has(a) > a { + display: flex !important; + position: relative; + padding-left: 5px; +} + +@media screen and (max-width: 767px) { + h1 { + font-size: 28px !important; + } + + h2 { + font-size: 22px !important; + } + + h3 { + font-size: 20px !important; + } + + h4 { + font-size: 18px !important; + } + + h5 { + font-size: 16px !important; + } +} + +@media screen and (min-width: 768px) { + h1 { + font-size: 48px !important; + } + + h2 { + font-size: 34px !important; + } + + h3 { + font-size: 24px !important; + } + + h4 { + font-size: 22px !important; + } + + h5 { + font-size: 20px !important; + } +} + +@media screen and (max-width: 991px) { + h1 { + margin-top: 15px; + } + + a.headerlink { + opacity: 1 !important; + color: transparent; + } + + h1:has(a):hover > a::after, + h2:has(a):hover > a::after, + h3:has(a):hover > a::after, + h4:has(a):hover > a::after, + h5:has(a):hover > a::after { + content: none !important; + display: none !important; + } + + h1:has(a) > a::before, + h2:has(a) > a::before, + h3:has(a) > a::before, + h4:has(a) > a::before, + h5:has(a) > a::before { + content: url('../images/cmnd-link-icon.svg'); + display: flex; + align-items: center; + justify-content: center; + position: absolute; + top: 25%; + height: 100%; + width: 20px; + z-index: 2; + background-color: transparent; + } +} + +@media screen and (min-width: 992px) { + h1:has(a):hover > a::after, + h2:has(a):hover > a::after, + h3:has(a):hover > a::after, + h4:has(a):hover > a::after, + h5:has(a):hover > a::after { + content: url('../images/cmnd-link-icon.svg'); + display: flex; + align-items: center; + justify-content: center; + position: absolute; + top: 0; + height: 100%; + width: 20px; + z-index: 2; + background-color: transparent; + } + + a.headerlink { + color: transparent; + } +} + diff --git a/docs/_static/css/hints.css b/docs/_static/css/hints.css new file mode 100644 index 00000000..fd7553f5 --- /dev/null +++ b/docs/_static/css/hints.css @@ -0,0 +1,123 @@ +div { + &.note, + &.hint, + &.warning, + &.error, + &.seealso, + &.tip { + border-radius: 8px; + + & > .admonition-title { + padding: 5px 8px; + border-radius: 6px; + font-family: 'Archivo', sans-serif !important; + font-size: 14px !important; + letter-spacing: -0.02em !important; + font-weight: 600 !important; + margin: -12px -16px 12px; + } + + & > .admonition-title::before { + content: url('../images/note-icon.svg'); + } + + & > .highlight-none { + margin-top: 10px; + } + + & > p:nth-child(1n+2) { + font-family: 'Roboto', sans-serif; + font-size: 16px; + letter-spacing: -0.5px; + color: #525659; + font-weight: 400; + margin: 10px 0 0 0 !important; + } + } + + &.note, + &.seealso { + background-color: #F5FCFF !important; + } + + &.note:has(a.reference), + &.hint:has(a.reference), + &.warning:has(a.reference), + &.error:has(a.reference), + &.seealso:has(a.reference), + &.tip:has(a.reference) { + & a.reference, + & a.reference span { + color: #508EEB !important; + } + } + + &.note, + &.seealso { + & > .admonition-title { + background-color: #CCEFFB !important; + color: #356E81 !important; + } + } + + &.hint, + &.tip { + background-color: #F7FDFB !important; + + & > .admonition-title { + background-color: #C6F0E3 !important; + color: #3F6461 !important; + } + } + + &.warning, + &.error { + background-color: #FDF7F7 !important; + + & > .admonition-title { + background-color: #F0C6C6 !important; + color: #8E2F2F !important; + } + } + +} + +#running-on-bare-metal div.note > p:nth-child(2) { + padding: 8px 12px 0 12px; +} + +@media screen and (max-width: 575px) { + div.note, + div.hint, + div.warning, + div.error, + div.seealso, + div.tip { + padding: 24px 32px !important; + border-radius: 8px; + } +} + +@media screen and (min-width: 576px) and (max-width: 991px) { + div.note, + div.hint, + div.warning, + div.error, + div.seealso, + div.tip { + padding: 24px 32px !important; + border-radius: 8px; + } +} + +@media screen and (min-width: 992px) { + div.note, + div.hint, + div.warning, + div.error, + div.seealso, + div.tip { + padding: 24px 32px !important; + border-radius: 8px; + } +} diff --git a/docs/_static/css/installation/running-on-bare-metal.css b/docs/_static/css/installation/running-on-bare-metal.css new file mode 100644 index 00000000..25ad7bbb --- /dev/null +++ b/docs/_static/css/installation/running-on-bare-metal.css @@ -0,0 +1,11 @@ +.toctree-l1 { + background-color: transparent; +} + +.current > .current > .internal { + background-color: #fff; + color: #FD8F01; + border: transparent; + padding: 11px 12px 11px 28px; + border: none !important; +} \ No newline at end of file diff --git a/docs/_static/css/leftSidebar.css b/docs/_static/css/leftSidebar.css new file mode 100644 index 00000000..87112121 --- /dev/null +++ b/docs/_static/css/leftSidebar.css @@ -0,0 +1,371 @@ +nav.wy-nav-side { + padding-bottom: 1em !important; +} + +.wy-nav-side { + padding: 20px 19px; + width: 294px; + height: calc(100vh - 50px); +} + +.wy-form input { + height: 32px; +} + +.wy-form input::placeholder { + font-family: 'Archivo', sans-serif; + font-weight: 400; + font-size: 14px; + letter-spacing: -0.02em; +} + +.wy-side-nav-search { + width: 100%; + padding: 0; + margin-bottom: 0; + + & > .icon-home, + & > .version { + display: none + } + + & input { + border-color: #C4C9CC; + + &::placeholder { + color: #8D9499; + } + } +} + +.wy-nav-side, +.wy-nav-side .wy-side-nav-search { + background-color: #F6F7F7 +} + +ul.current > li.toctree-l1[aria-expanded=false] > a.current { + padding-left: 25px; + color: #FD8F01; + + & button.toctree-expand::before { + content: '+'; + color: #FD8F01; + } +} + +ul.current > li.toctree-l1[aria-expanded=false] > a.internal:has( + ul[aria-expanded=false]) { + padding-left: 25px; + color: #FD8F01; + + & button.toctree-expand::before { + content: '+'; + color: #FD8F01; + } +} + +ul.current > li.toctree-l1.current > ul > li.toctree-l2[aria-expanded=false]:has(ul > li > a.current) > a.internal { + color: #FD8F01; + padding-top: 11px; + padding-bottom: 11px; + padding-right: 12px; +} + +ul.current > li.toctree-l1.current > + ul > li.toctree-l2.current > ul > li.toctree-l3[aria-expanded=false] + > a.current { + color: #FD8F01; + padding-top: 11px; + padding-bottom: 11px; + padding-right: 12px; +} + +ul.current > li.toctree-l1.current > + ul > li.toctree-l2.current > ul > li.toctree-l3[aria-expanded=false]:has(ul > li.toctree-l4 > a.current) + > a.internal { + color: #FD8F01; + padding-top: 11px; + padding-bottom: 11px; + padding-right: 12px; +} + +.toctree-l2 > ul > li.toctree-l3.current { + padding-left: 0 !important; + background-color: #fff; +} + +.wy-menu-vertical { + width: 100%; + max-width: 292px; + + & a { + color: #121010; + font-family: 'Archivo', sans-serif; + font-weight: 500; + font-size: 14px; + letter-spacing: -0.02em; + padding: 11px 12px; + } + + & p.caption { + color: #8D9499; + font-family: 'Archivo', sans-serif; + font-weight: 600; + font-size: 14px; + letter-spacing: -0.02em; + padding: 5px 12px; + margin-top: 6px; + margin-bottom: 4px; + text-transform: none; + } + + & li.toctree-l1.current > a { + background-color: #fff; + color: #FD8F01; + border: transparent; + padding: 11px 12px; + } + + & > ul.current > li.toctree-l1.current > a.internal:has(+ ul) { + padding-left: 25px !important; + } + + & > ul.current > li.toctree-l1.current > a.current { + padding-left: 12px; + } + + & li.toctree-l1.current .toctree-l2 > a { + background-color: #fff; + border: transparent; + } + + & li.toctree-l1.current .toctree-l2 > a.internal { + padding-left: 35px !important; + } + + & li.toctree-l1.current .toctree-l2.current > a.internal:first-of-type { + color: #fdab10; + } + + & li.toctree-l1.current .toctree-l2 > a:hover { + background-color: #E1E4E5; + } + + & li.toctree-l1.current .toctree-l2 > a.current { + color: #fdab10; + padding: 11px 12px 11px 35px; + } + + & li.toctree-l1.current .toctree-l2 > a:hover { + background-color: #E1E4E5; + } + + & li.toctree-l2.current > a, + & li.toctree-l2.current li.toctree-l3 > a { + background: #fff; + border: none; + padding-left: 50px; + } + + & li.toctree-l2.current li.toctree-l3 > a.current, + & li.toctree-l2.current li.toctree-l3.current > a.internal { + padding-left: 50px !important; + color: #fdab10; + } + + & li.toctree-l3.current li.toctree-l4 > a { + background: #fff; + padding-left: 65px !important; + border-right: none; + } + + & li.toctree-l3.current li.toctree-l4 > a.current { + color: #fdab10; + } +} + +.wy-menu-vertical a:hover, +.wy-menu-vertical > ul.current > li.toctree-l1.current > a:hover, +.wy-menu-vertical li.toctree-l1.current .toctree-l2 > a:hover, +.wy-menu-vertical li.toctree-l2.current li.toctree-l3 > a:hover, +.wy-menu-vertical li.toctree-l3.current li.toctree-l4 > a:hover { + background-color: #E1E4E5; +} + +.wy-menu-vertical ul li .current > a { + padding: 11px 12px !important; +} + +.wy-menu-vertical > ul.current[aria-expanded=true] > li.toctree-l1:has(a[aria-expanded=false]) > a { + padding-left: 25px; +} + +.wy-menu-vertical > ul.current[aria-expanded=true] > li.toctree-l1:not(:has( ~ li:only-child a)) > a:has(.toctree-expand) { + padding-left: 25px; +} + +.wy-side-scroll { + /* that makes scroll possible to the end of div */ + height: 94%; +} + +.wy-nav-top { + display: none; +} + +.openLeftSidebarMenuButton { + width: 24px; + height: 24px; + cursor: pointer; + transition: transform 250ms linear; +} + +.openLeftSidebarMenuButton:hover, +.closeLeftSidebarMenuButton:hover { + transform: scale(1.05); +} + +div.wy-nav-content > div.rst-content > div:has(div.openLeftSidebarMenuButton) { + display: flex; +} + +div.wy-nav-content + > div.rst-content + > div:has(div.openLeftSidebarMenuButton) + > .wy-breadcrumbs { + margin-left: 20px; + width: 100%; +} + +.closeButtonDivLine { + width: 100%; + display: flex; + position: sticky; + height: 30px; + justify-content: flex-end; +} + +.closeLeftSidebarMenuButton { + width: 83px; + height: 32px; + margin-right: -6px; + display: flex; + justify-content: center; + align-items: center; + background-color: #FFBF12; + border-radius: 4px; + font-family: 'Roboto', sans-serif; + font-size: 16px; + letter-spacing: -0.5px; + font-weight: 400; + color: #FFF; + cursor: pointer; + align-self: flex-end; + transition: transform 250ms linear; + + &::before { + content: url('../images/close-sidebar-icon.svg'); + height: 100%; + display: flex; + align-items: center; + width: 14px; + margin-right: 10px; + margin-top: 3px; + } +} + +.additionalStylesForShift { + display: block !important; + padding-bottom: 10px !important; +} + +.overlay { + background-color: #E7E7E7; +} + +.wy-body-for-nav:has(.overlay) { + background-color: rgb(209,209,209); +} + +.display_none { + display: none !important; +} + +@media screen and (max-width: 575px) { + .wy-menu-vertical { + padding: 10px 0 0 0; + } +} + +@media screen and (min-width: 576px) { + .wy-side-nav-search { + max-width: 256px; + } + + .wy-menu-vertical { + padding: 10px 35px 0 0; + } +} + +@media screen and (max-width: 767px) { + .wy-nav-side { + border-radius: 0; + position: fixed; + top: 60px; + } + + .wy-side-scroll::-webkit-scrollbar { + display: none + } +} + +@media screen and (min-width: 768px) { + .wy-nav-side { + border-radius: 16px; + position: fixed; + left: unset; + top: 70px; + min-height: unset; + } +} + +@media screen and (max-width: 1200px) { + .wy-nav-side { + height: calc(100vh - 60px); + } +} + +@media screen and (min-width: 1200px) { + .wy-nav-side { + height: calc(100vh - 73px); + } +} + +@media screen and (max-height: 300px) { + .wy-side-scroll { + height: 78%; + } +} + +@media screen and (min-height: 301px) and (max-height: 400px) { + .wy-side-scroll { + height: 82%; + } +} + +@media screen and (min-height: 401px) and (max-height: 500px) { + .wy-side-scroll { + height: 88%; + } +} + +@media screen and (min-height: 501px) and (max-height: 700px) { + .wy-side-scroll { + height: 90%; + } +} + +@media screen and (min-height: 701px) { + .wy-side-scroll { + height: 94%; + } +} \ No newline at end of file diff --git a/docs/_static/css/linkButtons.css b/docs/_static/css/linkButtons.css new file mode 100644 index 00000000..11a48e64 --- /dev/null +++ b/docs/_static/css/linkButtons.css @@ -0,0 +1,57 @@ +.rst-footer-buttons { + .fa-arrow-circle-left { + padding-left: 25px; + } + + .fa-arrow-circle-left::before { + content: url('../images/arrow-left.svg'); + position: absolute; + top: 10px; + left: 15px; + } + + & > .btn-neutral { + background: #fff !important; + min-width: 90px; + height: 40px; + border: 2px solid #FD8F01; + color: #121010 !important; + font-family: 'Archivo', sans-serif; + font-size: 16px; + font-weight: 600; + letter-spacing: -0.02em; + position: relative; + text-align: left; + box-shadow: none; + transition: transform 250ms linear; + display: flex; + align-items: center; + padding-top: 0; + padding-bottom: 0; + border-radius: 4px; + + &:hover, + &:active { + transform: scale(1.05); + /* padding-left: 16px; */ + } + + &:focus { + outline: none; + } + + .fa-arrow-circle-right::before { + content: url('../images/arrow-right.svg'); + position: absolute; + top: 10px; + right: 15px; + } + } +} + +p > a.reference.external, +p > a, +#partaker-i5 > p > a.external { + color: #FD8F01; + word-break: break-word; +} diff --git a/docs/_static/css/lists.css b/docs/_static/css/lists.css new file mode 100644 index 00000000..140663c9 --- /dev/null +++ b/docs/_static/css/lists.css @@ -0,0 +1,56 @@ +.simple > li, +.compound > ul > li, +.simple > li > ul > li, +#installation-and-image-management > div > ul > li.toctree-l1 > ul > li.toctree-l2, +#running-vyos-in-virtual-environments > div > ul > li.toctree-l1 > ul > li.toctree-l2, +#running-vyos-in-virtual-environments > div > ul > li.toctree-l1 > ul > li.toctree-l2 > ul > li.toctree-l3, +#running-vyos-in-cloud-environments > div > ul > li.toctree-l1 > ul > li.toctree-l2, +#running-vyos-in-cloud-environments > div > ul > li.toctree-l1 > ul > li.toctree-l2 > ul > li.toctree-l3, +#configuration-blueprints > div > ul > li.toctree-l1 > ul > li.toctree-l2, +#configuration-blueprints > div > ul > li.toctree-l1 > ul > li.toctree-l2 > ul > li.toctree-l3, +#contributing > div > ul > li.toctree-l1 > ul > li.toctree-l2, +#contributing > div > ul > li.toctree-l1 > ul > li.toctree-l2 > ul > li.toctree-l3 { + list-style: none !important; + position: relative; + + &::before { + content: ''; + position: absolute; + top: 8px; + left: -15px; + width: 6px; + height: 6px; + background-color: #000; + border-radius: 50%; + } +} + +.simple > li a, +.compound > ul > li a, +.simple > li > ul > li a { + color: #FD8F01; + font-family: 'Roboto', sans-serif; + font-size: 16px; + font-weight: 400; + letter-spacing: -0.5px; + height: 26px; +} + +.simple > li > ul > li p { + color: #525659; + font-family: 'Roboto', sans-serif; + font-size: 16px; + font-weight: 400; + letter-spacing: -0.5px; + height: 26px; +} + +#site-to-site ul, +#troubleshooting ol, +#troubleshooting ul { + margin-bottom: 0 !important; +} + +.rst-content:has(#troubleshooting) .rst-footer-buttons { + margin-top: 20px !important; +} \ No newline at end of file diff --git a/docs/_static/css/scrolls.css b/docs/_static/css/scrolls.css new file mode 100644 index 00000000..26cfe413 --- /dev/null +++ b/docs/_static/css/scrolls.css @@ -0,0 +1,20 @@ +.wy-table-responsive { + scrollbar-color: #99A0A5 transparent; + scroll-behavior: smooth; + + &::-webkit-scrollbar { + height: 5px; + } + + &::-webkit-scrollbar-track { + background-color: transparent; + border-radius: 8px; + margin: 0 10px; + } + + &::-webkit-scrollbar-thumb { + background-color: #99A0A5; + border-radius: 8px; + margin: 0 10px; + } +} diff --git a/docs/_static/css/separate-commands.css b/docs/_static/css/separate-commands.css new file mode 100644 index 00000000..5547c4ad --- /dev/null +++ b/docs/_static/css/separate-commands.css @@ -0,0 +1,116 @@ +.rst-content code.literal { + border: unset; + background-color: unset; + border: 1px solid rgba(253, 143, 1, 0.2); + background-color: #FFF4E6; + font-family: 'Archivo', sans-serif !important; + font-size: 14px !important; + font-weight: 500 !important; + color: #121010 !important; + border-radius: 4px; + padding: 3px 6px; + word-break: break-all; + + & > span.pre:nth-child(n+ 2) { + padding-left: 5px; + } +} + +div.opcmd-heading, +div.cfgcmd-heading, +table .opcmd, +table .cfgcmd { + padding: 0; + display: flex; + background-color: unset; + border: none; + border-radius: 8px 0 0 8px; +} + +div.opcmd-heading, +div.cfgcmd-heading { + margin-bottom: 15px; +} + +div.opcmd-heading, +table .opcmd { + border-left: 5px solid #B8E9F9; +} + +div.cfgcmd-heading, +table .cfgcmd { + border-left: 5px solid #FD8F01; +} + +span { + &.opcmd, + &.cfgcmd { + display: flex; + padding: 4px 8px 8px 30px; + align-items: center; + color: #121010 !important; + font-family: 'Roboto Mono', monospace !important; + letter-spacing: -0.04em !important; + font-weight: 500 !important; + position: relative; + word-break: break-all; + + &::before { + content: url('../images/cmnd-link-dollar-icon.svg'); + display: flex; + padding-right: 8px; + align-items: center; + position: absolute; + top: 6px; + left: 8px; + } + } + + &.opcmd { + background-color: #EBF9FF; + } + + &.cfgcmd { + background-color: #FFF4E6; + } +} + +span.opcmd, +span.cfgcmd { + font-size: 16px !important; +} + +table span.opcmd, +table span.cfgcmd { + font-size: 13px !important; +} + +.opcmd-heading > a.cmdlink, +.cfgcmd-heading > a.cmdlink { + display: flex; + + &::after { + display: flex; + align-items: center; + content: ''; + height: 100%; + align-items: center; + padding-right: 12px; + padding-top: 3px; + border-radius: 0 8px 8px 0; + } +} + +.opcmd-heading:hover a.cmdlink:after, +.cfgcmd-heading:hover a.cmdlink:after { + content: url('../images/cmnd-link-icon.svg'); + padding-right: 10px; +} + +.opcmd-heading a.cmdlink:after { + background-color: #EBF9FF; +} + +.cfgcmd-heading a.cmdlink:after { + background-color: #FFF4E6; +} \ No newline at end of file diff --git a/docs/_static/css/tables.css b/docs/_static/css/tables.css new file mode 100644 index 00000000..7a106d56 --- /dev/null +++ b/docs/_static/css/tables.css @@ -0,0 +1,231 @@ +.wy-table-responsive { + overflow : auto !important ; + width: 100%; + + & table { + border: none !important; + + + & td { + white-space : normal !important; + } + + & > caption:hover a { + position: relative; + + &::after { + content: url('../images/cmnd-link-icon.svg'); + position: absolute; + top: 0; + right: -3px; + z-index: 2; + background-color: #fff; + width: 20px; + height: 100%; + } + } + } +} + +#coverage table.docutils td.coverage-ok p { + color: green; + text-align: center; +} + +#coverage table.docutils:not(.field-list) tr:nth-child(2n-1) td.coverage-fail p, +#coverage table.docutils td.coverage-fail p { + color: red; + text-align: center; +} + +#coverage a.paginate_button.current, +#coverage a.paginate_button.next, +#coverage a.paginate_button.previous { + color: #FD8F01 !important; + background-color: none; + background: none; +} + +#coverage a.paginate_button { + margin-left: 0; + border: unset; + border-radius: 8px; + transition: background-color 250ms linear, color 250ms linear; +} + +#coverage a.paginate_button:hover, +#coverage a.paginate_button.current:hover, +#coverage a.paginate_button.next:hover, +#coverage a.paginate_button.previous:hover { + background-color: #E1E4E5 !important; + background: none; + border: unset; + color: #121010 !important; +} + +.selectDiv { + width: 20px; + height: 20px; + position: absolute; + top: 10px; + right: 10px; + z-index: 11111; + background-color: red; +} + +#table-cfgcmd_wrapper, +#table-opcmd_wrapper { + & label { + color: #121010 !important; + font-family: 'Archivo', sans-serif; + font-size: 14px; + font-weight: 600; + letter-spacing: -0.02em; + } + + & option { + color: #8D9499 !important; + font-family: 'Roboto', sans-serif; + font-size: 16px; + font-weight: 500; + letter-spacing: -0.02em; + } + + & select { + height: 40px; + width: 80px; + padding: 10px 14px; + margin: 0 10px; + border-radius: 4px; + border: 1px solid #C6C9CC !important; + color: #8D9499; + font-size: 16px; + position: relative; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-image: url("../images/select-arrow.svg"); + background-repeat: no-repeat; + background-position: right 18px top 50%; + } + + & input { + margin-left: 16px; + height: 40px; + padding: 10px 14px; + width: 245px; + border: 1px solid #C6C9CC !important; + color: #8D9499; + font-size: 16px; + } + + & .wy-table-responsive { + padding-top: 24px; + } +} + +@media screen and (max-width: 575px) { + #table-cfgcmd_wrapper, + #table-opcmd_wrapper { + & label { + & input { + margin-top: 10px + } + } + } +} + +thead tr th { + padding: 10px 16px !important; + border-top: none !important; + border-left: none !important; + border-right: none !important; + max-height: 40px; + + & p { + color: #121010 !important; + font-family: 'Archivo', sans-serif; + font-size: 14px !important; + font-weight: 600; + letter-spacing: -0.02em; + margin-right: 3px; + } +} + +.rst-content table.docutils td, +.wy-table-bordered-all td { + border-left: none !important; +} + +.rst-content table.docutils th:nth-child(2n), +.rst-content table.field-list th:nth-child(2n), +.wy-table td, .wy-table th:nth-child(2n) { + border-radius: 8px 8px 0 0 ; +} + +.wy-grid-for-nav:has(nav.display_none) .rst-content table.docutils td:nth-child(2n), +.wy-grid-for-nav:has(nav.display_none) .rst-content table.docutils th:nth-child(2n), +.wy-grid-for-nav:has(nav.display_none) .rst-content table.field-list td:nth-child(2n), +.wy-grid-for-nav:has(nav.display_none) .rst-content table.field-list th:nth-child(2n), +.wy-grid-for-nav:has(nav.display_none) .wy-table td, +.wy-grid-for-nav:has(nav.display_none) .wy-table th:nth-child(2n) { + background-color: #FAFAFA !important; +} + +.wy-grid-for-nav:has(nav.shift) .wy-nav-content-wrap-closed-sidebar .rst-content table th, +.wy-grid-for-nav:has(nav.shift) .wy-nav-content-wrap-closed-sidebar .rst-content table td { + background-color: #E7E7E7 !important; +} + +.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td, +.wy-table-backed, +.wy-table-odd td, +.wy-table-striped tr:nth-child(2n-1) td { + background-color: unset; +} + +tbody tr td { + & p { + color: #525659 !important; + font-family: 'Roboto', sans-serif; + font-size: 14px !important; + font-weight: 400; + letter-spacing: -0.02em; + } + + &.coverage-ok { + & p { + color: transparent !important; + width: 100%; + height: 100%; + margin: 0; + position: relative; + + &::before { + content: url('../images/check.svg'); + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + position: absolute; + top: 0; + } + } + } +} + +.dataTables_info { + color: #121010 !important; + font-family: 'Roboto', sans-serif; + font-size: 16px !important; + font-weight: 400; + letter-spacing: -0.5px; +} + +.paginate_button { + font-family: 'Archivo', sans-serif; + font-size: 16px !important; + font-weight: 600; + letter-spacing: -0.5px; +} \ No newline at end of file diff --git a/docs/_static/css/text.css b/docs/_static/css/text.css new file mode 100644 index 00000000..f1179534 --- /dev/null +++ b/docs/_static/css/text.css @@ -0,0 +1,120 @@ +.docutils .card-header p { + font-family: 'Archivo', sans-serif; + font-weight: 600; + font-size: 18px; + letter-spacing: -0.05em; + padding-bottom: 18px; + color: #121010; +} + +p, +blockquote > div > dl, +blockquote > div > dd, +#container dl, +#firewall dl, +#high-availability dl, +#development td, +#development th, +caption.caption-text, +.simple > dt, +div.line-block, +.paginate_button, +.dataTables_info, +#operational-commands label, +.card-body .card-text, +#search-results a { + font-family: 'Roboto', sans-serif; + font-size: 16px; + letter-spacing: -0.5px; + font-weight: 400; + color: #525659; + line-height: 1.6; +} + +p > strong { + color: #121010; +} + +.card-body .card-text { + padding-bottom: 22px; + display: block; +} + +.simple > dt { + font-weight: 600; +} + +#dual-hub-dmvpn-with-vyos td > p, +#route-based-redundant-site-to-site-vpn-to-azure-bgp-over-ikev2-ipsec td > p, +#route-based-site-to-site-vpn-to-azure-bgp-over-ikev2-ipsec td > p, +#development td p, +#development th p { + font-size: 14px !important; +} + +#development #writing-good-commit-messages > ul.simple > li > ul { + + & > li:nth-child(2) { + padding-bottom: 23px; + } + + & > li:nth-child(2) { + padding-bottom: 53px; + } +} + +#installation-and-image-management > div > p > span { + font-family: 'Archivo', sans-serif; + font-weight: 700; + letter-spacing: -0.02em; + font-size: 24px; + color: #121010; +} + +.caption-text { + text-align: left; + font-family: 'Roboto', sans-serif; +} + +p .caption-text { + color: #8D9499; + font-family: 'Roboto', sans-serif; +} + +aside.footnote .label { + & > a[role=doc-backlink] { + color: #fd8f01; + font-family: 'Roboto', sans-serif; + font-size: 16px; + } +} + +aside.footnote > p { + padding-bottom: 15px !important; +} + +#about a .external, +#a-note-on-copyright > dl.brackets > dt, +#a-note-on-copyright > dl.brackets > dt > .brackets > a, +a.footnote-reference.brackets, +#search-results a { + color: #FD8F01; +} + +#history p { + padding-bottom: 22px; + margin-bottom: 0; + font-size: 16px; +} + +#a-note-on-copyright > dl p { + padding-bottom: 12px; +} + +#search-results a { + font-size: 19px; +} + +#specify-custom-config-file { + padding-top: 15px; +} \ No newline at end of file diff --git a/docs/_static/images/IPSec_close_action_settings.jpg b/docs/_static/images/IPSec_close_action_settings.jpg index a4e258cc..6996f857 100644 Binary files a/docs/_static/images/IPSec_close_action_settings.jpg and b/docs/_static/images/IPSec_close_action_settings.jpg differ diff --git a/docs/_static/images/VyOS_Dual-Hub_DMVPN.png b/docs/_static/images/VyOS_Dual-Hub_DMVPN.png new file mode 100644 index 00000000..9c25a308 Binary files /dev/null and b/docs/_static/images/VyOS_Dual-Hub_DMVPN.png differ diff --git a/docs/_static/images/arrow-left.svg b/docs/_static/images/arrow-left.svg new file mode 100644 index 00000000..16d6750b --- /dev/null +++ b/docs/_static/images/arrow-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/_static/images/arrow-right.svg b/docs/_static/images/arrow-right.svg new file mode 100644 index 00000000..15ab0eb4 --- /dev/null +++ b/docs/_static/images/arrow-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/_static/images/breadcrumbs-icon.svg b/docs/_static/images/breadcrumbs-icon.svg new file mode 100644 index 00000000..6420468b --- /dev/null +++ b/docs/_static/images/breadcrumbs-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/_static/images/check.svg b/docs/_static/images/check.svg new file mode 100644 index 00000000..fcec28a1 --- /dev/null +++ b/docs/_static/images/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/_static/images/close-sidebar-icon.svg b/docs/_static/images/close-sidebar-icon.svg new file mode 100644 index 00000000..e630ce27 --- /dev/null +++ b/docs/_static/images/close-sidebar-icon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/docs/_static/images/cmnd-link-dollar-icon.svg b/docs/_static/images/cmnd-link-dollar-icon.svg new file mode 100644 index 00000000..b0e4a74b --- /dev/null +++ b/docs/_static/images/cmnd-link-dollar-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/_static/images/cmnd-link-icon.svg b/docs/_static/images/cmnd-link-icon.svg new file mode 100644 index 00000000..4602fadf --- /dev/null +++ b/docs/_static/images/cmnd-link-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/_static/images/copy-code-icon.svg b/docs/_static/images/copy-code-icon.svg new file mode 100644 index 00000000..3417dfe5 --- /dev/null +++ b/docs/_static/images/copy-code-icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/_static/images/github.svg b/docs/_static/images/github.svg new file mode 100644 index 00000000..cb3d30ef --- /dev/null +++ b/docs/_static/images/github.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/docs/_static/images/hamburger-icon.svg b/docs/_static/images/hamburger-icon.svg new file mode 100644 index 00000000..9fad3003 --- /dev/null +++ b/docs/_static/images/hamburger-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/_static/images/note-icon.svg b/docs/_static/images/note-icon.svg new file mode 100644 index 00000000..fd4f05c3 --- /dev/null +++ b/docs/_static/images/note-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/docs/_static/images/wireguard_site2site_diagram.jpg b/docs/_static/images/wireguard_site2site_diagram.jpg index fc305952..4a7a95e4 100644 Binary files a/docs/_static/images/wireguard_site2site_diagram.jpg and b/docs/_static/images/wireguard_site2site_diagram.jpg differ diff --git a/docs/_static/images/zone-policy-diagram.png b/docs/_static/images/zone-policy-diagram.png index 49e3e046..cfde4af6 100644 Binary files a/docs/_static/images/zone-policy-diagram.png and b/docs/_static/images/zone-policy-diagram.png differ diff --git a/docs/_static/js/codecopier.js b/docs/_static/js/codecopier.js new file mode 100644 index 00000000..bf0b3b4d --- /dev/null +++ b/docs/_static/js/codecopier.js @@ -0,0 +1,67 @@ +const hamburgerIcon = ` + + + +` + +const innersOfCopyDiv = ` +

Copy

+ + + + +` + +function formDiv(id) { + return ` +
+ ${innersOfCopyDiv} +
+` +} + +$(document).ready(async function () { + const codeSnippets = $( + '.rst-content div[class^=highlight] div[class^=highlight], .rst-content pre.literal-block div[class^=highlight], .rst-content pre.literal-block div[class^=highlight]' + ) + + codeSnippets.each((index, el) => { + el.insertAdjacentHTML('beforeend', formDiv(index)) + }) + + const copyButton = $('.copyDiv') + + copyButton.click(async ({ + currentTarget + }) => { + // we obtain text and copy it + const id = currentTarget.dataset.identifier + + try { + await navigator.clipboard.writeText(currentTarget.offsetParent.innerText) + } catch (error) { + console.log('Copiing text failed, please try again', { + error + }) + } + + // we edit the copyDiv connected to copied text + const divWithNeededId = $(`div[data-identifier='${id}']`) + divWithNeededId.addClass('copiedNotifier') + divWithNeededId.html('Copied!') + + setTimeout(() => { + divWithNeededId.html(innersOfCopyDiv) + divWithNeededId.removeClass('copiedNotifier') + + }, 2000) + }) + + // we edit the button that is added by readthedocs portal + const readTheDocsButton = $('div.rst-versions') + const navbar = $('nav[data-toggle=wy-nav-shift]') + + navbar.append(readTheDocsButton) + +}); + diff --git a/docs/_static/js/footer.js b/docs/_static/js/footer.js new file mode 100644 index 00000000..5f135768 --- /dev/null +++ b/docs/_static/js/footer.js @@ -0,0 +1,92 @@ +$(document).ready(function() { + insertIframe() + + const options = { + threshold: 0.01, + } + const divDoc = document.querySelector('.iframe-container') + const innerSidebar = $('.wy-side-scroll') + + intersectionObserver(options, divDoc, innerSidebar) + + $(window).resize(function() { + intersectionObserver(options, divDoc, innerSidebar) + }) + + $(window).scroll(function() { + intersectionObserver(options, divDoc, innerSidebar) + }) +}); + +function intersectionObserver(options, divDoc, innerSidebar) { + // we delete any inline-styles from innerSidebar + if($(innerSidebar).attr('style')) { + innerSidebar.removeAttr('style') + } + const screenWidth = $(window).width() + const sidebar = $('.wy-nav-side') + const documentHeight = $(document).height() + const iframeHeight = $('.iframe-container').height() + const currentPosition = $(document).scrollTop() + const additionalPaddingFromSidebar = screenWidth > 991 ? 70 : 83 + const heightThatIsAddedByPaddings = 36 + const resultOfSums = documentHeight - + iframeHeight - + currentPosition - + additionalPaddingFromSidebar - + heightThatIsAddedByPaddings + const heightOfAdditionalButton = 50 + + const onEntry = (entries, observer) => { + entries.forEach(entry => { + if(entry.isIntersecting) { + if(resultOfSums <= 70) { + $(sidebar).hide() + return + } + $(sidebar).show() + $(sidebar).height(resultOfSums) + $(sidebar).css('margin-bottom', '20px') + $(innerSidebar).removeAttr('style') + $(innerSidebar).height(resultOfSums - heightOfAdditionalButton) + return + } else { + $(sidebar).removeAttr('style') + $(innerSidebar).removeAttr('style') + } + }) + } + const observer = new IntersectionObserver(onEntry, options); + observer.observe(divDoc) + + if($(innerSidebar).attr('style')) { + observer.unobserve(divDoc) + } + + determineHeightOfFooterContainer() + +} + +function determineHeightOfFooterContainer() { + const iframeFooter= $('#vyos-footer-iframe'); + const title = window.document.getElementsByTagName('title')?.[0]?.text; + const iframeContainer = $('.iframe-container') + const href = window.location.href; + + window.addEventListener('message',function(message){ + if(message.data.footerIframeHeight){ + $(iframeFooter).css('min-height', `${message.data.footerIframeHeight + 1}px`) + $(iframeContainer).height(message.data.footerIframeHeight + 1) + iframeFooter[0].contentWindow.postMessage({title, href},'*'); + } + }) +} + +function insertIframe() { + const body = $('.wy-body-for-nav') + body.append(divWithIframe) +} + +const divWithIframe = `
+ +
` diff --git a/docs/_static/js/sidebar.js b/docs/_static/js/sidebar.js new file mode 100644 index 00000000..8b5c029d --- /dev/null +++ b/docs/_static/js/sidebar.js @@ -0,0 +1,162 @@ +$(document).ready(function () { + removeOverlayAndCloseSidebar() + documentLoaded() + + $(window).on("resize", function () { + const screenWidth = window.innerWidth + + if (screenWidth <= 991) return userIsInTabletScreenWidth(screenWidth) + return removeOverlayAndButtons(screenWidth) + }) + +}) + +function removeButtons() { + const alreadyCreatedOpenButtonCheck = $('.openLeftSidebarMenuButton') + const alreadyCreatedCloseButtonCheck = $('.closeButtonDivLine') + + if(alreadyCreatedOpenButtonCheck[0]) alreadyCreatedOpenButtonCheck[0].remove() + if(alreadyCreatedCloseButtonCheck[0]) alreadyCreatedCloseButtonCheck[0].remove() +} + +function documentLoaded() { + const screenWidth = window.innerWidth + + if (screenWidth <= 991) return userIsInTabletScreenWidth(screenWidth) + return +} + +function userIsInTabletScreenWidth(screenWidth) { + const alreadyCreatedButtonCheck = $('.openLeftSidebarMenuButton') + if (alreadyCreatedButtonCheck[0]) return + createOpenSidebarButton(screenWidth) + createCloseSidebarButton(screenWidth) + removeOverlayAndCloseSidebar() +} + +function createOverlay(screenWidth) { + const contentContainer = $('.wy-nav-content') + contentContainer.addClass('overlay') + + const overlayDiv = ` +
+ ` + + contentContainer.append(overlayDiv) + + $('.wy-nav-content.overlay').on('click', onOverlayClickHandler) +} + +function onOverlayClickHandler() { + removeOverlayAndCloseSidebar() +} + +function removeOverlayAndCloseSidebar() { + const screenWidth = window.innerWidth + + const contentContainer = $('.wy-nav-content') + contentContainer.removeClass('overlay') + + const overlayDiv = $('.overlayDiv') + overlayDiv.remove() + + const leftSidebarOpened = $('nav.wy-nav-side.shift') + leftSidebarOpened.removeClass('shift') + + const leftSidebar = $('nav.wy-nav-side') + + // that's working don't touch + if(screenWidth > 991) { + // when user is not in tablet -> we add classes on opened sidebar and remove classes on closed sidebar + const contentSection = $('section.wy-nav-content-wrap') + const contentDiv = $('div.wy-nav-content') + contentSection.addClass('wy-nav-content-wrap-opened-sidebar') + contentDiv.addClass('wy-nav-content-opened-sidebar') + contentSection.removeClass('wy-nav-content-wrap-closed-sidebar') + contentDiv.removeClass('wy-nav-content-closed-sidebar') + leftSidebar.removeClass('display_none') + return + } + + if(screenWidth <= 991) { + // I add closed classes to make contentContainer 100% width + const contentSection = $('section.wy-nav-content-wrap') + const contentDiv = $('div.wy-nav-content') + contentSection.removeClass('wy-nav-content-wrap-opened-sidebar') + contentDiv.removeClass('wy-nav-content-opened-sidebar') + contentSection.addClass('wy-nav-content-wrap-closed-sidebar') + contentDiv.addClass('wy-nav-content-closed-sidebar') + leftSidebar.addClass('display_none') + } + +} + +function createOpenSidebarButton() { + const divToInsert = $('div[role=navigation][aria-label="Page navigation"]') + divToInsert[0].insertAdjacentHTML('afterbegin', formOpenSidebarButton()) + + const newlyCreatedButton = $('.openLeftSidebarMenuButton') + + newlyCreatedButton.on('click', onOpenLeftSidebarMenuButtonClickHandler) +} + +function onOpenLeftSidebarMenuButtonClickHandler(e) { + e.stopPropagation() + const leftSidebar = $('nav.wy-nav-side') + const leftSidebarOpened = $('nav.wy-nav-side.shift') + if(leftSidebarOpened[0]) { + // leftSidebarOpened.removeClass('shift') + removeOverlayAndCloseSidebar() + } + + createOverlay() + if(leftSidebar.hasClass('display_none')) leftSidebar.removeClass('display_none') + if(leftSidebar.hasClass('.additionalStylesForShift')) leftSidebar.removeClass('.additionalStylesForShift') + // here I add classes to contentSection and contentDiv to make them margined left and remove closed classes if any + const contentSection = $('section.wy-nav-content-wrap') + const contentDiv = $('div.wy-nav-content') + // contentSection.removeClass('wy-nav-content-wrap-closed-sidebar') + // contentDiv.removeClass('wy-nav-content-closed-sidebar') + // contentSection.addClass('wy-nav-content-wrap-opened-sidebar') + // contentDiv.addClass('wy-nav-content-opened-sidebar') + return leftSidebar.addClass('shift') +} + +function createCloseSidebarButton(screenWidth) { + const updatedLeftSidebarScrollDiv = $('nav.wy-nav-side') + + const alreadyCreatedButtonCheck = $('div.closeLeftSidebarMenuButton') + if(alreadyCreatedButtonCheck[0]) return + + updatedLeftSidebarScrollDiv[0].insertAdjacentHTML('beforeend', formCloseLeftSidebarButton()) + updatedLeftSidebarScrollDiv.addClass('additionalStylesForShift') + + const createdCloseSidebarButton = $('.closeButtonDivLine') + + createdCloseSidebarButton.on('click', function () { + removeOverlayAndCloseSidebar() + }) +} + +function formOpenSidebarButton() { + return ` +
+ ${hamburgerIcon} +
+ ` +} + +function formCloseLeftSidebarButton() { + return ` +
+
+ Close +
+
+ ` +} + +function removeOverlayAndButtons(screenWidth) { + removeOverlayAndCloseSidebar() + removeButtons() +} diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html index 6cb68508..5736a26f 100644 --- a/docs/_templates/layout.html +++ b/docs/_templates/layout.html @@ -1,12 +1,32 @@ {% extends "!layout.html" %} {%- set current_version = "1.5.x circinus" %} {% block extrahead %} + + + + + + + + + + + + + + + + + + + + -{% endblock %} -{% block extrabody %} -

Warning: This is the dev version. The latest stable version is - Equuleus 1.3.x.

+ + + + {% endblock %} diff --git a/docs/conf.py b/docs/conf.py index 4414286d..f05832fe 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ from docutils.parsers.rst.roles import set_classes # -- Project information ----------------------------------------------------- project = u'VyOS' -copyright = u'2023, VyOS maintainers and contributors' +copyright = u'2024, VyOS maintainers and contributors' author = u'VyOS maintainers and contributors' # The short X.Y version @@ -192,4 +192,4 @@ texinfo_documents = [ def setup(app): - pass + pass \ No newline at end of file diff --git a/docs/copyright.md b/docs/copyright.md index 2a06d761..97cc30ca 100644 --- a/docs/copyright.md +++ b/docs/copyright.md @@ -1,6 +1,6 @@ # Copyright Notice -Copyright (C) 2018-2023 VyOS maintainers and contributors +Copyright (C) 2018-2024 VyOS maintainers and contributors Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all -- cgit v1.2.3 From 4dd84a7c4d784229209eeb4b0d72457b094e08ce Mon Sep 17 00:00:00 2001 From: aapostoliuk Date: Wed, 21 Feb 2024 16:57:34 +0200 Subject: Rewritten the L2TP documentation Rewritten the L2TP documentation Added the example 'PPPoE over L2TP' to blueprints --- docs/_static/images/lac-lns-diagram.jpg | Bin 0 -> 35665 bytes docs/_static/images/lac-lns-winclient.jpg | Bin 0 -> 90842 bytes docs/configexamples/index.rst | 1 + docs/configexamples/lac-lns.rst | 169 +++++++++ docs/configuration/vpn/l2tp.rst | 551 ++++++++++++++++++++++++------ 5 files changed, 616 insertions(+), 105 deletions(-) create mode 100644 docs/_static/images/lac-lns-diagram.jpg create mode 100644 docs/_static/images/lac-lns-winclient.jpg create mode 100644 docs/configexamples/lac-lns.rst (limited to 'docs/_static') diff --git a/docs/_static/images/lac-lns-diagram.jpg b/docs/_static/images/lac-lns-diagram.jpg new file mode 100644 index 00000000..4463a3c3 Binary files /dev/null and b/docs/_static/images/lac-lns-diagram.jpg differ diff --git a/docs/_static/images/lac-lns-winclient.jpg b/docs/_static/images/lac-lns-winclient.jpg new file mode 100644 index 00000000..9fa99152 Binary files /dev/null and b/docs/_static/images/lac-lns-winclient.jpg differ diff --git a/docs/configexamples/index.rst b/docs/configexamples/index.rst index 7134e14c..d5973eb2 100644 --- a/docs/configexamples/index.rst +++ b/docs/configexamples/index.rst @@ -17,6 +17,7 @@ This chapter contains various configuration examples: wan-load-balancing pppoe-ipv6-basic l3vpn-hub-and-spoke + lac-lns inter-vrf-routing-vrf-lite qos segment-routing-isis diff --git a/docs/configexamples/lac-lns.rst b/docs/configexamples/lac-lns.rst new file mode 100644 index 00000000..b246c4d3 --- /dev/null +++ b/docs/configexamples/lac-lns.rst @@ -0,0 +1,169 @@ +:lastproofread: 2024-02-21 + +.. _examples-lac-lns: + +############### +PPPoE over L2TP +############### + +This document is to describe a basic setup using PPPoE over L2TP. +LAC and LNS are components of the broadband topology. +LAC - L2TP access concentrator +LNS - L2TP Network Server +LAC and LNS forms L2TP tunnel. LAC receives packets from PPPoE clients and +forward them to LNS. LNS is the termination point that comes from PPP packets +from the remote client. + +In this example we use VyOS 1.5 as LNS and Cisco IOS as LAC. +All users with domain **vyos.io** will be tunneled to LNS via L2TP. + +Network Topology +================ + +.. image:: /_static/images/lac-lns-diagram.jpg + :width: 60% + :align: center + :alt: Network Topology Diagram + +Configurations +============== + +LAC +--- + +.. code-block:: none + + aaa new-model + ! + aaa authentication ppp default local + ! + vpdn enable + vpdn aaa attribute nas-ip-address vpdn-nas + ! + vpdn-group LAC + request-dialin + protocol l2tp + domain vyos.io + initiate-to ip 192.168.139.100 + source-ip 192.168.139.101 + local name LAC + l2tp tunnel password 0 test123 + ! + bba-group pppoe MAIN-BBA + virtual-template 1 + ! + interface GigabitEthernet0/0 + description To LNS + ip address 192.168.139.101 255.255.255.0 + duplex auto + speed auto + media-type rj45 + ! + interface GigabitEthernet0/1 + description To PPPoE clients + no ip address + duplex auto + speed auto + media-type rj45 + pppoe enable group MAIN-BBA + ! + +LNS +--- + +.. code-block:: none + + set interfaces ethernet eth0 address '192.168.139.100/24' + set nat source rule 100 outbound-interface name 'eth0' + set nat source rule 100 source address '10.0.0.0/24' + set nat source rule 100 translation address 'masquerade' + set protocols static route 0.0.0.0/0 next-hop 192.168.139.2 + set vpn l2tp remote-access authentication mode 'radius' + set vpn l2tp remote-access authentication radius server 192.168.139.110 key 'radiustest' + set vpn l2tp remote-access client-ip-pool TEST-POOL range '10.0.0.2-10.0.0.100' + set vpn l2tp remote-access default-pool 'TEST-POOL' + set vpn l2tp remote-access gateway-address '10.0.0.1' + set vpn l2tp remote-access lns host-name 'LAC' + set vpn l2tp remote-access lns shared-secret 'test123' + set vpn l2tp remote-access name-server '8.8.8.8' + set vpn l2tp remote-access ppp-options disable-ccp + +.. note:: This setup requires the Compression Control Protocol (CCP) + being disabled, the command ``set vpn l2tp remote-access ppp-options disable-ccp`` + accomplishes that. + +Client +------ + +In this lab we use Windows PPPoE client. + +.. image:: /_static/images/lac-lns-winclient.jpg + :width: 100% + :align: center + :alt: Window PPPoE Client Configuration + +Monitoring +---------- + +Monitoring on LNS side + +.. code-block:: none + + vyos@vyos:~$ show l2tp-server sessions + ifname | username | ip | ip6 | ip6-dp | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes + --------+--------------+----------+-----+--------+-----------------+------------+--------+----------+-----------+---------- + l2tp0 | test@vyos.io | 10.0.0.2 | | | 192.168.139.101 | | active | 00:00:35 | 188.4 KiB | 9.3 MiB + +Monitoring on LAC side + +.. code-block:: none + + Router#show pppoe session + 1 session in FORWARDED (FWDED) State + 1 session total + Uniq ID PPPoE RemMAC Port VT VA State + SID LocMAC VA-st Type + 1 1 000c.290b.20a6 Gi0/1 1 N/A FWDED + 0c58.88ac.0001 + + Router#show l2tp + L2TP Tunnel and Session Information Total tunnels 1 sessions 1 + + LocTunID RemTunID Remote Name State Remote Address Sessn L2TP Class/ + Count VPDN Group + 23238 2640 LAC est 192.168.139.100 1 LAC + + LocID RemID TunID Username, Intf/ State Last Chg Uniq ID + Vcid, Circuit + 25641 25822 23238 test@vyos.io, Gi0/1 est 00:05:36 1 + +Monitoring on RADIUS Server side + +.. code-block:: none + + root@Radius:~# cat /var/log/freeradius/radacct/192.168.139.100/detail-20240221 + Wed Feb 21 13:37:17 2024 + User-Name = "test@vyos.io" + NAS-Port = 0 + NAS-Port-Id = "l2tp0" + NAS-Port-Type = Virtual + Service-Type = Framed-User + Framed-Protocol = PPP + Calling-Station-Id = "192.168.139.101" + Called-Station-Id = "192.168.139.100" + Acct-Status-Type = Start + Acct-Authentic = RADIUS + Acct-Session-Id = "45c731e169d9a4f1" + Acct-Session-Time = 0 + Acct-Input-Octets = 0 + Acct-Output-Octets = 0 + Acct-Input-Packets = 0 + Acct-Output-Packets = 0 + Acct-Input-Gigawords = 0 + Acct-Output-Gigawords = 0 + Framed-IP-Address = 10.0.0.2 + NAS-IP-Address = 192.168.139.100 + Event-Timestamp = "Feb 21 2024 13:37:17 UTC" + Tmp-String-9 = "ai:" + Acct-Unique-Session-Id = "ea6a1089816f19c0d0f1819bc61c3318" + Timestamp = 1708522637 diff --git a/docs/configuration/vpn/l2tp.rst b/docs/configuration/vpn/l2tp.rst index ce3b6711..f0c60ec1 100644 --- a/docs/configuration/vpn/l2tp.rst +++ b/docs/configuration/vpn/l2tp.rst @@ -1,30 +1,80 @@ .. _l2tp: +#### L2TP ----- +#### VyOS utilizes accel-ppp_ to provide L2TP server functionality. It can be used with local authentication or a connected RADIUS server. -L2TP over IPsec -=============== - -Example for configuring a simple L2TP over IPsec VPN for remote access (works -with native Windows and Mac VPN clients): +*********************** +Configuring L2TP Server +*********************** .. code-block:: none - set vpn ipsec interface eth0 - - set vpn l2tp remote-access outside-address 192.0.2.2 + set vpn l2tp remote-access authentication mode local + set vpn l2tp remote-access authentication local-users username test password 'test' set vpn l2tp remote-access client-ip-pool L2TP-POOL range 192.168.255.2-192.168.255.254 set vpn l2tp remote-access default-pool 'L2TP-POOL' + set vpn l2tp remote-access outside-address 192.0.2.2 + set vpn l2tp remote-access gateway-address 192.168.255.1 + + +.. cfgcmd:: set vpn l2tp remote-access authentication mode + + Set authentication backend. The configured authentication backend is used + for all queries. + + * **radius**: All authentication queries are handled by a configured RADIUS + server. + * **local**: All authentication queries are handled locally. + +.. cfgcmd:: set vpn l2tp remote-access authentication local-users username password + + + Create `` for local authentication on this system. The users password + will be set to ``. + +.. cfgcmd:: set vpn l2tp remote-access client-ip-pool range + + Use this command to define the first IP address of a pool of + addresses to be given to l2tp clients. If notation ``x.x.x.x-x.x.x.x``, + it must be within a /24 subnet. If notation ``x.x.x.x/x`` is + used there is possibility to set host/netmask. + +.. cfgcmd:: set vpn l2tp remote-access default-pool + + Use this command to define default address pool name. + +.. cfgcmd:: set vpn l2tp remote-access gateway-address + + Specifies single `` IP address to be used as local address of PPP + interfaces. + +***************** +Configuring IPsec +***************** + +.. code-block:: none + + set vpn ipsec interface eth0 set vpn l2tp remote-access ipsec-settings authentication mode pre-shared-secret set vpn l2tp remote-access ipsec-settings authentication pre-shared-secret - set vpn l2tp remote-access authentication mode local - set vpn l2tp remote-access authentication local-users username test password 'test' -In the above example, an external IP of 192.0.2.2 is assumed. + +.. cfgcmd:: set vpn ipsec interface + + Use this command to define IPsec interface. + +.. cfgcmd:: set vpn l2tp remote-access ipsec-settings authentication mode + + Set mode for IPsec authentication between VyOS and L2TP clients. + +.. cfgcmd:: set vpn l2tp remote-access ipsec-settings authentication mode + + Set predefined shared secret phrase. + If a local firewall policy is in place on your external interface you will need to allow the ports below: @@ -64,156 +114,150 @@ To allow VPN-clients access via your external address, a NAT rule is required: set nat source rule 110 source address '192.168.255.0/24' set nat source rule 110 translation address masquerade +********************************* +Configuring RADIUS authentication +********************************* -VPN-clients will request configuration parameters, optionally you can DNS -parameter to the client. +To enable RADIUS based authentication, the authentication mode needs to be +changed within the configuration. Previous settings like the local users, still +exists within the configuration, however they are not used if the mode has been +changed from local to radius. Once changed back to local, it will use all local +accounts again. .. code-block:: none - set vpn l2tp remote-access name-server '198.51.100.8' - set vpn l2tp remote-access name-server '198.51.100.4' - -Established sessions can be viewed using the **show l2tp-server sessions** -operational command + set vpn l2tp remote-access authentication mode radius -.. code-block:: none +.. cfgcmd:: set vpn l2tp remote-access authentication radius server key - vyos@vyos:~$ show l2tp-server sessions - ifname | username | ip | ip6 | ip6-dp | calling-sid | rate-limit | state | uptime | rx-bytes | tx-bytes - --------+----------+---------------+-----+--------+-------------+------------+--------+----------+----------+---------- - l2tp0 | test | 192.168.255.3 | | | 192.168.0.36 | | active | 02:01:47 | 7.7 KiB | 1.2 KiB + Configure RADIUS `` and its required shared `` for + communicating with the RADIUS server. +Since the RADIUS server would be a single point of failure, multiple RADIUS +servers can be setup and will be used subsequentially. +For example: +.. code-block:: none -LNS (L2TP Network Server) -========================= + set vpn l2tp remote-access authentication radius server 10.0.0.1 key 'foo' + set vpn l2tp remote-access authentication radius server 10.0.0.2 key 'foo' -LNS are often used to connect to a LAC (L2TP Access Concentrator). +.. note:: Some RADIUS_ severs use an access control list which allows or denies + queries, make sure to add your VyOS router to the allowed client list. -Below is an example to configure a LNS: +RADIUS source address +===================== -.. code-block:: none +If you are using OSPF as IGP, always the closest interface connected to the +RADIUS server is used. With VyOS 1.2 you can bind all outgoing RADIUS requests +to a single source IP e.g. the loopback interface. - set vpn l2tp remote-access outside-address 192.0.2.2 - set vpn l2tp remote-access client-ip-pool L2TP-POOL range 192.168.255.2-192.168.255.254 - set vpn l2tp remote-access default-pool 'L2TP-POOL' - set vpn l2tp remote-access lns shared-secret 'secret' - set vpn l2tp remote-access ppp-options disable-ccp - set vpn l2tp remote-access authentication mode local - set vpn l2tp remote-access authentication local-users username test password 'test' +.. cfgcmd:: set vpn l2tp remote-access authentication radius source-address
-The example above uses 192.0.2.2 as external IP address. A LAC normally requires -an authentication password, which is set in the example configuration to -``lns shared-secret 'secret'``. This setup requires the Compression Control -Protocol (CCP) being disabled, the command ``set vpn l2tp remote-access -ccp-disable`` accomplishes that. + Source IPv4 address used in all RADIUS server queires. +.. note:: The ``source-address`` must be configured on one of VyOS interface. + Best practice would be a loopback or dummy interface. -Bandwidth Shaping -================= +RADIUS advanced options +======================= -Bandwidth rate limits can be set for local users or via RADIUS based attributes. +.. cfgcmd:: set vpn l2tp remote-access authentication radius server port -Bandwidth Shaping for local users -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Configure RADIUS `` and its required port for authentication requests. -The rate-limit is set in kbit/sec. +.. cfgcmd:: set vpn l2tp remote-access authentication radius server fail-time