From 4a3ef5d191baed9835925c9bd4f0084075e61648 Mon Sep 17 00:00:00 2001 From: Matteo Pagin Date: Thu, 8 May 2025 14:01:13 +0200 Subject: [PATCH 1/8] Initial EXata DT component setup --- exata_dt/.tnlcm/public.yaml | 57 +++++++ exata_dt/README.md | 16 ++ exata_dt/changelog.md | 6 + exata_dt/code/component_playbook.yaml | 160 ++++++++++++++++++ .../one/cac/01_pre/jenkins_ssh_config.yaml | 10 ++ .../one/cac/01_pre/tnuser_ssh_config.yaml | 16 ++ .../code/one/cac/01_pre/vm_resources.yaml | 21 +++ exata_dt/code/one/iac/loadcore_agent.tf.j2 | 48 ++++++ exata_dt/result_templates/fail_result.md.j2 | 5 + exata_dt/result_templates/ok_result.md.j2 | 23 +++ exata_dt/sample_input_file.yaml | 7 + ...tnlcm_descriptor_open5gs_k8s_loadcore.yaml | 66 ++++++++ ..._tnlcm_descriptor_open5gs_vm_loadcore.yaml | 76 +++++++++ exata_dt/variables/one/private.yaml | 16 ++ 14 files changed, 527 insertions(+) create mode 100644 exata_dt/.tnlcm/public.yaml create mode 100644 exata_dt/README.md create mode 100644 exata_dt/changelog.md create mode 100644 exata_dt/code/component_playbook.yaml create mode 100644 exata_dt/code/one/cac/01_pre/jenkins_ssh_config.yaml create mode 100644 exata_dt/code/one/cac/01_pre/tnuser_ssh_config.yaml create mode 100644 exata_dt/code/one/cac/01_pre/vm_resources.yaml create mode 100644 exata_dt/code/one/iac/loadcore_agent.tf.j2 create mode 100644 exata_dt/result_templates/fail_result.md.j2 create mode 100644 exata_dt/result_templates/ok_result.md.j2 create mode 100644 exata_dt/sample_input_file.yaml create mode 100644 exata_dt/sample_tnlcm_descriptor_open5gs_k8s_loadcore.yaml create mode 100644 exata_dt/sample_tnlcm_descriptor_open5gs_vm_loadcore.yaml create mode 100644 exata_dt/variables/one/private.yaml diff --git a/exata_dt/.tnlcm/public.yaml b/exata_dt/.tnlcm/public.yaml new file mode 100644 index 00000000..3104a810 --- /dev/null +++ b/exata_dt/.tnlcm/public.yaml @@ -0,0 +1,57 @@ +###################################################### +## +## Component public variables +## +## Diverse information read by the TNLCM +## to adapt its behaviour depending on the component. +## +###################################################### + + +#################################### +## Component metadata +#################################### +metadata: + maintainers: + - Álvaro Curto Merino + - Matteo Pagin + short_description: EXata DT appliance for KVM + long_description: | + Appliance with preinstalled EXata DT as a Docker image. + hypervisors: ["one"] + appliances: ["https://marketplace.mobilesandbox.cloud:9443/appliance/EXata"] + + +#################################### +## Site-specific variables +#################################### +site_variables: + exata_licensing_server_ip: IP address of the EXata licensing server in your site. + base_appliance: + # TODO: Needed? + # template_id: ID of the 'LoadCore Agent Test Tool' VM template to use in your OpenNebula environment + # image_id: ID of the 'LoadCore Agent Test Tool' VM image to use in your OpenNebula environment + hugepages_appliance: + # TODO: Needed? + # template_id: ID of the 'LoadCore Agent Test Tool + hugepages' VM template to use in your OpenNebula environment + # image_id: ID of the 'LoadCore Agent Test Tool + hugepages' VM image to use in your OpenNebula environment + + + +#################################### +## Input variables +#################################### +input: + one_loadcore_agent_networks: + description: Ordered list of Virtual Network names the VM will be part of. The first Virtual Network is used by Jenkins to reach and configure the VM, so most cases will be fine using always the tn_vxlan + type: "list[tn_vxlan or vnet]" + default_value: ["tn_vxlan"] + required_when: false + + +#################################### +## Generated terraform outputs +#################################### +terraform_outputs: + __entity_name__id: "VM ID in OpenNebula. Generated from Terraform Manifest" + __entity_name__ips: "Dictionary of VM IP addresses: {: }. Generated from Terraform Manifest" diff --git a/exata_dt/README.md b/exata_dt/README.md new file mode 100644 index 00000000..b9211afb --- /dev/null +++ b/exata_dt/README.md @@ -0,0 +1,16 @@ +# loadcore_agent + +Deploy a VM with Keysight's LoadCore Agent ready to play. +After booting, the agent is automatically registered to the LoadCore Middleware server. + +This component requires a working Loadcore Middleware exposed to the Trial Networks in the site. The Middleware IP address can be provided in the 6G-Sandbox-Sites repository branch of the site. +To set this applinace in your site, please first download either the [base appliance](https://marketplace.mobilesandbox.cloud:9443/appliance/loadcore_agent) or the one with [hugepages](https://marketplace.mobilesandbox.cloud:9443/appliance/loadcore_agent_hugepages). The hugepages appliance is heavier but provides better support for DPDK. + + +### Sample Trial Network using loadcore_agent with an open5gs_k8s 5G Core + +![loadcore_open5gs_k8s](https://github.com/6G-SANDBOX/6G-Library/blob/assets/loadcore/loadcore_open5gs_k8s.png) + +### Sample Trial Network using loadcore_agent with an open5gs_vm 5G Core + +![loadcore_open5gs_vm](https://github.com/6G-SANDBOX/6G-Library/blob/assets/loadcore/loadcore_open5gs_vm.png) diff --git a/exata_dt/changelog.md b/exata_dt/changelog.md new file mode 100644 index 00000000..7a5af9a9 --- /dev/null +++ b/exata_dt/changelog.md @@ -0,0 +1,6 @@ +# Changelog + +## v0.5.0 + +### Added +- Initial release of `exata_dt` component to the 6G-Library. diff --git a/exata_dt/code/component_playbook.yaml b/exata_dt/code/component_playbook.yaml new file mode 100644 index 00000000..1f0f1691 --- /dev/null +++ b/exata_dt/code/component_playbook.yaml @@ -0,0 +1,160 @@ +--- +- name: "STAGE 1: Apply IAC to deploy the component" + hosts: localhost + gather_facts: false + connection: local + tasks: + - name: Load enviromental variables from different sources + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/load_variables.yaml" + + - name: Prepare terraform working directory + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/terraform_workdir.yaml" + + - name: Configure selected VM resources + ansible.builtin.include_tasks: "{{ workspace }}/{{ component_type }}/code/{{ site_hypervisor }}/cac/01_pre/vm_resources.yaml" + + - name: Terraform apply + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/terraform_apply.yaml" + + +- name: "STAGE 2: Prepare to access the component" + hosts: localhost + gather_facts: false + connection: local + tasks: + - name: Retrieve terraform outputs + ansible.builtin.shell: + args: + chdir: "{{ workspace }}/.terraform/" + cmd: "set -o pipefail && terraform output --json | jq 'with_entries(.value |= .value)'" + executable: /bin/bash + register: terraform_outputs + changed_when: false + + - name: Set Terraform outputs as playbook facts + ansible.builtin.set_fact: + bastion_ip: "{{ (terraform_outputs.stdout | from_json)['tn_bastion-ips'][site_networks_id.default | string] }}" + tn_ssh_public_key: "{{ (terraform_outputs.stdout | from_json)['tn_ssh_public_key'] }}" + tn_dns_token: "{{ (terraform_outputs.stdout | from_json)['tn_dns_token'] }}" + ips: "{{ (terraform_outputs.stdout | from_json)[entity_name + '-ips'] }}" + id: "{{ (terraform_outputs.stdout | from_json)[entity_name + '-id'] }}" + access_vnet_id: "{{ (terraform_outputs.stdout | from_json)[one_exata_dt_networks[0] + '-id'] | string }}" + domain_name: >- + {{ + ( + (component_type | regex_replace('_', '') | lower) ~ '-' ~ + (custom_name | regex_replace('_', '') | lower) ~ '.' ~ + (tn_id | regex_replace('_', '') | lower) ~ '.' ~ + site_domain + ) | trim + }} + + - name: Add new VM to Ansible Inventory + ansible.builtin.add_host: + hostname: "EXata" + ansible_host: "{{ ips[access_vnet_id][0] }}" + ansible_ssh_common_args: "-J jenkins@{{ bastion_ip }}" + ansible_user: "jenkins" + + - name: Add tn_bastion to Ansible Inventory + ansible.builtin.add_host: + hostname: "bastion" + ansible_host: "{{ bastion_ip }}" + ansible_user: "jenkins" + + - name: Add new VM to SSH config file in the Jenkins-master for debugging purposes + ansible.builtin.include_tasks: "{{ workspace }}/EXata/code/{{ site_hypervisor }}/cac/01_pre/jenkins_ssh_config.yaml" + + - name: Add new VM to an SSH config file ment to be usable by the experimenter + ansible.builtin.include_tasks: "{{ workspace }}/EXata/code/{{ site_hypervisor }}/cac/01_pre/tnuser_ssh_config.yaml" + + +- name: "STAGE 3: Apply CAC to prepare the component" + hosts: "EXata" + gather_facts: false + tasks: + - name: Wait for system to become reachable + ansible.builtin.wait_for_connection: + connect_timeout: 5 + timeout: 200 + + - name: Load enviromental variables from different sources + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/load_variables.yaml" + + - name: Set site ssh key as authorized in jenkins user + ansible.posix.authorized_key: + user: jenkins + state: present + key: "{{ item }}" + loop: + - "{{ hostvars['localhost'].get('site_admin_ssh_public_key', '') }}" + when: item != '' + + #TODO: Customize this? + - name: Create new user for experimenter access + become: true + ansible.builtin.user: + name: tnuser + shell: /bin/bash + groups: sudo + password: '' + - name: Set TN ssh key as authorized in new user + become: true + ansible.posix.authorized_key: + user: tnuser + state: present + key: "{{ item }}" + loop: + - "{{ hostvars['localhost'].get('tn_ssh_public_key', '') }}" + + #TODO: Remove this? + # - name: Remove user ixia + # ansible.builtin.user: + # name: ixia + # state: absent + # remove: true + # become: true + # when: not hostvars['localhost'].get('one_loadcore_agent_ixia', false) + + # - name: Execute bash script to register the Agent with the Middleware + # ansible.builtin.shell: | + # set -o pipefail + # printf "{{ middleware_ip }}\neth0\ny\nn" | /opt/5gc-test-engine/agent-setup.sh + # args: + # executable: /bin/bash + # vars: + # middleware_ip: "{{ hostvars.localhost.site_available_components.loadcore_agent.loadcore_middleware_ip | default('') }}" + # become: true + # changed_when: false + +#TODO: Customize this to allow access to the licensing server +# - name: "STAGE 4: Access tn_bastion to set firewall exceptions" +# hosts: bastion +# gather_facts: false +# tasks: +# - name: Write firewall exception for the Loadcore Middleware +# ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/nftables_add.yaml" +# vars: +# fw_exceptions: +# - "{{ hostvars.localhost.site_available_components.loadcore_agent.loadcore_middleware_ip | default('') }}" + + +- name: "STAGE 5: Publish execution results" + hosts: localhost + gather_facts: false + connection: local + tasks: + - name: Set DNS record for the component + ansible.builtin.uri: + url: >- + {{ + 'http://' ~ bastion_ip ~ ':5380/api/zones/records/add?token=' ~ tn_dns_token ~ + '&domain=' ~ domain_name ~ + '&type=A&ptr=true&createPtrZone=true&ipAddress=' ~ ips[access_vnet_id][0] | trim + }} + method: POST + body_format: json + status_code: [200] + + - name: Publish execution results to TNLCM and S3 object storage + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/publish_ok_results.yaml" diff --git a/exata_dt/code/one/cac/01_pre/jenkins_ssh_config.yaml b/exata_dt/code/one/cac/01_pre/jenkins_ssh_config.yaml new file mode 100644 index 00000000..4b87f58d --- /dev/null +++ b/exata_dt/code/one/cac/01_pre/jenkins_ssh_config.yaml @@ -0,0 +1,10 @@ +--- +- name: Append new commponent's name and IP into a .ssh/config.d/ file + community.general.ssh_config: + host: "{{ tn_id }}-{{ entity_name }}" + hostname: "{{ ips[access_vnet_id][0] | default('ERROR_ASSIGNING_IP', true) }}" + proxyjump: "{{ tn_id }}-tn_bastion" + remote_user: "jenkins" + ssh_config_file: "/var/lib/jenkins/.ssh/config.d/{{ tn_id }}" + state: present + register: jenkins_ssh_config diff --git a/exata_dt/code/one/cac/01_pre/tnuser_ssh_config.yaml b/exata_dt/code/one/cac/01_pre/tnuser_ssh_config.yaml new file mode 100644 index 00000000..6caa1a9c --- /dev/null +++ b/exata_dt/code/one/cac/01_pre/tnuser_ssh_config.yaml @@ -0,0 +1,16 @@ +--- +### Module ssh_config has limited options and doesnt allow to specify identity files that doesn't exist +- name: Append new component's name and IP into a .ssh/config.d/ file + ansible.builtin.blockinfile: + path: "{{ workspace }}/misc-{{ tn_id }}-ssh_config" + block: | + Host {{ tn_id }}-{{ entity_name }} + HostName "{{ ips[access_vnet_id][0] | default('ERROR_ASSIGNING_IP', true) }}" + User tnuser + IdentityFile ~/.ssh/misc-{{ tn_id }}-id_ed25519 + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + LogLevel QUIET + marker: "# {mark} {{ tn_id }}-{{ entity_name }} CONFIG" + create: true + register: tnuser_ssh_config diff --git a/exata_dt/code/one/cac/01_pre/vm_resources.yaml b/exata_dt/code/one/cac/01_pre/vm_resources.yaml new file mode 100644 index 00000000..e2454dc4 --- /dev/null +++ b/exata_dt/code/one/cac/01_pre/vm_resources.yaml @@ -0,0 +1,21 @@ +--- +- name: "Set variables for the terraform manifest according to the selected appliance" + ansible.builtin.set_fact: + one_memory: > + {{ + one_loadcore_agent_hugepages | bool | ternary( + one_loadcore_agent_memory.hugepages_appliance, + one_loadcore_agent_memory.base_appliance + ) }} + # TODO: Needed? + # template_id: >- + # {{ + # one_loadcore_agent_hugepages | bool | ternary( + # site_available_components.loadcore_agent.hugepages_appliance.template_id | default(site_available_components.loadcore_agent.template_id), + # site_available_components.loadcore_agent.base_appliance.template_id | default(site_available_components.loadcore_agent.template_id) + # ) }} + + +- name: Overwrite again with explicit values from the input file + ansible.builtin.include_vars: + file: "{{ workspace }}/{{ component_type }}/variables/input_file.yaml" diff --git a/exata_dt/code/one/iac/loadcore_agent.tf.j2 b/exata_dt/code/one/iac/loadcore_agent.tf.j2 new file mode 100644 index 00000000..d5e80596 --- /dev/null +++ b/exata_dt/code/one/iac/loadcore_agent.tf.j2 @@ -0,0 +1,48 @@ +# https://registry.terraform.io/providers/OpenNebula/opennebula/latest/docs/resources/virtual_machine +# https://docs.opennebula.io/6.8/management_and_operations/references/template.html#context-section +resource "opennebula_virtual_machine" "{{ entity_name }}" { + name = "{{ tn_id }}-{{ entity_name }}" + template_id = {{ template_id }} + cpu = {{ one_exata_dt_cpu }} + vcpu = {{ one_exata_dt_cpu }} + memory = {{ one_memory }} + + context = { + NETWORK = "YES" + NETCFG_TYPE = "interfaces" + SET_HOSTNAME = "$NAME" + USERNAME = "jenkins" + SSH_PUBLIC_KEY = "$USER[SSH_PUBLIC_KEY]" + START_SCRIPT_BASE64 = "IyEvYmluL2Jhc2gKZ3Jvd3BhcnQgL2Rldi92ZGEgMQpyZXNpemUyZnMgL2Rldi92ZGEx" + } + + # Ignore changes in the disk argument due to limitations in the OpenNebula Terraform provider (#598) + lifecycle { + ignore_changes = [disk] + } + disk { + image_id = {{ image_id }} + size = {{ one_exata_dt_disk }} + target = "vda" + driver = "qcow2" + } + +{% for network in one_exata_dt_networks %} + nic { + model = "virtio" + network_id = opennebula_virtual_network.{{ network }}.id + } +{% endfor %} + + depends_on = [ opennebula_virtual_network_address_range.tn_vxlan ] +} + +output "{{ entity_name }}-id" { + description = "OpenNebula VM ID" + value = opennebula_virtual_machine.{{ entity_name }}.id +} + +output "{{ entity_name }}-ips" { + description = "OpenNebula VM Network Assignments" + value = { for nic in opennebula_virtual_machine.{{ entity_name }}.nic[*] : nic.network_id => nic.computed_ip... } +} diff --git a/exata_dt/result_templates/fail_result.md.j2 b/exata_dt/result_templates/fail_result.md.j2 new file mode 100644 index 00000000..18d45144 --- /dev/null +++ b/exata_dt/result_templates/fail_result.md.j2 @@ -0,0 +1,5 @@ +There was an error. Detailed info: + +``` +{{ terraform_apply.stderr }} +``` \ No newline at end of file diff --git a/exata_dt/result_templates/ok_result.md.j2 b/exata_dt/result_templates/ok_result.md.j2 new file mode 100644 index 00000000..5721ec1c --- /dev/null +++ b/exata_dt/result_templates/ok_result.md.j2 @@ -0,0 +1,23 @@ +# {{ tn_id }}-{{ entity_name}} + +The component `{{ tn_id }}-{{ entity_name }}` has been succesfully created. + +

