DenisGNoonan | 9043807 | 2024-08-14 12:38:47 +0100 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | |
| 3 | ################################################################################ |
| 4 | # Copyright (C) 2024 OpenInfra Foundation Europe. All rights reserved. # |
| 5 | # # |
| 6 | # Licensed under the Apache License, Version 2.0 (the "License"); # |
| 7 | # you may not use this file except in compliance with the License. # |
| 8 | # You may obtain a copy of the License at # |
| 9 | # # |
| 10 | # http://www.apache.org/licenses/LICENSE-2.0 # |
| 11 | # # |
| 12 | # Unless required by applicable law or agreed to in writing, software # |
| 13 | # distributed under the License is distributed on an "AS IS" BASIS, # |
| 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # |
| 15 | # See the License for the specific language governing permissions and # |
| 16 | # limitations under the License. # |
| 17 | ################################################################################ |
| 18 | |
| 19 | function get_published_apis_payload() { |
| 20 | |
| 21 | IFS=$'\n' read -d '' -r -a ipv4Ar <<< ${interfaceDescIpv4Addr} |
| 22 | IFS=$'\n' read -d '' -r -a portAr <<< ${interfaceDescPort} |
| 23 | IFS=$'\n' read -d '' -r -a securityMethodsAr <<< ${interfaceDescSecurityMethods} |
| 24 | |
| 25 | interfaceDescArLen=${#ipv4Ar[@]} |
| 26 | >&2 echo "interfaceDescArLen: ${interfaceDescArLen}" |
| 27 | |
| 28 | # Iterate over the array using array indexing |
| 29 | interfaceDescBlock="" |
| 30 | for (( i=0; i<interfaceDescArLen; i++ )); do |
| 31 | >&2 echo "ipv4Ar[$i]: ${ipv4Ar[$i]}" |
| 32 | |
| 33 | interfaceDescItem=" |
| 34 | { |
| 35 | \"ipv4Addr\": \"${ipv4Ar[$i]}\", |
| 36 | \"port\": ${portAr[$i]}, |
| 37 | \"securityMethods\": ${securityMethodsAr[$i]} |
| 38 | }" |
| 39 | interfaceDescBlock="${interfaceDescBlock}${interfaceDescItem}, " |
| 40 | >&2 echo "interfaceDescItem: ${interfaceDescItem}" |
| 41 | done |
| 42 | |
| 43 | # Trim the trailing space and comma |
| 44 | interfaceDescBlock="${interfaceDescBlock%??}" |
| 45 | |
| 46 | >&2 echo "interfaceDescBlock: ${interfaceDescBlock}" |
| 47 | |
| 48 | |
| 49 | declare -a commType_array |
| 50 | read -r -a commType_array <<< "${resourcesAr["CommType"]}" |
| 51 | |
| 52 | declare -a resourceName_array |
| 53 | read -r -a resourceName_array <<< "${resourcesAr["ResourceName"]}" |
| 54 | |
| 55 | declare -a uri_array |
| 56 | read -r -a uri_array <<< "${resourcesAr["Uri"]}" |
| 57 | |
| 58 | declare -a ops_array |
| 59 | |
| 60 | ops_array=$(echo ${resourcesAr["Operations"]} | tr ' ' '*') |
| 61 | |
| 62 | declare -a operations_array |
| 63 | |
| 64 | IFS=',' read -r -a operations_array <<< "${ops_array}" |
| 65 | |
| 66 | for operation in ${operations_array[@]}; do |
| 67 | >&2 echo "Operations Element: ${operation}" |
| 68 | done |
| 69 | |
| 70 | ops_ar_length=${#operations_array[@]} |
| 71 | |
| 72 | >&2 echo "ops_ar_length operations_array ${ops_ar_length}" |
| 73 | |
| 74 | # Iterate over the array using array indexing |
| 75 | resourceBlock="" |
| 76 | for (( i=0; i<ops_ar_length; i++ )); do |
| 77 | IFS='*' read -r -a ops_per_resource <<< "${operations_array[$i]}" |
| 78 | |
| 79 | resourceStart=" |
| 80 | { |
| 81 | \"CommType\": \"${commType_array[$i]}\", |
| 82 | \"Operations\": [ |
| 83 | " |
| 84 | |
| 85 | # Print the array elements |
| 86 | resourceMid="" |
| 87 | for element in "${ops_per_resource[@]}"; do |
| 88 | resourceMid="${resourceMid}\"${element}\", " |
| 89 | done |
| 90 | |
| 91 | resourceMid=$(sed 's/..$//' <<< "$resourceMid") |
| 92 | resourceMid="${resourceMid} |
| 93 | ]," |
| 94 | |
| 95 | |
| 96 | resourceEnd=" |
| 97 | \"ResourceName\": \"${resourceName_array[$i]}\", |
| 98 | \"Uri\": \"${uri_array[$i]}\" |
| 99 | }" |
| 100 | |
| 101 | |
| 102 | resourceItem="${resourceStart}${resourceMid}${resourceEnd}" |
| 103 | |
| 104 | resourceBlock="${resourceBlock}${resourceItem}, " |
| 105 | done |
| 106 | |
| 107 | resourceBlock=${resourceBlock::-2} |
| 108 | |
| 109 | payload="{ |
| 110 | \"AefProfiles\": [ |
| 111 | { |
| 112 | \"AefId\": \"${aefId}\", |
| 113 | \"interfaceDescriptions\": [ |
| 114 | ${interfaceDescBlock} |
| 115 | ], |
| 116 | \"DomainName\": \"${domainName}\", |
| 117 | \"Protocol\": \"HTTP_1_1\", |
| 118 | \"Versions\": [ |
| 119 | { |
| 120 | \"ApiVersion\": ${ApiVersion}, |
| 121 | \"Resources\": [ |
| 122 | ${resourceBlock} |
| 123 | ] |
| 124 | } |
| 125 | ] |
| 126 | } |
| 127 | ], |
| 128 | \"ApiName\": ${api_name}, |
| 129 | \"Description\": \"Description,namespace,repoName,chartName,releaseName\" |
| 130 | }" |
| 131 | >&2 echo "payload ${payload}" |
| 132 | |
| 133 | echo $payload | jq . |
| 134 | } |
| 135 | |
| 136 | function publish_service() { |
| 137 | echo "Publish service for $service_name" |
| 138 | |
| 139 | aef_profiles=$(echo "$service" | jq -c '.value.AefProfiles') |
| 140 | api_name=$(echo "$service" | jq -c '.value.ApiName') |
| 141 | |
| 142 | echo "$aef_profiles" | jq -c '.[]' | while read -r aef_profile; do |
| 143 | |
| 144 | interfaceDescriptions=$(echo "$aef_profile" | jq -c '.interfaceDescriptions') |
| 145 | |
| 146 | >&2 echo "interfaceDescriptions: ${interfaceDescriptions}"; |
| 147 | |
| 148 | interfaceDescIpv4Addr=$(echo $interfaceDescriptions | jq -r .[]."ipv4Addr") |
| 149 | interfaceDescPort=$(echo $interfaceDescriptions | jq .[]."port") |
| 150 | interfaceDescSecurityMethods=$(echo $interfaceDescriptions | jq -c .[]."securityMethods") |
| 151 | |
| 152 | >&2 echo "interfaceDescIpv4Addr: ${interfaceDescIpv4Addr}"; |
| 153 | >&2 echo "interfaceDescPort: ${interfaceDescPort}"; |
| 154 | >&2 echo "interfaceDescSecurityMethods: ${interfaceDescSecurityMethods}"; |
| 155 | |
| 156 | versions=$(echo "$aef_profile" | jq -c '.Versions[]') |
| 157 | |
| 158 | ApiVersion=$(echo "$versions" | jq -c '.ApiVersion') |
| 159 | >&2 echo "ApiVersion: $ApiVersion" |
| 160 | |
| 161 | Resources=$(echo "$versions" | jq -c '.Resources[]') |
| 162 | |
| 163 | # Parse Resources |
| 164 | declare -A resourcesAr |
| 165 | |
| 166 | commTypeCsv="" |
| 167 | |
| 168 | for row in $(echo "$Resources" | jq -c '.CommType'); do |
| 169 | commType=$(echo "$row" | jq -r '.'); |
| 170 | >&2 echo "commType: $commType"; |
| 171 | commTypeCsv="${commTypeCsv}${commType} " |
| 172 | >&2 echo "Building commTypeCsv ${commTypeCsv}" |
| 173 | done |
| 174 | |
| 175 | commTypeCsv=$(echo "$commTypeCsv" | xargs) |
| 176 | resourcesAr["CommType"]=${commTypeCsv} |
| 177 | |
| 178 | resourceNameCsv="" |
| 179 | for row in $(echo "$Resources" | jq -c '.ResourceName'); do |
| 180 | resourceName=$(echo "$row" | jq -r '.'); |
| 181 | >&2 echo "resourceName: $resourceName"; |
| 182 | resourceNameCsv="${resourceNameCsv}${resourceName} " |
| 183 | >&2 echo "Building resourceNameCsv ${resourceNameCsv}" |
| 184 | done |
| 185 | resourceNameCsv=$(echo "$resourceNameCsv" | xargs) |
| 186 | resourcesAr["ResourceName"]=$resourceNameCsv |
| 187 | |
| 188 | uriCsv="" |
| 189 | for row in $(echo "$Resources" | jq -c '.Uri'); do |
| 190 | uri=$(echo "$row" | jq -r '.'); |
| 191 | >&2 echo "uri: $uri"; |
| 192 | uriCsv="${uriCsv}${uri} " |
| 193 | >&2 echo "Building uriCsv ${uriCsv}" |
| 194 | done |
| 195 | uriCsv=$(echo "$uriCsv" | xargs) |
| 196 | resourcesAr["Uri"]=$uriCsv |
| 197 | |
| 198 | operationsCsv="" |
| 199 | for row in $(echo "$Resources" | jq -c '.Operations'); do |
| 200 | operations=$(echo "$row" | jq -r '.[]') |
| 201 | >&2 echo "operations: $operations"; |
| 202 | operationsCsv="${operationsCsv}${operations}," |
| 203 | >&2 echo "Building operationsCsv ${operationsCsv}" |
| 204 | done |
| 205 | resourcesAr["Operations"]=$operationsCsv |
| 206 | |
| 207 | payload=$(get_published_apis_payload) |
| 208 | |
| 209 | # Make the REST call |
| 210 | url="http://${first_node_ip}:${servicemanager_node_port}/published-apis/v1/${apfId}/service-apis" |
| 211 | >&2 echo "published-apis url: ${url}" |
| 212 | response=$(curl -s -X POST -H "Content-Type: application/json" -d "$payload" "$url") |
| 213 | |
| 214 | ret=$? |
| 215 | if [ $ret -ne 0 ]; then |
| 216 | echo "REST call to Service Manager/published-apis failed, error code $ret" |
| 217 | return $ret |
| 218 | fi |
| 219 | |
| 220 | resp_code=$(echo $response | jq -r '.status') |
| 221 | if [ "$resp_code" != "null" ] && [ "$resp_code" != "201" ]; then |
| 222 | echo "Failed to publish service $service_name with response code $resp_code" |
| 223 | fi |
| 224 | |
| 225 | response=$(echo "${response}" | jq .) |
| 226 | >&2 echo "Response for published service $service_name: $response" |
| 227 | done |
| 228 | return 0 |
| 229 | } |
| 230 | |
| 231 | function register_provider() { |
| 232 | # Make the REST call |
| 233 | url="http://${first_node_ip}:${servicemanager_node_port}/api-provider-management/v1/registrations" |
| 234 | response=$(curl -s -X POST -H "Content-Type: application/json" -d "$payload" "$url") |
| 235 | |
| 236 | ret=$? |
| 237 | if [ $ret -ne 0 ]; then |
| 238 | echo "REST call to Service Manager/api-provider-management failed, error code $ret" |
| 239 | status="$ret" |
| 240 | else |
| 241 | check_resp=$(jq --argjson resp "$response" -n '$resp.apiProvDomId') |
| 242 | if [ $check_resp != "null" ]; then |
| 243 | status=201 |
| 244 | else |
| 245 | status=$(jq --argjson resp "$response" -n '$resp.status') |
| 246 | fi |
| 247 | fi |
| 248 | echo $status |
| 249 | } |
| 250 | |
| 251 | function get_registrations_payload() { |
| 252 | payload="{ |
| 253 | \"apiProvDomInfo\": \"${domainName}\", |
| 254 | \"apiProvFuncs\": [ |
| 255 | { |
| 256 | \"apiProvFuncInfo\": \"${apf_info}\", |
| 257 | \"apiProvFuncRole\": \"APF\", |
| 258 | \"regInfo\": { |
| 259 | \"apiProvPubKey\": \"APF-PublicKey\" |
| 260 | } |
| 261 | }, |
| 262 | { |
| 263 | \"apiProvFuncInfo\": \"${aef_info}\", |
| 264 | \"apiProvFuncRole\": \"AEF\", |
| 265 | \"regInfo\": { |
| 266 | \"apiProvPubKey\": \"AEF-PublicKey\" |
| 267 | } |
| 268 | } |
| 269 | ], |
| 270 | \"regSec\": \"${service_name}-regsec\" |
| 271 | }" |
| 272 | echo $payload |
| 273 | } |
| 274 | |
| 275 | function register_apf() { |
| 276 | echo "Register provider for ${service_name}" |
| 277 | # Prepare the JSON payload for the REST calls |
| 278 | apf_info="${service_name} as APF" |
| 279 | aef_info="${service_name} as AEF" |
| 280 | aefId="AEF_id_${service_name}_as_AEF" |
| 281 | apfId="APF_id_${service_name}_as_APF" |
| 282 | |
| 283 | payload=$(get_registrations_payload) |
| 284 | >&2 echo "Registration payload: $payload" |
| 285 | resp=$(register_provider) |
| 286 | |
| 287 | if [ $resp != 201 ]; then |
| 288 | >&2 echo "Failed to register provider with error code ${resp}" |
| 289 | return $resp |
| 290 | fi |
| 291 | return 0 |
| 292 | } |
| 293 | |
| 294 | function find_running_services_from_config() { |
| 295 | result="" |
| 296 | |
| 297 | # Extract service names from YAML using yq and strip leading/trailing whitespace |
| 298 | SERVICE_NAMES=$(yq eval '. | keys[]' "$yaml_file") |
| 299 | |
| 300 | # Check each service using kubectl |
| 301 | for service in $SERVICE_NAMES; do |
| 302 | >&2 echo "Checking service: $service in nonrtric" |
| 303 | # Use kubectl get to check if the service exists and capture the output |
| 304 | SERVICE_STATUS=$(kubectl get service "$service" -n nonrtric) |
| 305 | |
| 306 | if [ $? = 0 ]; then |
| 307 | >&2 echo "Service $service is found in nonrtric" |
| 308 | result+="$service " |
| 309 | else |
| 310 | >&2 echo "Service $service is not running in nonrtric" |
| 311 | SERVICE_STATUS=$(kubectl get service "$service" -n onap) |
| 312 | if [ $? = 0 ]; then |
| 313 | >&2 echo "Service $service is found in onap" |
| 314 | result+="$service " |
| 315 | else |
| 316 | >&2 echo "Service $service is not found in onap" |
| 317 | fi |
| 318 | fi |
| 319 | done |
| 320 | |
| 321 | # Trim trailing whitespace |
| 322 | result=$(echo "$result" | xargs) |
| 323 | echo $result |
| 324 | } |
| 325 | |
| 326 | function publish_services_from_config() { |
| 327 | echo "Find running services" |
| 328 | domainName="kong" |
| 329 | running_services_list=$(find_running_services_from_config) |
| 330 | |
| 331 | # Iterate through the configured services |
| 332 | echo "$json_config" | jq -c 'to_entries[]' | while read -r service; do |
| 333 | service_name=$(echo "$service" | jq -r '.key') |
| 334 | if echo "$running_services_list" | grep -q "$service_name"; then |
| 335 | register_apf |
| 336 | ret=$? |
| 337 | if [ $ret -ne 0 ]; then |
| 338 | break |
| 339 | fi |
| 340 | |
| 341 | publish_service |
| 342 | ret=$? |
| 343 | if [ $ret -ne 0 ]; then |
| 344 | break |
| 345 | fi |
| 346 | fi |
| 347 | done |
| 348 | } |
| 349 | |
| 350 | # Ensure yq and jq are installed |
| 351 | if ! command -v yq &> /dev/null; then |
| 352 | >&2 echo "yq is not installed. Installing yq..." |
| 353 | sudo snap install yq --channel=v4/stable |
| 354 | fi |
| 355 | |
| 356 | if ! command -v jq &> /dev/null; then |
| 357 | >&2 echo "jq is not installed. Installing jq..." |
| 358 | sudo snap install jq |
| 359 | fi |
| 360 | |
| 361 | # Read and parse the YAML file |
| 362 | yaml_file="${1:-config.yaml}" |
| 363 | json_config=$(yq eval "$yaml_file" -o=json) |
| 364 | |
| 365 | echo "Preloading Service Manager from ${yaml_file}" |
| 366 | |
| 367 | # Get our Node IP and nodePort |
| 368 | first_node_ip=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}') |
| 369 | servicemanager_node_port=$(kubectl get service servicemanager -n nonrtric -o jsonpath='{.spec.ports[0].nodePort}') |
| 370 | |
| 371 | echo "Waiting for capifcore deployment" |
| 372 | kubectl wait --for=condition=Available -n nonrtric --timeout=300s deploy/capifcore |
| 373 | |
| 374 | echo "Waiting for servicemanager deployment" |
| 375 | kubectl wait --for=condition=Available -n nonrtric --timeout=300s deploy/servicemanager |
| 376 | |
| 377 | echo "Waiting for kong deployment" |
| 378 | kubectl wait --for=condition=Available -n nonrtric --timeout=300s deploy/oran-nonrtric-kong |
| 379 | |
| 380 | publish_services_from_config |
| 381 | |
| 382 | echo "Service Manager preload completed for ${yaml_file}" |