Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • tfs/controller
1 result
Show changes
Commits on Source (646)
Showing with 553 additions and 17 deletions
......@@ -179,5 +179,3 @@ libyang/
# Other logs
**/logs/*.log.*
# PySpark checkpoints
src/analytics/.spark/*
......@@ -48,8 +48,8 @@ include:
- local: '/src/bgpls_speaker/.gitlab-ci.yml'
- local: '/src/kpi_manager/.gitlab-ci.yml'
- local: '/src/kpi_value_api/.gitlab-ci.yml'
- local: '/src/kpi_value_writer/.gitlab-ci.yml'
- local: '/src/telemetry/.gitlab-ci.yml'
#- local: '/src/kpi_value_writer/.gitlab-ci.yml'
#- local: '/src/telemetry/.gitlab-ci.yml'
- local: '/src/analytics/.gitlab-ci.yml'
- local: '/src/qos_profile/.gitlab-ci.yml'
- local: '/src/vnt_manager/.gitlab-ci.yml'
......
......@@ -15,6 +15,7 @@
coverage==6.3
grpcio==1.47.*
grpcio-health-checking==1.47.*
grpcio-reflection==1.47.*
grpcio-tools==1.47.*
grpclib==0.4.4
prettytable==3.5.0
......
......@@ -215,6 +215,9 @@ export GRAF_EXT_PORT_HTTP=${GRAF_EXT_PORT_HTTP:-"3000"}
# Deploy Apache Kafka
./deploy/kafka.sh
#Deploy Monitoring (Prometheus, Mimir, Grafana)
./deploy/monitoring.sh
# Expose Dashboard
./deploy/expose_dashboard.sh
......
......@@ -42,7 +42,7 @@ export KFK_REDEPLOY=${KFK_REDEPLOY:-""}
mkdir -p ${TMP_MANIFESTS_FOLDER}
function kafka_deploy() {
# copy zookeeper and kafka manifest files to temporary manifest location
# copy zookeeper and kafka manifest files to temporary manifest location
cp "${KFK_MANIFESTS_PATH}/${KFK_ZOOKEEPER_MANIFEST}" "${TMP_MANIFESTS_FOLDER}/${KFK_ZOOKEEPER_MANIFEST}"
cp "${KFK_MANIFESTS_PATH}/${KFK_MANIFEST}" "${TMP_MANIFESTS_FOLDER}/${KFK_MANIFEST}"
......@@ -57,11 +57,12 @@ function kafka_deploy() {
# Kafka zookeeper service should be deployed before the kafka service
kubectl --namespace ${KFK_NAMESPACE} apply -f "${TMP_MANIFESTS_FOLDER}/${KFK_ZOOKEEPER_MANIFEST}"
KFK_ZOOKEEPER_SERVICE="zookeeper-service" # this command may be replaced with command to extract service name automatically
KFK_ZOOKEEPER_IP=$(kubectl --namespace ${KFK_NAMESPACE} get service ${KFK_ZOOKEEPER_SERVICE} -o 'jsonpath={.spec.clusterIP}')
#KFK_ZOOKEEPER_SERVICE="zookeeper-service" # this command may be replaced with command to extract service name automatically
#KFK_ZOOKEEPER_IP=$(kubectl --namespace ${KFK_NAMESPACE} get service ${KFK_ZOOKEEPER_SERVICE} -o 'jsonpath={.spec.clusterIP}')
# Kafka service should be deployed after the zookeeper service
sed -i "s/<ZOOKEEPER_INTERNAL_IP>/${KFK_ZOOKEEPER_IP}/" "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST"
#sed -i "s/<ZOOKEEPER_INTERNAL_IP>/${KFK_ZOOKEEPER_IP}/" "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST"
sed -i "s/<KAFKA_NAMESPACE>/${KFK_NAMESPACE}/" "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST"
# echo ">>> Deploying Apache Kafka Broker"
kubectl --namespace ${KFK_NAMESPACE} apply -f "${TMP_MANIFESTS_FOLDER}/$KFK_MANIFEST"
......
#!/bin/bash
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
# -----------------------------------------------------------
# Global namespace for all deployments
# -----------------------------------------------------------
NAMESPACE="monitoring"
VALUES_FILE_PATH="manifests/monitoring"
# -----------------------------------------------------------
# Prometheus Configuration
# -----------------------------------------------------------
RELEASE_NAME_PROM="mon-prometheus"
CHART_REPO_NAME_PROM="prometheus-community"
CHART_REPO_URL_PROM="https://prometheus-community.github.io/helm-charts"
CHART_NAME_PROM="prometheus"
VALUES_FILE_PROM="$VALUES_FILE_PATH/prometheus_values.yaml"
# -----------------------------------------------------------
# Mimir Configuration
# -----------------------------------------------------------
# RELEASE_NAME_MIMIR="mon-mimir"
# CHART_REPO_NAME_MIMIR="grafana"
# CHART_REPO_URL_MIMIR="https://grafana.github.io/helm-charts"
# CHART_NAME_MIMIR="mimir-distributed"
# VALUES_FILE_MIMIR="$VALUES_FILE_PATH/mimir_values.yaml"
# -----------------------------------------------------------
# Grafana Configuration
# -----------------------------------------------------------
# RELEASE_NAME_GRAFANA="mon-grafana"
# CHART_REPO_NAME_GRAFANA="grafana"
# CHART_REPO_URL_GRAFANA="https://grafana.github.io/helm-charts"
# CHART_NAME_GRAFANA="grafana"
# VALUES_FILE_GRAFANA="$VALUES_FILE_PATH/grafana_values.yaml"
# -----------------------------------------------------------
# Function to deploy or upgrade a Helm chart
# -----------------------------------------------------------
deploy_chart() {
local release_name="$1"
local chart_repo_name="$2"
local chart_repo_url="$3"
local chart_name="$4"
local values_file="$5"
local namespace="$6"
echo ">>> Deploying [${release_name}] from repo [${chart_repo_name}]..."
# Add or update the Helm repo
echo "Adding/updating Helm repo: $chart_repo_name -> $chart_repo_url"
helm repo add "$chart_repo_name" "$chart_repo_url" || true
helm repo update
# Create namespace if needed
echo "Creating namespace '$namespace' if it doesn't exist..."
kubectl get namespace "$namespace" >/dev/null 2>&1 || kubectl create namespace "$namespace"
# Install or upgrade the chart
if [ -n "$values_file" ] && [ -f "$values_file" ]; then
echo "Installing/Upgrading $release_name using custom values from $values_file..."
helm upgrade --install "$release_name" "$chart_repo_name/$chart_name" \
--namespace "$namespace" \
--values "$values_file"
else
echo "Installing/Upgrading $release_name with default chart values..."
helm upgrade --install "$release_name" "$chart_repo_name/$chart_name" \
--namespace "$namespace"
fi
echo "<<< Deployment initiated for [$release_name]."
echo
}
# -----------------------------------------------------------
# Actual Deployments
# -----------------------------------------------------------
# 1) Deploy Prometheus
deploy_chart "$RELEASE_NAME_PROM" \
"$CHART_REPO_NAME_PROM" \
"$CHART_REPO_URL_PROM" \
"$CHART_NAME_PROM" \
"$VALUES_FILE_PROM" \
"$NAMESPACE"
# Optionally wait for Prometheus server pod to become ready
kubectl rollout status deployment/"$RELEASE_NAME_PROM-server" -n "$NAMESPACE" || true
# 2) Deploy Mimir
# deploy_chart "$RELEASE_NAME_MIMIR" \
# "$CHART_REPO_NAME_MIMIR" \
# "$CHART_REPO_URL_MIMIR" \
# "$CHART_NAME_MIMIR" \
# "$VALUES_FILE_MIMIR" \
# "$NAMESPACE"
# Depending on how Mimir runs (StatefulSets, Deployments), you can wait for
# the correct resource to be ready. For example:
# kubectl rollout status statefulset/"$RELEASE_NAME_MIMIR-distributor" -n "$NAMESPACE" || true
# 3) Deploy Grafana
# deploy_chart "$RELEASE_NAME_GRAFANA" \
# "$CHART_REPO_NAME_GRAFANA" \
# "$CHART_REPO_URL_GRAFANA" \
# "$CHART_NAME_GRAFANA" \
# "$VALUES_FILE_GRAFANA" \
# "$NAMESPACE"
# kubectl rollout status deployment/"$RELEASE_NAME_GRAFANA" -n "$NAMESPACE" || true
# -----------------------------------------------------------
echo "All deployments completed!"
......@@ -69,8 +69,7 @@ function nats_deploy_single() {
echo ">>> NATS is present; skipping step."
else
echo ">>> Deploy NATS"
helm3 install ${NATS_NAMESPACE} nats/nats --namespace ${NATS_NAMESPACE} --set nats.image=nats:2.9-alpine --set config.cluster.enabled=true --set config.cluster.tls.enabled=true
helm3 install ${NATS_NAMESPACE} nats/nats --namespace ${NATS_NAMESPACE} --set nats.image=nats:2.9-alpine
echo ">>> Waiting NATS statefulset to be created..."
while ! kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; do
......
......@@ -153,7 +153,7 @@ kubectl create secret generic crdb-data --namespace ${TFS_K8S_NAMESPACE} --type=
--from-literal=CRDB_SSLMODE=require
printf "\n"
echo ">>> Create Secret with Apache Kakfa..."
echo ">>> Create Secret with Apache Kafka..."
KFK_SERVER_PORT=$(kubectl --namespace ${KFK_NAMESPACE} get service kafka-service -o 'jsonpath={.spec.ports[0].port}')
kubectl create secret generic kfk-kpi-data --namespace ${TFS_K8S_NAMESPACE} --type='Opaque' \
--from-literal=KFK_NAMESPACE=${KFK_NAMESPACE} \
......@@ -342,11 +342,7 @@ for COMPONENT in $TFS_COMPONENTS; do
sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT-gateway:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
else
VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f4)
if [ "$TFS_SKIP_BUILD" != "YES" ]; then
IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
else
IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT:$VERSION" | sed 's,//,/,g' | sed 's,http:/,,g')
fi
IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g')
sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
fi
......
src/tests/ecoc24/
\ No newline at end of file
clab-*/
*.clab.yml.bak
*.tar
*.tar.gz
# Hackfest 5 - Control an Emulated DataPlane through TeraFlowSDN
## Prepare your VM
```bash
cd ~/tfs-ctrl
git checkout feat/hackfest5
git pull
```
## ContainerLab Commands
### Download and install ContainerLab
```bash
sudo bash -c "$(curl -sL https://get.containerlab.dev)" -- -v 0.59.0
```
### Check available images in Docker
```bash
docker images | grep -E "ceos|multitool"
```
### Download hackfest5 cEOS image and create Docker image [already done]
- Note: Image to be downloaded for free from [Arista](https://www.arista.com/en/login) website.
```bash
docker import ~/tfs-ctrl/hackfest5/images/arista/cEOS64-lab-4.31.5M.tar ceos:4.31.5M
docker import ~/tfs-ctrl/hackfest5/images/arista/cEOS64-lab-4.32.2F.tar ceos:4.32.2F
```
### Deploy scenario
```bash
~/tfs-ctrl/hackfest5/clab-deploy.sh
```
### Inspect scenario
```bash
~/tfs-ctrl/hackfest5/clab-inspect.sh
```
### Show scenario's topology
```bash
~/tfs-ctrl/hackfest5/clab-graph.sh
```
### Destroy scenario
```bash
~/tfs-ctrl/hackfest5/clab-destroy.sh
```
### Access cEOS CLI
```bash
~/tfs-ctrl/hackfest5/clab-cli-r1.sh
```
### Access DC CLI
```bash
~/tfs-ctrl/hackfest5/clab-cli-dc1.sh
```
### Start pinging remote DC
```bash
~/tfs-ctrl/hackfest5/clab-cli-dc1.sh
ping 192.168.2.10
```
## TeraFlowSDN Commands
### Check status of MicroK8s
```bash
microk8s.status --wait-ready
```
### Start MicroK8s
```bash
microk8s.start
```
### Periodically report status of MicroK8s every second
```bash
watch -n 1 microk8s.status --wait-ready
```
### Periodically report status of workload in MicroK8s every second
```bash
watch -n 1 kubectl get all --all-namespaces
```
### Re-Deploy TeraFlowSDN
```bash
~/tfs-ctrl/hackfest5/redeploy-tfs.sh
```
### Show TeraFlowSDN Deployment status
```bash
source ~/tfs-ctrl/hackfest5/deploy_specs.sh
./deploy/show.sh
```
### Show log of a TeraFlowSDN component
```bash
source ~/tfs-ctrl/hackfest5/deploy_specs.sh
~/tfs-ctrl/scripts/show_logs_device.sh
```
## L3VPN Commands
### Create a new IETF L3VPN through TeraFlowSDN NBI
```bash
cd ~/tfs-ctrl/hackfest5/data
curl -X POST \
--header "Content-Type: application/json" \
--data @ietf-l3vpn-service.json \
--user "admin:admin" \
http://127.0.0.1/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services
```
### Get UUID of a IETF L3VPN through TeraFlowSDN NBI
```bash
curl --user "admin:admin" \
http://127.0.0.1/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services/vpn-service=ietf-l3vpn-svc/
```
### Delete a IETF L3VPN through TeraFlowSDN NBI
```bash
curl -X DELETE --user "admin:admin" \
http://127.0.0.1/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services/vpn-service=ietf-l3vpn-svc/
```
### Start pinging remote DC
```bash
~/tfs-ctrl/hackfest5/clab-cli-dc1.sh
ping 192.168.2.10
```
## gNMIc Commands
### Install gNMIc
```bash
sudo bash -c "$(curl -sL https://get-gnmic.kmrd.dev)"
```
### gNMI Capabilities request
```bash
gnmic --address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure capabilities
```
### gNMI Get request
```bash
gnmic --address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf get --path / > r1.json
gnmic --address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf get --path /interfaces/interface > r1-ifaces.json
```
### gNMI Set request
```bash
gnmic --address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf set --update-path /system/config/hostname --update-value "my-r1"
gnmic --address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf get --path /system/config/hostname
```
### Subscribe request
```bash
gnmic --address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf subscribe --path /interfaces/interface[name=Management0]/state/
# In another terminal, you can generate traffic opening SSH connection
ssh admin@clab-hackfest5-r1
```
### Check configurations done:
```bash
gnmic --address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf get --path '/network-instances' > r1-nis.json
gnmic --address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf get --path '/interfaces' > r1-ifs.json
```
### Delete elements:
```bash
--address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf set --delete '/network-instances/network-instance[name=b19229e8]'
--address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf set --delete '/interfaces/interface[name=ethernet-1/1]/subinterfaces/subinterface[index=0]'
--address clab-hackfest5-r1 --port 6030 --username admin --password admin --insecure --encoding json_ietf set --delete '/interfaces/interface[name=ethernet-1/2]/subinterfaces/subinterface[index=0]'
```
#!/bin/bash
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
docker exec -it clab-hackfest5-dc1 bash
#!/bin/bash
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
docker exec -it clab-hackfest5-dc2 bash
#!/bin/bash
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
docker exec -it clab-hackfest5-r1 Cli
#!/bin/bash
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
docker exec -it clab-hackfest5-r2 Cli
#!/bin/bash
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cd ~/tfs-ctrl/hackfest5
sudo containerlab deploy --topo hackfest5.clab.yml
#!/bin/bash
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cd ~/tfs-ctrl/hackfest5
sudo containerlab destroy --topo hackfest5.clab.yml
sudo rm -rf clab-hackfest5/ .hackfest5.clab.yml.bak
#!/bin/bash
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cd ~/tfs-ctrl/hackfest5
sudo containerlab graph --topo hackfest5.clab.yml
#!/bin/bash
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cd ~/tfs-ctrl/hackfest5
sudo containerlab inspect --topo hackfest5.clab.yml
{
"ietf-l3vpn-svc:l3vpn-svc": {
"vpn-services": {"vpn-service": [{"vpn-id": "ietf-l3vpn-svc"}]},
"sites": {
"site": [
{
"site-id": "site_DC1",
"management": {"type": "ietf-l3vpn-svc:provider-managed"},
"locations": {"location": [{"location-id": "DC1"}]},
"devices": {"device": [{"device-id": "dc1", "location": "DC1"}]},
"site-network-accesses": {
"site-network-access": [
{
"site-network-access-id": "eth1",
"site-network-access-type": "ietf-l3vpn-svc:multipoint",
"device-reference": "dc1",
"vpn-attachment": {"vpn-id": "ietf-l3vpn-svc", "site-role": "ietf-l3vpn-svc:spoke-role"},
"ip-connection": {
"ipv4": {
"address-allocation-type": "ietf-l3vpn-svc:static-address",
"addresses": {
"provider-address": "192.168.1.1",
"customer-address": "192.168.1.10",
"prefix-length": 24
}
}
},
"service": {
"svc-mtu": 1500,
"svc-input-bandwidth": 1000000000,
"svc-output-bandwidth": 1000000000,
"qos": {"qos-profile": {"classes": {"class": [{
"class-id": "qos-realtime",
"direction": "ietf-l3vpn-svc:both",
"latency": {"latency-boundary": 10},
"bandwidth": {"guaranteed-bw-percent": 100}
}]}}}
}
}
]
}
},
{
"site-id": "site_DC2",
"management": {"type": "ietf-l3vpn-svc:provider-managed"},
"locations": {"location": [{"location-id": "DC2"}]},
"devices": {"device": [{"device-id": "dc2", "location": "DC2"}]},
"site-network-accesses": {
"site-network-access": [
{
"site-network-access-id": "eth1",
"site-network-access-type": "ietf-l3vpn-svc:multipoint",
"device-reference": "dc2",
"vpn-attachment": {"vpn-id": "ietf-l3vpn-svc", "site-role": "ietf-l3vpn-svc:hub-role"},
"ip-connection": {
"ipv4": {
"address-allocation-type": "ietf-l3vpn-svc:static-address",
"addresses": {
"provider-address": "192.168.2.1",
"customer-address": "192.168.2.10",
"prefix-length": 24
}
}
},
"service": {
"svc-mtu": 1500,
"svc-input-bandwidth": 1000000000,
"svc-output-bandwidth": 1000000000,
"qos": {"qos-profile": {"classes": {"class": [{
"class-id": "qos-realtime",
"direction": "ietf-l3vpn-svc:both",
"latency": {"latency-boundary": 10},
"bandwidth": {"guaranteed-bw-percent": 100}
}]}}}
}
}
]
}
}
]
}
}
}