+ + +

+ +It consists of an LoadCore Agent Virtual Machine + +## Important information: + +- **OpenNebula VM ID**: `{{ id }}` +- **VM memory**: `{{ one_loadcore_agent_memory}} MiB` +- **VM VCPUs**: `{{ one_loadcore_agent_cpu }}` +- **VM internal storage**: `{{ one_loadcore_agent_disk}} MiB` +- **VM IP addresses**: +{% for ip_list in ips.values() %} +{% for ip in ip_list %} + - `{{ ip }}` +{% endfor %} +{% endfor %} \ No newline at end of file diff --git a/exata_dt/sample_input_file.yaml b/exata_dt/sample_input_file.yaml new file mode 100644 index 00000000..9245f235 --- /dev/null +++ b/exata_dt/sample_input_file.yaml @@ -0,0 +1,7 @@ +# THIS IS AN INPUT FILE EXAMPLE. Values may not be valid for your enviroment + +#This is a list of network ids. Each entry means a network interface attached to this network. +one_exata_dt_networks: + - "vnet_1" + - "vnet_2" + - "vnet_3" diff --git a/exata_dt/sample_tnlcm_descriptor_open5gs_k8s_loadcore.yaml b/exata_dt/sample_tnlcm_descriptor_open5gs_k8s_loadcore.yaml new file mode 100644 index 00000000..bf885619 --- /dev/null +++ b/exata_dt/sample_tnlcm_descriptor_open5gs_k8s_loadcore.yaml @@ -0,0 +1,66 @@ +trial_network: + tn_init: + type: "tn_init" + dependencies: [] + input: {} + vnet-internal: + type: "vnet" + name: "internal" + dependencies: + - "tn_init" + input: + one_vnet_first_ip: "10.10.10.1" + one_vnet_netmask: 24 + one_vnet_address_size: 100 + one_vnet_gw: "10.10.10.1" + oneKE-cluster: + type: "oneKE" + name: "cluster" + dependencies: + - "vnet-internal" + input: + one_oneKE_external_vnet: "tn_vxlan" + one_oneKE_internal_vnet: "vnet-internal" + # one_oneKE_cni_plugin: "canal" # Default value + # one_oneKE_metallb: true # Default value + one_oneKE_metallb_range: "10.10.10.200-10.10.10.240" + open5gs_k8s-core: + type: "open5gs_k8s" + name: "core" + dependencies: + - "oneKE-cluster" + input: + one_open5gs_k8s_target: "oneKE-cluster" + one_open5gs_k8s_amf_n2_ip: "10.10.10.200" + one_open5gs_k8s_upf_n3_ip: "10.10.10.201" + one_open5gs_k8s_ue_count: 1 + one_open5gs_k8s_tac: 1 + one_open5gs_k8s_mcc: "214" + one_open5gs_k8s_mnc: "702" + # one_open5gs_vm_msin: "0000000001" + # one_open5gs_vm_key: "465B5CE8B199B49FAA5F0A2EE238A6BC" + # one_open5gs_vm_opc: "E8ED289DEBA952E4283B54E88E6183CA" + one_open5gs_k8s_apn: "internet" + one_open5gs_k8s_s_nssai_sst: 1 + one_open5gs_k8s_s_nssai_sd: "000009" + loadcore_agent-dn: + type: "loadcore_agent" + name: "dn" + dependencies: + - "vnet-internal" + input: + one_loadcore_agent_networks: + - "tn_vxlan" + - "vnet-internal" + one_loadcore_agent_hugepages: true + loadcore_agent-gnb: + type: "loadcore_agent" + name: "gnb" + dependencies: + - "vnet-internal" + input: + one_loadcore_agent_networks: + - "tn_vxlan" + - "vnet-internal" + - "vnet-internal" + one_loadcore_agent_hugepages: true diff --git a/exata_dt/sample_tnlcm_descriptor_open5gs_vm_loadcore.yaml b/exata_dt/sample_tnlcm_descriptor_open5gs_vm_loadcore.yaml new file mode 100644 index 00000000..4774aa71 --- /dev/null +++ b/exata_dt/sample_tnlcm_descriptor_open5gs_vm_loadcore.yaml @@ -0,0 +1,76 @@ +trial_network: + tn_init: + type: "tn_init" + dependencies: [] + input: {} + vnet-n2: + type: "vnet" + name: "n2" + dependencies: + - "tn_init" + input: + one_vnet_first_ip: "10.10.10.1" + one_vnet_netmask: 24 + one_vnet_address_size: 254 + # one_vnet_gw: null # there is no gateway in this network + # one_vnet_dns: null # there is no DNS in this network + # vnet-n3: + # type: "vnet" + # name: "n3" + # dependencies: + # - "tn_init" + # input: + # one_vnet_first_ip: "10.10.11.1" + # one_vnet_netmask: 24 + # one_vnet_address_size: 254 + # # one_vnet_gw: null # there is no gateway in this network + # # one_vnet_dns: null # there is no DNS in this network + open5gs_vm-core: + type: "open5gs_vm" + name: "core" + dependencies: + - "tn_init" + - "vnet-n2" + # - "vnet-n3" + input: + one_open5gs_vm_external_vnet: "tn_vxlan" + one_open5gs_vm_internal_vnet: + - "vnet-n2" # network used for n2 and n3 (when list length=1) + #- "vnet-n3" # optional network used for n3 + one_open5gs_vm_size: "small" + # one_open5gs_vm_ue_subnet: "10.45.0.0/16" # Default value + one_open5gs_vm_amf_n2_ip: "10.10.10.200" # Default value is "10.21.12.200" + one_open5gs_vm_upf_n3_ip: "10.10.10.201" # Default value is "10.21.12.201" + # one_open5gs_vm_ue_count: 20 # Default value + # one_open5gs_vm_tac: 200 # Default value + # one_open5gs_vm_mcc: "001" # Default value + # one_open5gs_vm_mnc: "01" # Default value + # one_open5gs_vm_msin: "0000000001" # Default value + # one_open5gs_vm_key: "465B5CE8B199B49FAA5F0A2EE238A6BC" # Default value + # one_open5gs_vm_opc: "E8ED289DEBA952E4283B54E88E6183CA" # Default value + # one_open5gs_vm_apn: "internet" # Default value + # one_open5gs_vm_s_nssai_sst: 1 # Default value + # one_open5gs_vm_s_nssai_sd: "000001" # Default value + # one_open5gs_vm_use_nightly: false # Default value + one_open5gs_vm_install_webui: true # Default value is false + loadcore_agent-dn: + type: "loadcore_agent" + name: "dn" + dependencies: + - "vnet-n2" + input: + one_loadcore_agent_networks: + - "tn_vxlan" + - "vnet-n2" + one_loadcore_agent_hugepages: true + loadcore_agent-gnb: + type: "loadcore_agent" + name: "gnb" + dependencies: + - "vnet-n2" + input: + one_loadcore_agent_networks: + - "tn_vxlan" + - "vnet-n2" + - "vnet-n2" # "vnet-n3" + one_loadcore_agent_hugepages: true diff --git a/exata_dt/variables/one/private.yaml b/exata_dt/variables/one/private.yaml new file mode 100644 index 00000000..f2c5d5d2 --- /dev/null +++ b/exata_dt/variables/one/private.yaml @@ -0,0 +1,16 @@ +###################################################### +## +## Component private variables +## +## Variables required for the deployment +## and their default value. +## Some of them are modifiable through input variables +## +###################################################### + +one_exata_dt_cpu: 6 +one_exata_dt_memory: + base_appliance: 8192 +one_exata_dt_disk: 10240 +one_exata_dt_networks: + - tn_vxlan From 1045f0f87faffa856404de4e7346ee0c2c324ea6 Mon Sep 17 00:00:00 2001 From: Matteo Pagin Date: Thu, 8 May 2025 14:53:45 +0200 Subject: [PATCH 2/8] Further adapt Loadcore base to the EXata DT component --- exata_dt/.tnlcm/public.yaml | 16 +--- exata_dt/README.md | 17 ++--- .../code/one/cac/01_pre/vm_resources.yaml | 16 ---- .../{loadcore_agent.tf.j2 => exata_dt.tf.j2} | 2 +- exata_dt/result_templates/ok_result.md.j2 | 6 +- .../sample_tnlcm_descriptor_exata_dt.yaml | 37 +++++++++ ...tnlcm_descriptor_open5gs_k8s_loadcore.yaml | 66 ---------------- ..._tnlcm_descriptor_open5gs_vm_loadcore.yaml | 76 ------------------- exata_dt/variables/one/private.yaml | 5 +- 9 files changed, 52 insertions(+), 189 deletions(-) rename exata_dt/code/one/iac/{loadcore_agent.tf.j2 => exata_dt.tf.j2} (97%) create mode 100644 exata_dt/sample_tnlcm_descriptor_exata_dt.yaml delete mode 100644 exata_dt/sample_tnlcm_descriptor_open5gs_k8s_loadcore.yaml delete mode 100644 exata_dt/sample_tnlcm_descriptor_open5gs_vm_loadcore.yaml diff --git a/exata_dt/.tnlcm/public.yaml b/exata_dt/.tnlcm/public.yaml index 3104a810..dfdc3abd 100644 --- a/exata_dt/.tnlcm/public.yaml +++ b/exata_dt/.tnlcm/public.yaml @@ -13,8 +13,8 @@ #################################### metadata: maintainers: - - Álvaro Curto Merino - Matteo Pagin + - Álvaro Curto Merino short_description: EXata DT appliance for KVM long_description: | Appliance with preinstalled EXata DT as a Docker image. @@ -27,22 +27,14 @@ metadata: #################################### site_variables: exata_licensing_server_ip: IP address of the EXata licensing server in your site. - base_appliance: - # TODO: Needed? - # template_id: ID of the 'LoadCore Agent Test Tool' VM template to use in your OpenNebula environment - # image_id: ID of the 'LoadCore Agent Test Tool' VM image to use in your OpenNebula environment - hugepages_appliance: - # TODO: Needed? - # template_id: ID of the 'LoadCore Agent Test Tool + hugepages' VM template to use in your OpenNebula environment - # image_id: ID of the 'LoadCore Agent Test Tool + hugepages' VM image to use in your OpenNebula environment - - + # template_id: ID of the 'LoadCore Agent Test Tool' VM template to use in your OpenNebula environment + # image_id: ID of the 'LoadCore Agent Test Tool' VM image to use in your OpenNebula environment #################################### ## Input variables #################################### input: - one_loadcore_agent_networks: + one_exata_dt_networks: description: Ordered list of Virtual Network names the VM will be part of. The first Virtual Network is used by Jenkins to reach and configure the VM, so most cases will be fine using always the tn_vxlan type: "list[tn_vxlan or vnet]" default_value: ["tn_vxlan"] diff --git a/exata_dt/README.md b/exata_dt/README.md index b9211afb..e6023de6 100644 --- a/exata_dt/README.md +++ b/exata_dt/README.md @@ -1,16 +1,9 @@ -# loadcore_agent +# exata_dt -Deploy a VM with Keysight's LoadCore Agent ready to play. -After booting, the agent is automatically registered to the LoadCore Middleware server. +Deploy a VM with Keysight's EXata. The latter allows Experimenters to include EXata DTs as part of a Trial Network, in turn enabling the programmatic retrieval of insights and predictions about the twinned live network. -This component requires a working Loadcore Middleware exposed to the Trial Networks in the site. The Middleware IP address can be provided in the 6G-Sandbox-Sites repository branch of the site. -To set this applinace in your site, please first download either the [base appliance](https://marketplace.mobilesandbox.cloud:9443/appliance/loadcore_agent) or the one with [hugepages](https://marketplace.mobilesandbox.cloud:9443/appliance/loadcore_agent_hugepages). The hugepages appliance is heavier but provides better support for DPDK. +This component requires a working EXata licensing server exposed to the Trial Networks in the site. The licensing server IP address can be provided in the 6G-Sandbox-Sites repository branch of the site. +### Sample Trial Network using exata_dt -### Sample Trial Network using loadcore_agent with an open5gs_k8s 5G Core - -![loadcore_open5gs_k8s](https://github.com/6G-SANDBOX/6G-Library/blob/assets/loadcore/loadcore_open5gs_k8s.png) - -### Sample Trial Network using loadcore_agent with an open5gs_vm 5G Core - -![loadcore_open5gs_vm](https://github.com/6G-SANDBOX/6G-Library/blob/assets/loadcore/loadcore_open5gs_vm.png) +[sample_tnlcm_descriptor_exata_dt](sample_tnlcm_descriptor_exata_dt.yaml) \ No newline at end of file diff --git a/exata_dt/code/one/cac/01_pre/vm_resources.yaml b/exata_dt/code/one/cac/01_pre/vm_resources.yaml index e2454dc4..7cd3a2ba 100644 --- a/exata_dt/code/one/cac/01_pre/vm_resources.yaml +++ b/exata_dt/code/one/cac/01_pre/vm_resources.yaml @@ -1,20 +1,4 @@ --- -- name: "Set variables for the terraform manifest according to the selected appliance" - ansible.builtin.set_fact: - one_memory: > - {{ - one_loadcore_agent_hugepages | bool | ternary( - one_loadcore_agent_memory.hugepages_appliance, - one_loadcore_agent_memory.base_appliance - ) }} - # TODO: Needed? - # template_id: >- - # {{ - # one_loadcore_agent_hugepages | bool | ternary( - # site_available_components.loadcore_agent.hugepages_appliance.template_id | default(site_available_components.loadcore_agent.template_id), - # site_available_components.loadcore_agent.base_appliance.template_id | default(site_available_components.loadcore_agent.template_id) - # ) }} - - name: Overwrite again with explicit values from the input file ansible.builtin.include_vars: diff --git a/exata_dt/code/one/iac/loadcore_agent.tf.j2 b/exata_dt/code/one/iac/exata_dt.tf.j2 similarity index 97% rename from exata_dt/code/one/iac/loadcore_agent.tf.j2 rename to exata_dt/code/one/iac/exata_dt.tf.j2 index d5e80596..c42a149d 100644 --- a/exata_dt/code/one/iac/loadcore_agent.tf.j2 +++ b/exata_dt/code/one/iac/exata_dt.tf.j2 @@ -5,7 +5,7 @@ resource "opennebula_virtual_machine" "{{ entity_name }}" { template_id = {{ template_id }} cpu = {{ one_exata_dt_cpu }} vcpu = {{ one_exata_dt_cpu }} - memory = {{ one_memory }} + memory = {{ one_exata_dt_memory }} context = { NETWORK = "YES" diff --git a/exata_dt/result_templates/ok_result.md.j2 b/exata_dt/result_templates/ok_result.md.j2 index 5721ec1c..03de8924 100644 --- a/exata_dt/result_templates/ok_result.md.j2 +++ b/exata_dt/result_templates/ok_result.md.j2 @@ -12,9 +12,9 @@ It consists of an LoadCore Agent Virtual Machine ## Important information: - **OpenNebula VM ID**: `{{ id }}` -- **VM memory**: `{{ one_loadcore_agent_memory}} MiB` -- **VM VCPUs**: `{{ one_loadcore_agent_cpu }}` -- **VM internal storage**: `{{ one_loadcore_agent_disk}} MiB` +- **VM memory**: `{{ one_exata_dt_memory}} MiB` +- **VM VCPUs**: `{{ one_exata_dt_cpu }}` +- **VM internal storage**: `{{ one_exata_dt_disk}} MiB` - **VM IP addresses**: {% for ip_list in ips.values() %} {% for ip in ip_list %} diff --git a/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml b/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml new file mode 100644 index 00000000..f70e1275 --- /dev/null +++ b/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml @@ -0,0 +1,37 @@ +trial_network: + tn_init: + type: "tn_init" + dependencies: [] + input: {} + vnet-n2: + type: "vnet" + name: "n2" + dependencies: + - "tn_init" + input: + one_vnet_first_ip: "10.10.10.1" + one_vnet_netmask: 24 + one_vnet_address_size: 254 + # one_vnet_gw: null # there is no gateway in this network + # one_vnet_dns: null # there is no DNS in this network + # vnet-n3: + # type: "vnet" + # name: "n3" + # dependencies: + # - "tn_init" + # input: + # one_vnet_first_ip: "10.10.11.1" + # one_vnet_netmask: 24 + # one_vnet_address_size: 254 + # # one_vnet_gw: null # there is no gateway in this network + # # one_vnet_dns: null # there is no DNS in this network + # loadcore_agent-dn: + # type: "loadcore_agent" + # name: "dn" + # dependencies: + # - "vnet-n2" + # input: + # one_loadcore_agent_networks: + # - "tn_vxlan" + # - "vnet-n2" + # one_loadcore_agent_hugepages: true diff --git a/exata_dt/sample_tnlcm_descriptor_open5gs_k8s_loadcore.yaml b/exata_dt/sample_tnlcm_descriptor_open5gs_k8s_loadcore.yaml deleted file mode 100644 index bf885619..00000000 --- a/exata_dt/sample_tnlcm_descriptor_open5gs_k8s_loadcore.yaml +++ /dev/null @@ -1,66 +0,0 @@ -trial_network: - tn_init: - type: "tn_init" - dependencies: [] - input: {} - vnet-internal: - type: "vnet" - name: "internal" - dependencies: - - "tn_init" - input: - one_vnet_first_ip: "10.10.10.1" - one_vnet_netmask: 24 - one_vnet_address_size: 100 - one_vnet_gw: "10.10.10.1" - oneKE-cluster: - type: "oneKE" - name: "cluster" - dependencies: - - "vnet-internal" - input: - one_oneKE_external_vnet: "tn_vxlan" - one_oneKE_internal_vnet: "vnet-internal" - # one_oneKE_cni_plugin: "canal" # Default value - # one_oneKE_metallb: true # Default value - one_oneKE_metallb_range: "10.10.10.200-10.10.10.240" - open5gs_k8s-core: - type: "open5gs_k8s" - name: "core" - dependencies: - - "oneKE-cluster" - input: - one_open5gs_k8s_target: "oneKE-cluster" - one_open5gs_k8s_amf_n2_ip: "10.10.10.200" - one_open5gs_k8s_upf_n3_ip: "10.10.10.201" - one_open5gs_k8s_ue_count: 1 - one_open5gs_k8s_tac: 1 - one_open5gs_k8s_mcc: "214" - one_open5gs_k8s_mnc: "702" - # one_open5gs_vm_msin: "0000000001" - # one_open5gs_vm_key: "465B5CE8B199B49FAA5F0A2EE238A6BC" - # one_open5gs_vm_opc: "E8ED289DEBA952E4283B54E88E6183CA" - one_open5gs_k8s_apn: "internet" - one_open5gs_k8s_s_nssai_sst: 1 - one_open5gs_k8s_s_nssai_sd: "000009" - loadcore_agent-dn: - type: "loadcore_agent" - name: "dn" - dependencies: - - "vnet-internal" - input: - one_loadcore_agent_networks: - - "tn_vxlan" - - "vnet-internal" - one_loadcore_agent_hugepages: true - loadcore_agent-gnb: - type: "loadcore_agent" - name: "gnb" - dependencies: - - "vnet-internal" - input: - one_loadcore_agent_networks: - - "tn_vxlan" - - "vnet-internal" - - "vnet-internal" - one_loadcore_agent_hugepages: true diff --git a/exata_dt/sample_tnlcm_descriptor_open5gs_vm_loadcore.yaml b/exata_dt/sample_tnlcm_descriptor_open5gs_vm_loadcore.yaml deleted file mode 100644 index 4774aa71..00000000 --- a/exata_dt/sample_tnlcm_descriptor_open5gs_vm_loadcore.yaml +++ /dev/null @@ -1,76 +0,0 @@ -trial_network: - tn_init: - type: "tn_init" - dependencies: [] - input: {} - vnet-n2: - type: "vnet" - name: "n2" - dependencies: - - "tn_init" - input: - one_vnet_first_ip: "10.10.10.1" - one_vnet_netmask: 24 - one_vnet_address_size: 254 - # one_vnet_gw: null # there is no gateway in this network - # one_vnet_dns: null # there is no DNS in this network - # vnet-n3: - # type: "vnet" - # name: "n3" - # dependencies: - # - "tn_init" - # input: - # one_vnet_first_ip: "10.10.11.1" - # one_vnet_netmask: 24 - # one_vnet_address_size: 254 - # # one_vnet_gw: null # there is no gateway in this network - # # one_vnet_dns: null # there is no DNS in this network - open5gs_vm-core: - type: "open5gs_vm" - name: "core" - dependencies: - - "tn_init" - - "vnet-n2" - # - "vnet-n3" - input: - one_open5gs_vm_external_vnet: "tn_vxlan" - one_open5gs_vm_internal_vnet: - - "vnet-n2" # network used for n2 and n3 (when list length=1) - #- "vnet-n3" # optional network used for n3 - one_open5gs_vm_size: "small" - # one_open5gs_vm_ue_subnet: "10.45.0.0/16" # Default value - one_open5gs_vm_amf_n2_ip: "10.10.10.200" # Default value is "10.21.12.200" - one_open5gs_vm_upf_n3_ip: "10.10.10.201" # Default value is "10.21.12.201" - # one_open5gs_vm_ue_count: 20 # Default value - # one_open5gs_vm_tac: 200 # Default value - # one_open5gs_vm_mcc: "001" # Default value - # one_open5gs_vm_mnc: "01" # Default value - # one_open5gs_vm_msin: "0000000001" # Default value - # one_open5gs_vm_key: "465B5CE8B199B49FAA5F0A2EE238A6BC" # Default value - # one_open5gs_vm_opc: "E8ED289DEBA952E4283B54E88E6183CA" # Default value - # one_open5gs_vm_apn: "internet" # Default value - # one_open5gs_vm_s_nssai_sst: 1 # Default value - # one_open5gs_vm_s_nssai_sd: "000001" # Default value - # one_open5gs_vm_use_nightly: false # Default value - one_open5gs_vm_install_webui: true # Default value is false - loadcore_agent-dn: - type: "loadcore_agent" - name: "dn" - dependencies: - - "vnet-n2" - input: - one_loadcore_agent_networks: - - "tn_vxlan" - - "vnet-n2" - one_loadcore_agent_hugepages: true - loadcore_agent-gnb: - type: "loadcore_agent" - name: "gnb" - dependencies: - - "vnet-n2" - input: - one_loadcore_agent_networks: - - "tn_vxlan" - - "vnet-n2" - - "vnet-n2" # "vnet-n3" - one_loadcore_agent_hugepages: true diff --git a/exata_dt/variables/one/private.yaml b/exata_dt/variables/one/private.yaml index f2c5d5d2..5416980c 100644 --- a/exata_dt/variables/one/private.yaml +++ b/exata_dt/variables/one/private.yaml @@ -9,8 +9,7 @@ ###################################################### one_exata_dt_cpu: 6 -one_exata_dt_memory: - base_appliance: 8192 -one_exata_dt_disk: 10240 +one_exata_dt_memory: 8192 +one_exata_dt_disk: 42950 one_exata_dt_networks: - tn_vxlan From 53fd3cbb113afb304bc77af87eb06d3699f4589e Mon Sep 17 00:00:00 2001 From: Matteo Pagin Date: Thu, 8 May 2025 15:11:17 +0200 Subject: [PATCH 3/8] Set image and template IDs --- exata_dt/.tnlcm/public.yaml | 2 -- exata_dt/code/one/iac/exata_dt.tf.j2 | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/exata_dt/.tnlcm/public.yaml b/exata_dt/.tnlcm/public.yaml index dfdc3abd..29f5d402 100644 --- a/exata_dt/.tnlcm/public.yaml +++ b/exata_dt/.tnlcm/public.yaml @@ -27,8 +27,6 @@ metadata: #################################### site_variables: exata_licensing_server_ip: IP address of the EXata licensing server in your site. - # template_id: ID of the 'LoadCore Agent Test Tool' VM template to use in your OpenNebula environment - # image_id: ID of the 'LoadCore Agent Test Tool' VM image to use in your OpenNebula environment #################################### ## Input variables diff --git a/exata_dt/code/one/iac/exata_dt.tf.j2 b/exata_dt/code/one/iac/exata_dt.tf.j2 index c42a149d..cfb50974 100644 --- a/exata_dt/code/one/iac/exata_dt.tf.j2 +++ b/exata_dt/code/one/iac/exata_dt.tf.j2 @@ -2,7 +2,7 @@ # https://docs.opennebula.io/6.8/management_and_operations/references/template.html#context-section resource "opennebula_virtual_machine" "{{ entity_name }}" { name = "{{ tn_id }}-{{ entity_name }}" - template_id = {{ template_id }} + template_id = {{ site_available_components.EXata.template_id }} cpu = {{ one_exata_dt_cpu }} vcpu = {{ one_exata_dt_cpu }} memory = {{ one_exata_dt_memory }} @@ -21,7 +21,7 @@ resource "opennebula_virtual_machine" "{{ entity_name }}" { ignore_changes = [disk] } disk { - image_id = {{ image_id }} + image_id = {{ site_available_components.EXata.image_id }} size = {{ one_exata_dt_disk }} target = "vda" driver = "qcow2" From 7b04635e8bb9eba0e02e7c6871a0d1d3528c3127 Mon Sep 17 00:00:00 2001 From: Matteo Pagin Date: Fri, 9 May 2025 13:05:38 +0200 Subject: [PATCH 4/8] Configure tnuser user, whitelist licensing server --- exata_dt/.tnlcm/public.yaml | 8 +++- exata_dt/changelog.md | 2 +- exata_dt/code/component_playbook.yaml | 39 ++++++------------- exata_dt/code/one/iac/exata_dt.tf.j2 | 1 - .../sample_tnlcm_descriptor_exata_dt.yaml | 2 +- 5 files changed, 20 insertions(+), 32 deletions(-) diff --git a/exata_dt/.tnlcm/public.yaml b/exata_dt/.tnlcm/public.yaml index 29f5d402..8ad170ca 100644 --- a/exata_dt/.tnlcm/public.yaml +++ b/exata_dt/.tnlcm/public.yaml @@ -15,9 +15,13 @@ metadata: maintainers: - Matteo Pagin - Álvaro Curto Merino - short_description: EXata DT appliance for KVM + short_description: EXata Digital Twin appliance for KVM long_description: | - Appliance with preinstalled EXata DT as a Docker image. + Appliance featuring Keysight's EXata. The latter allows Experimenters to include EXata Digital Twins as part of a Trial Network, in turn enabling the programmatic retrieval of insights and predictions about the twinned live network. + This component requires a working EXata licensing server exposed to the Trial Networks in the site. The licensing server IP address can be provided in the 6G-Sandbox-Sites repository branch of the site. + The component has been implemented as a Docker Compose stack comprising two services: one hosting an instance of EXata, and the other hosting an instance of the official MariaDB service. + The interaction of Experimenters and/or the reminder of the Trial Network with the DT component takes place via northbound APIs exposed by a custom Python FastAPI webserver. The latter accepts HTTP requests and translates them into commands to the EXata and MariaDB Docker services. + hypervisors: ["one"] appliances: ["https://marketplace.mobilesandbox.cloud:9443/appliance/EXata"] diff --git a/exata_dt/changelog.md b/exata_dt/changelog.md index 7a5af9a9..d6e5a4d6 100644 --- a/exata_dt/changelog.md +++ b/exata_dt/changelog.md @@ -1,6 +1,6 @@ # Changelog -## v0.5.0 +## v0.6.0 ### Added - Initial release of `exata_dt` component to the 6G-Library. diff --git a/exata_dt/code/component_playbook.yaml b/exata_dt/code/component_playbook.yaml index 1f0f1691..c74c5467 100644 --- a/exata_dt/code/component_playbook.yaml +++ b/exata_dt/code/component_playbook.yaml @@ -62,6 +62,7 @@ ansible_host: "{{ bastion_ip }}" ansible_user: "jenkins" + # TODO: Copy if not there already - name: Add new VM to SSH config file in the Jenkins-master for debugging purposes ansible.builtin.include_tasks: "{{ workspace }}/EXata/code/{{ site_hypervisor }}/cac/01_pre/jenkins_ssh_config.yaml" @@ -90,14 +91,7 @@ - "{{ hostvars['localhost'].get('site_admin_ssh_public_key', '') }}" when: item != '' - #TODO: Customize this? - - name: Create new user for experimenter access - become: true - ansible.builtin.user: - name: tnuser - shell: /bin/bash - groups: sudo - password: '' + # User "tnuser" is already created as part of the appliance creation steps - name: Set TN ssh key as authorized in new user become: true ansible.posix.authorized_key: @@ -107,15 +101,6 @@ loop: - "{{ hostvars['localhost'].get('tn_ssh_public_key', '') }}" - #TODO: Remove this? - # - name: Remove user ixia - # ansible.builtin.user: - # name: ixia - # state: absent - # remove: true - # become: true - # when: not hostvars['localhost'].get('one_loadcore_agent_ixia', false) - # - name: Execute bash script to register the Agent with the Middleware # ansible.builtin.shell: | # set -o pipefail @@ -127,16 +112,16 @@ # become: true # changed_when: false -#TODO: Customize this to allow access to the licensing server -# - name: "STAGE 4: Access tn_bastion to set firewall exceptions" -# hosts: bastion -# gather_facts: false -# tasks: -# - name: Write firewall exception for the Loadcore Middleware -# ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/nftables_add.yaml" -# vars: -# fw_exceptions: -# - "{{ hostvars.localhost.site_available_components.loadcore_agent.loadcore_middleware_ip | default('') }}" +# Whitelist the EXata licensing server in the bastion +- name: "STAGE 4: Access tn_bastion to set firewall exceptions" + hosts: bastion + gather_facts: false + tasks: + - name: Write firewall exception for the EXata licensing server + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/nftables_add.yaml" + vars: + fw_exceptions: + - "{{ hostvars.localhost.site_available_components.exata_dt.exata_licensing_server_ip | default('') }}" - name: "STAGE 5: Publish execution results" diff --git a/exata_dt/code/one/iac/exata_dt.tf.j2 b/exata_dt/code/one/iac/exata_dt.tf.j2 index cfb50974..84f39fad 100644 --- a/exata_dt/code/one/iac/exata_dt.tf.j2 +++ b/exata_dt/code/one/iac/exata_dt.tf.j2 @@ -13,7 +13,6 @@ resource "opennebula_virtual_machine" "{{ entity_name }}" { SET_HOSTNAME = "$NAME" USERNAME = "jenkins" SSH_PUBLIC_KEY = "$USER[SSH_PUBLIC_KEY]" - START_SCRIPT_BASE64 = "IyEvYmluL2Jhc2gKZ3Jvd3BhcnQgL2Rldi92ZGEgMQpyZXNpemUyZnMgL2Rldi92ZGEx" } # Ignore changes in the disk argument due to limitations in the OpenNebula Terraform provider (#598) diff --git a/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml b/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml index f70e1275..ff6040aa 100644 --- a/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml +++ b/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml @@ -34,4 +34,4 @@ trial_network: # one_loadcore_agent_networks: # - "tn_vxlan" # - "vnet-n2" - # one_loadcore_agent_hugepages: true + From ef05b47c88cbefb50cc9ed442f03b84328e2b13d Mon Sep 17 00:00:00 2001 From: Matteo Pagin Date: Fri, 9 May 2025 14:48:48 +0200 Subject: [PATCH 5/8] Update ok result --- exata_dt/code/component_playbook.yaml | 9 ++++----- exata_dt/result_templates/ok_result.md.j2 | 7 +------ 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/exata_dt/code/component_playbook.yaml b/exata_dt/code/component_playbook.yaml index c74c5467..aea9a554 100644 --- a/exata_dt/code/component_playbook.yaml +++ b/exata_dt/code/component_playbook.yaml @@ -51,7 +51,7 @@ - name: Add new VM to Ansible Inventory ansible.builtin.add_host: - hostname: "EXata" + hostname: "exata_dt" ansible_host: "{{ ips[access_vnet_id][0] }}" ansible_ssh_common_args: "-J jenkins@{{ bastion_ip }}" ansible_user: "jenkins" @@ -62,16 +62,15 @@ ansible_host: "{{ bastion_ip }}" ansible_user: "jenkins" - # TODO: Copy if not there already - name: Add new VM to SSH config file in the Jenkins-master for debugging purposes - ansible.builtin.include_tasks: "{{ workspace }}/EXata/code/{{ site_hypervisor }}/cac/01_pre/jenkins_ssh_config.yaml" + ansible.builtin.include_tasks: "{{ workspace }}/exata_dt/code/{{ site_hypervisor }}/cac/01_pre/jenkins_ssh_config.yaml" - name: Add new VM to an SSH config file ment to be usable by the experimenter - ansible.builtin.include_tasks: "{{ workspace }}/EXata/code/{{ site_hypervisor }}/cac/01_pre/tnuser_ssh_config.yaml" + ansible.builtin.include_tasks: "{{ workspace }}/exata_dt/code/{{ site_hypervisor }}/cac/01_pre/tnuser_ssh_config.yaml" - name: "STAGE 3: Apply CAC to prepare the component" - hosts: "EXata" + hosts: "exata_dt" gather_facts: false tasks: - name: Wait for system to become reachable diff --git a/exata_dt/result_templates/ok_result.md.j2 b/exata_dt/result_templates/ok_result.md.j2 index 03de8924..beb4ab2e 100644 --- a/exata_dt/result_templates/ok_result.md.j2 +++ b/exata_dt/result_templates/ok_result.md.j2 @@ -2,12 +2,7 @@ The component `{{ tn_id }}-{{ entity_name }}` has been succesfully created. -

