diff --git a/.global/cac/terraform_apply.yaml b/.global/cac/terraform_apply.yaml index 9d14bb4d..c448af9d 100644 --- a/.global/cac/terraform_apply.yaml +++ b/.global/cac/terraform_apply.yaml @@ -56,6 +56,18 @@ register: tnlcm_post ignore_errors: true + - name: Send FAIL markdown response to S3 + amazon.aws.s3_object: + endpoint_url: "{{ site_s3_server.endpoint }}" + mode: put + access_key: "{{ lookup('ansible.builtin.env', 'AWS_ACCESS_KEY_ID') }}" + secret_key: "{{ lookup('ansible.builtin.env', 'AWS_SECRET_ACCESS_KEY') }}" + bucket: "{{ site_s3_server.bucket }}" + object: "{{ tn_id }}/fail_result-{{ entity_name }}.md" + src: "{{ workspace }}/{{ component_type }}/code/fail_result-{{ entity_name }}.md" + encrypt: false + validate_certs: false + - name: Stop playbook execution ansible.builtin.fail: msg: "The Execution of 'terraform apply' failed. Check generated markdown file for more debugging information." diff --git a/.global/pac/TN_DEPLOY.groovy b/.global/pac/TN_DEPLOY.groovy index 8439fddb..ddabe734 100644 --- a/.global/pac/TN_DEPLOY.groovy +++ b/.global/pac/TN_DEPLOY.groovy @@ -9,13 +9,13 @@ pipeline { } parameters { - string(name: 'TN_ID', defaultValue: '', description: 'Trial Network Identifier. MANDATORY') + string(name: 'TN_ID', defaultValue: '', description: 'Trial Network Identifier. Valid characters are A-Z, a-z, 0-9 and underscore _. MANDATORY') string(name: 'COMPONENT_TYPE', defaultValue: '', description: '6G Library Component type. MANDATORY') - string(name: 'CUSTOM_NAME', defaultValue: '', description: 'Custom name for the component inside the Trian Network. MANDATORY except for tn_init (including tn_vxlan and tn_bastion)') + string(name: 'CUSTOM_NAME', defaultValue: '', description: 'Custom name for the component inside the Trial Network. Valid characters are A-Z, a-z, 0-9 and underscore _. MANDATORY except for tn_init (including tn_vxlan and tn_bastion)') string(name: 'DEPLOYMENT_SITE', defaultValue: '', description: 'Site where the deployment is being made. E.g. uma, athens, fokus, oulu... MANDATORY') string(name: 'TNLCM_CALLBACK', defaultValue: 'http://tnlcm-ip:5000/tnlcm/callback/', description: 'URL of the TNLCM to notify the results. MANDATORY') string(name: 'LIBRARY_URL', defaultValue: 'https://github.com/6G-SANDBOX/6G-Library.git', description: '6G-Library repository HTTPS URL. Leave it as-is unless you want to test your own fork') - string(name: 'LIBRARY_BRANCH', defaultValue: 'refs/heads/main', description: 'LIBRARY_URL checkout to use. Valid inputs can be refs/heads/, refs/tags/ or . Leave it as-is unless you want to test alternative releases/branches/commits.') + string(name: 'LIBRARY_BRANCH', defaultValue: 'v0.2.1', description: 'LIBRARY_URL checkout to use. Valid inputs can be refs/heads/, refs/tags/ or . Leave it as-is unless you want to test alternative releases/branches/commits.') string(name: 'SITES_URL', defaultValue: 'https://github.com/6G-SANDBOX/6G-Sandbox-Sites.git', description: '6G-Library-Sites repository HTTP URL. Leave it as-is unless you want to test your own fork') string(name: 'SITES_BRANCH', defaultValue: 'refs/heads/main', description: 'SITES_URL checkout to use. Valid inputs can be refs/heads/, refs/tags/ or . Leave it as-is unless you want to test alternative releases/branches/commits.') booleanParam(name: 'DEBUG', defaultValue: false, description: 'Enable DEBUG. Files will not be purged after the pipeline execution') diff --git a/.global/pac/TN_DESTROY.groovy b/.global/pac/TN_DESTROY.groovy index 68759275..4dd74932 100644 --- a/.global/pac/TN_DESTROY.groovy +++ b/.global/pac/TN_DESTROY.groovy @@ -10,10 +10,10 @@ pipeline { parameters { string(name: 'TN_ID', defaultValue: '', description: 'Trial Network Identifier. MANDATORY') - choice(name: 'DEPLOYMENT_SITE', choices: ['uma', 'athens', 'fokus', 'oulu'], description: 'Site where the deployment was made. Choose between uma, athens, fokus or oulu. MANDATORY') + string(name: 'DEPLOYMENT_SITE', defaultValue: '', description: 'Site where the deployment is being made. E.g. uma, athens, fokus, oulu... MANDATORY') string(name: 'TNLCM_CALLBACK', defaultValue: 'http://tnlcm-ip:5000/tnlcm/callback/', description: 'URL of the TNLCM to notify the results. MANDATORY') string(name: 'LIBRARY_URL', defaultValue: 'https://github.com/6G-SANDBOX/6G-Library.git', description: '6G-Library repository HTTPS URL. Leave it as-is unless you want to test your own fork') - string(name: 'LIBRARY_BRANCH', defaultValue: 'refs/heads/main', description: 'LIBRARY_URL checkout to use. Valid inputs can be refs/heads/, refs/tags/ or . Default value can purge TNs from previous 6G-Library version.') + string(name: 'LIBRARY_BRANCH', defaultValue: 'v0.2.1', description: 'LIBRARY_URL checkout to use. Valid inputs can be refs/heads/, refs/tags/ or . Default value can purge TNs from previous 6G-Library version.') string(name: 'SITES_URL', defaultValue: 'https://github.com/6G-SANDBOX/6G-Sandbox-Sites.git', description: '6G-Library-Sites repository HTTP URL. Leave it as-is unless you want to test your own fork') string(name: 'SITES_BRANCH', defaultValue: 'refs/heads/main', description: 'SITES_URL checkout to use. Valid inputs can be refs/heads/, refs/tags/ or . Default value can purge TNs from previous 6G-Library version.') booleanParam(name: 'DEBUG', defaultValue: false, description: 'Enable DEBUG. Files will not be purged after the pipeline execution') @@ -91,4 +91,4 @@ pipeline { } } } -} \ No newline at end of file +} diff --git a/changelog.md b/changelog.md index 4e08f1d1..e4d93ae1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## [v0.2.1] + +### Changed + +- Failed terraform applies correctly post a markdown to the MinIO informing about the error. +- Corrected texts in the pipeline parameter descriptions +- New nokia_radio_uma component + ## [v0.2.0] - 2024-06-06 ### Added diff --git a/nokia_radio_uma/.tnlcm/public.yaml b/nokia_radio_uma/.tnlcm/public.yaml new file mode 100644 index 00000000..a7c3512e --- /dev/null +++ b/nokia_radio_uma/.tnlcm/public.yaml @@ -0,0 +1,75 @@ +###################################################### +## +## Component public variables +## +## Variables accesible to the experimenter. +## +## They are contained inside 3 global variables +## with all required info: +## +## 1. metadata: General information like mantainers, +## component dependencies and allowed platforms +## +## 2. input: Customizable variables for each +## deployment to be filled by the experimenter +## or the TNLCM +## +## 3. output: Values sent to the TNLCM callback to +## keep track of the TN deployments +## +###################################################### + + +#################################### +## Component metadata +#################################### +metadata: + maintainers: + - Jesus Macias Portela + - Ana Isabel Lara García + - Álvaro Curto Merino + short_description: Enables the capability of using Nokia Radio in a Trial Network. + long_description: | + This component enables the integration of Nokia Airscale physical equipment located at UMA with a 5G core deployed in the Trial Network. + It is done by enabling the necessary routing path through the use of the element called ‘Route Manager’ (already deployed in the site). + The configuration exposed by this component should be synchronized with the 5G core and the UE to be used in conjunction: + - 'mcc': "214" + - 'mnc': "702" + - 'apn': "internet" + - 'tac': "0001" + - 's_nssai_sst': "1" + - 's_nssai_sd': "000009" + - 'amf_ip': "10.10.12.200" + - 'upf_ip': "10.10.12.201" + NOTE: Currently this component is only available in the site "uma". + hypervisors: [one] + +#################################### +## Component input +#################################### + +input: + one_nokia_main_ip: + description: Address of Nokia Airscale. + type: str + required_when: false + one_nokia_reservation_time: + description: Time in minutes for the Nokia Airsale reservation + type: int + default_value: 60 + required_when: true + one_nokia_route_manager_ip: + description: Address of the route manager that will enable routing between Nokia Airscale and 5G Core. + type: str + default_value: "10.11.28.134" + required_when: true + one_nokia_oneKE: + description: Name of the oneKE cluster to route Nokia traffic. + type: "oneKE" + required_when: true + +#################################### +## Component output +#################################### +output: + nokia_metadata_dict: Dictionary with multiple parameters used in the component bootstrap \ No newline at end of file diff --git a/nokia_radio_uma/README.md b/nokia_radio_uma/README.md new file mode 100644 index 00000000..d250ceee --- /dev/null +++ b/nokia_radio_uma/README.md @@ -0,0 +1,5 @@ +# NOKIA RADIO UMA + +Component that enables the capability of access physical Nokia Radio in a Trial Network + +NOTE: Currently this component is only available in the site "uma" \ No newline at end of file diff --git a/nokia_radio_uma/changelog.md b/nokia_radio_uma/changelog.md new file mode 100644 index 00000000..a4eb64ca --- /dev/null +++ b/nokia_radio_uma/changelog.md @@ -0,0 +1,8 @@ +# Changelog + +## [v0.2.0] - 2024-06-06 + +### Added + +- New component + diff --git a/nokia_radio_uma/code/all/cac/enable_routing_bastion.yaml b/nokia_radio_uma/code/all/cac/enable_routing_bastion.yaml new file mode 100644 index 00000000..edeb65e0 --- /dev/null +++ b/nokia_radio_uma/code/all/cac/enable_routing_bastion.yaml @@ -0,0 +1,6 @@ +- name: Add routes in bastion + ansible.builtin.shell: "ip route add {{ item }}" + with_items: + - "{{ one_nokia_routable_network }} via {{ hostvars['localhost']['node_ips'].vnf_0 }}" + - "{{ one_nokia_main_ip }} via {{ one_nokia_route_manager_ip }}" + become: yes \ No newline at end of file diff --git a/nokia_radio_uma/code/all/cac/enable_routing_manager.yaml b/nokia_radio_uma/code/all/cac/enable_routing_manager.yaml new file mode 100644 index 00000000..c19e2870 --- /dev/null +++ b/nokia_radio_uma/code/all/cac/enable_routing_manager.yaml @@ -0,0 +1,7 @@ +- name: Execute manage_route script in Router Manager + ansible.builtin.shell: + args: + executable: /bin/bash + cmd: "nohup /root/route-manager.sh {{ tn_id }} {{ one_nokia_routable_network }} {{ hostvars['localhost']['bastion_ip'] }} {{ one_nokia_reservation_time }} > /tmp/route-manager.log 2>&1 &" + async: 0 + poll: 0 \ No newline at end of file diff --git a/nokia_radio_uma/code/component_playbook.yaml b/nokia_radio_uma/code/component_playbook.yaml new file mode 100644 index 00000000..7d82ee27 --- /dev/null +++ b/nokia_radio_uma/code/component_playbook.yaml @@ -0,0 +1,86 @@ +--- +- name: "STAGE 1: Prepare to access a previous target 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: 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] }}" + node_ips: "{{ (terraform_outputs.stdout | from_json)[one_nokia_oneKE + '-node_ips'] }}" + + - name: Add Route Manager to Ansible Inventory + ansible.builtin.add_host: + hostname: "routemanager" + ansible_host: "{{ one_nokia_route_manager_ip }}" + ansible_user: "root" + ansible_ssh_private_key_file: "/var/lib/jenkins/.ssh/id_ed25519" + + - name: Add the bastion to Ansible Inventory + ansible.builtin.add_host: + hostname: "bastion" + ansible_host: "{{ bastion_ip }}" + ansible_user: "jenkins" + + +- name: "STAGE 2: Apply IaC to deploy the component - STEP 1" + hosts: "routemanager" + gather_facts: false + tasks: + - name: Load enviromental variables from different sources inside the component + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/load_variables.yaml" + + - name: Enable routing path in Route Manager + ansible.builtin.include_tasks: "{{ workspace }}/{{ component_type }}/code/all/cac/enable_routing_manager.yaml" + +- name: "STAGE 2: Apply IaC to deploy the component - STEP 2" + hosts: "bastion" + gather_facts: false + tasks: + - name: Load enviromental variables from different sources inside the component + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/load_variables.yaml" + + - name: Enable routing path in Bastion + ansible.builtin.include_tasks: "{{ workspace }}/{{ component_type }}/code/all/cac/enable_routing_bastion.yaml" + + +- name: "STAGE 3: Publish execution results" + hosts: localhost + gather_facts: false + connection: local + tasks: + - name: Define Nokia metadata dictionary + ansible.builtin.set_fact: + nokia_metadata_dict: >- + { + 'one_nokia_reservation_time': '{{ one_nokia_reservation_time }}', + 'one_nokia_route_manager_ip': '{{ one_nokia_route_manager_ip }}' + } + + - name: Publish Nokia metadata as terraform outputs" + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/custom_tf_outputs.yaml" + vars: + custom_outputs: + - key: "{{ entity_name }}-metadata" + value: "{{ nokia_metadata_dict }}" + + - name: Publish execution results to TNLCM + ansible.builtin.include_tasks: "{{ workspace }}/.global/cac/publish_ok_results.yaml" + vars: + output: + open5gs_metadata_dict: "{{ nokia_metadata_dict | b64encode }}" diff --git a/nokia_radio_uma/result_templates/fail_result.md.j2 b/nokia_radio_uma/result_templates/fail_result.md.j2 new file mode 100644 index 00000000..18d45144 --- /dev/null +++ b/nokia_radio_uma/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/nokia_radio_uma/result_templates/ok_result.md.j2 b/nokia_radio_uma/result_templates/ok_result.md.j2 new file mode 100644 index 00000000..fbbc0de2 --- /dev/null +++ b/nokia_radio_uma/result_templates/ok_result.md.j2 @@ -0,0 +1,18 @@ +# NOKIA RADIO UMA + +NOKIA RADIO UMA ( {{ one_nokia_main_ip }} ) component has been successfully addded to the Trial Network `{{ tn_id }}`. + +Important information: + +This component will be available for `{{ one_nokia_reservation_time }}` minutes from now. The Route Manager used for enabling the routing path is `{{ one_nokia_route_manager_ip }}`. + + +### Relevant information about Radio Configuration: + +* PLMN ID (MCC): {{ one_nokia_mcc }} +* PLMN ID (MNC): {{ one_nokia_mnc }} +* TAC: {{ one_nokia_tac }} +* S-NSSAI (SST): {{ one_nokia_s_nssai_sst }} +* S-NSSAI (SD): {{ one_nokia_s_nssai_sd }} +* AMF_IP: {{ one_nokia_amf_ip }} +* UPF_IP: {{ one_nokia_upf_ip }} diff --git a/nokia_radio_uma/sample_input_file.yaml b/nokia_radio_uma/sample_input_file.yaml new file mode 100644 index 00000000..d5bdddd1 --- /dev/null +++ b/nokia_radio_uma/sample_input_file.yaml @@ -0,0 +1,6 @@ +# THIS IS AN INPUT FILE EXAMPLE. Values may not be valid for your enviroment + +one_nokias_oneKE: "oneKE-main" +one_nokia_main_ip: "your_nokia_ip" +one_nokia_route_manager_ip: "10.19.98.000" +one_nokia_reservation_time: "60" diff --git a/nokia_radio_uma/variables/one/private.yaml b/nokia_radio_uma/variables/one/private.yaml new file mode 100644 index 00000000..af441c47 --- /dev/null +++ b/nokia_radio_uma/variables/one/private.yaml @@ -0,0 +1,18 @@ +###################################################### +## +## Component private variables +## +## Variables required for the deployment +## and their default value. +## Some of them are modifiable through input variables +## +###################################################### + +one_nokia_routable_network: "10.10.12.0/24" +one_nokia_mcc: "214" +one_nokia_mnc: "702" +one_nokia_tac: "0001" +one_nokia_s_nssai_sst: "1" +one_nokia_s_nssai_sd: "000009" +one_nokia_amf_ip: "10.10.12.200" +one_nokia_upf_ip: "10.10.12.201"