- - -

- -It consists of an LoadCore Agent Virtual Machine +It consists of an EXata VM, which allows Experimenters to include EXata DTs as part of a Trial Network, in turn enabling the programmatic retrieval of insights and predictions about the twinned live network. ## Important information: From 90b745532e368afd6b8d8f8382b148a12643716c Mon Sep 17 00:00:00 2001 From: Matteo Pagin Date: Tue, 3 Jun 2025 09:35:29 +0200 Subject: [PATCH 6/8] Add palybook step for dumping the licensing server IP into EXata license file --- exata_dt/code/component_playbook.yaml | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/exata_dt/code/component_playbook.yaml b/exata_dt/code/component_playbook.yaml index aea9a554..a6c17c84 100644 --- a/exata_dt/code/component_playbook.yaml +++ b/exata_dt/code/component_playbook.yaml @@ -100,16 +100,23 @@ loop: - "{{ hostvars['localhost'].get('tn_ssh_public_key', '') }}" - # - name: Execute bash script to register the Agent with the Middleware - # ansible.builtin.shell: | - # set -o pipefail - # printf "{{ middleware_ip }}\neth0\ny\nn" | /opt/5gc-test-engine/agent-setup.sh - # args: - # executable: /bin/bash - # vars: - # middleware_ip: "{{ hostvars.localhost.site_available_components.loadcore_agent.loadcore_middleware_ip | default('') }}" - # become: true - # changed_when: false + # The IP address of the EXata licensing server must be specified in the EXata license file. + # This step fetches the IP address of the EXata licensing server from the site variables, and dumps it + # into the host VM. Then, the latter is used by the component Docker entrypoint to overwrite the default + # EXata license file with the one that includes the IP address of the EXata licensing server. + - name: Write the EXata license file taking as input the IP addres of the EXata licensing server + ansible.builtin.shell: | + set -o pipefail + mkdir -p /home/EXata/webserver/exata-webserver-app/license + touch /home/EXata/webserver/exata-webserver-app/license/LicenseFile.lic + printf "SERVER {{ licensing_server_ip }} ANY\nVENDOR scalable\nUSE_SERVER" > /home/EXata/webserver/exata-webserver-app/license/LicenseFile.lic + args: + executable: /bin/bash + vars: + # Retrieve the EXata licensing server IP address for the platform the component is being deployed on + licensing_server_ip: "{{ hostvars.localhost.site_available_components.exata_dt.exata_licensing_server_ip | default('') }}" + become: true + changed_when: false # Whitelist the EXata licensing server in the bastion - name: "STAGE 4: Access tn_bastion to set firewall exceptions" From 2f6c5cb9252a964279c7460a8458790767a41e32 Mon Sep 17 00:00:00 2001 From: Matteo Pagin Date: Fri, 6 Jun 2025 11:36:57 +0200 Subject: [PATCH 7/8] Update sample descriptor --- exata_dt/sample_tnlcm_descriptor_exata_dt.yaml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml b/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml index ff6040aa..4aa34672 100644 --- a/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml +++ b/exata_dt/sample_tnlcm_descriptor_exata_dt.yaml @@ -25,13 +25,9 @@ trial_network: # one_vnet_address_size: 254 # # one_vnet_gw: null # there is no gateway in this network # # one_vnet_dns: null # there is no DNS in this network - # loadcore_agent-dn: - # type: "loadcore_agent" - # name: "dn" - # dependencies: - # - "vnet-n2" - # input: - # one_loadcore_agent_networks: - # - "tn_vxlan" - # - "vnet-n2" - + exata_dt: + type: "exata_dt" + name: "exata_dt" + dependencies: + - "tn_init" + - "vnet-n2" \ No newline at end of file From 0ad43d39886bf063897834b430361dc4a288ba18 Mon Sep 17 00:00:00 2001 From: Matteo Pagin Date: Wed, 11 Jun 2025 10:29:52 +0200 Subject: [PATCH 8/8] Correctly set image_id and template_id vars --- exata_dt/.tnlcm/public.yaml | 2 ++ exata_dt/code/one/iac/exata_dt.tf.j2 | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/exata_dt/.tnlcm/public.yaml b/exata_dt/.tnlcm/public.yaml index 8ad170ca..10c450cb 100644 --- a/exata_dt/.tnlcm/public.yaml +++ b/exata_dt/.tnlcm/public.yaml @@ -31,6 +31,8 @@ metadata: #################################### site_variables: exata_licensing_server_ip: IP address of the EXata licensing server in your site. + template_id: ID of the Appliance to use in the OpenNebula environment + image_id: ID of the Appliance to use in the OpenNebula environment #################################### ## Input variables diff --git a/exata_dt/code/one/iac/exata_dt.tf.j2 b/exata_dt/code/one/iac/exata_dt.tf.j2 index 84f39fad..0f393b02 100644 --- a/exata_dt/code/one/iac/exata_dt.tf.j2 +++ b/exata_dt/code/one/iac/exata_dt.tf.j2 @@ -2,7 +2,7 @@ # https://docs.opennebula.io/6.8/management_and_operations/references/template.html#context-section resource "opennebula_virtual_machine" "{{ entity_name }}" { name = "{{ tn_id }}-{{ entity_name }}" - template_id = {{ site_available_components.EXata.template_id }} + template_id = {{ site_available_components.exata_dt.template_id }} cpu = {{ one_exata_dt_cpu }} vcpu = {{ one_exata_dt_cpu }} memory = {{ one_exata_dt_memory }} @@ -20,7 +20,7 @@ resource "opennebula_virtual_machine" "{{ entity_name }}" { ignore_changes = [disk] } disk { - image_id = {{ site_available_components.EXata.image_id }} + image_id = {{ site_available_components.exata_dt.image_id }} size = {{ one_exata_dt_disk }} target = "vda" driver = "qcow2"