X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=code%2Fnetwork-topology-parser%2Fmain.go;fp=code%2Fnetwork-topology-parser%2Fmain.go;h=6fdbf38ec696a306c70d2cb64d63c3ec90ef313e;hb=ce0a6e1ea17d53759f3fc9b56fb3bf429ca21d36;hp=0000000000000000000000000000000000000000;hpb=bb8d838a4d78858b2a5807214df92857957632d2;p=oam.git diff --git a/code/network-topology-parser/main.go b/code/network-topology-parser/main.go new file mode 100644 index 0000000..6fdbf38 --- /dev/null +++ b/code/network-topology-parser/main.go @@ -0,0 +1,218 @@ +/************************************************************************ +* Copyright 2022 highstreet technologies GmbH +* +* 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. +************************************************************************/ + +package main + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "os" + + "github.com/goccy/go-yaml" +) + +var configYAML Config + +// common parts consist of the anchors that are reused for the services +func createCommonParts() { + configYAML.Version = "3.8" + + configYAML.CommonEnvs = make(map[string]string, 1) + + configYAML.CommonEnvs["IPv6_ENABLED"] = "${IPv6_ENABLED}" + configYAML.CommonEnvs["SSH_CONNECTIONS"] = "${SSH_CONNECTIONS}" + configYAML.CommonEnvs["TLS_CONNECTIONS"] = "${TLS_CONNECTIONS}" + configYAML.CommonEnvs["NTS_NF_MOUNT_POINT_ADDRESSING_METHOD"] = "${NTS_NF_MOUNT_POINT_ADDRESSING_METHOD}" + configYAML.CommonEnvs["NTS_HOST_IP"] = "${NTS_HOST_IP}" + configYAML.CommonEnvs["NTS_HOST_BASE_PORT"] = "${NTS_HOST_BASE_PORT}" + configYAML.CommonEnvs["NTS_HOST_NETCONF_SSH_BASE_PORT"] = "${NTS_HOST_NETCONF_SSH_BASE_PORT}" + configYAML.CommonEnvs["NTS_HOST_NETCONF_TLS_BASE_PORT"] = "${NTS_HOST_NETCONF_TLS_BASE_PORT}" + configYAML.CommonEnvs["NTS_HOST_TRANSFER_FTP_BASE_PORT"] = "${NTS_HOST_TRANSFER_FTP_BASE_PORT}" + configYAML.CommonEnvs["NTS_HOST_TRANSFER_SFTP_BASE_PORT"] = "${NTS_HOST_TRANSFER_SFTP_BASE_PORT}" + configYAML.CommonEnvs["SDN_CONTROLLER_PROTOCOL"] = "${SDN_CONTROLLER_PROTOCOL}" + configYAML.CommonEnvs["SDN_CONTROLLER_IP"] = "${SDNC_OAM_IPv6}" + configYAML.CommonEnvs["SDN_CONTROLLER_PORT"] = "${SDNC_REST_PORT}" + configYAML.CommonEnvs["SDN_CONTROLLER_CALLHOME_IP"] = "${SDNC_OAM_IPv6}" + configYAML.CommonEnvs["SDN_CONTROLLER_CALLHOME_PORT"] = "${SDN_CONTROLLER_CALLHOME_PORT}" + configYAML.CommonEnvs["SDN_CONTROLLER_USERNAME"] = "${ADMIN_USERNAME}" + configYAML.CommonEnvs["SDN_CONTROLLER_PASSWORD"] = "${ADMIN_PASSWORD}" + configYAML.CommonEnvs["VES_COMMON_HEADER_VERSION"] = "${VES_COMMON_HEADER_VERSION}" + configYAML.CommonEnvs["VES_ENDPOINT_PROTOCOL"] = "${VES_ENDPOINT_PROTOCOL}" + configYAML.CommonEnvs["VES_ENDPOINT_IP"] = "${VES_COLLECTOR_OAM_IPv6}" + configYAML.CommonEnvs["VES_ENDPOINT_PORT"] = "${VES_ENDPOINT_PORT}" + configYAML.CommonEnvs["VES_ENDPOINT_AUTH_METHOD"] = "${VES_ENDPOINT_AUTH_METHOD}" + configYAML.CommonEnvs["VES_ENDPOINT_USERNAME"] = "${VES_ENDPOINT_USERNAME}" + configYAML.CommonEnvs["VES_ENDPOINT_PASSWORD"] = "${VES_ENDPOINT_PASSWORD}" + + configYAML.DuEnv = make(map[string]string, 1) + configYAML.DuEnv["NTS_NF_STANDALONE_START_FEATURES"] = "datastore-populate ves-heartbeat ves-file-ready ves-pnf-registration web-cut-through" + + configYAML.RuEnv = make(map[string]string, 1) + configYAML.RuEnv["NTS_NF_STANDALONE_START_FEATURES"] = "datastore-populate netconf-call-home web-cut-through" + + configYAML.TopoEnv = make(map[string]string, 1) + configYAML.TopoEnv["NTS_NF_STANDALONE_START_FEATURES"] = "datastore-populate netconf-call-home web-cut-through" + + var commonNf CommonNf + commonNf.StopGracePeriod = "5m" + commonNf.CapAdd = append(commonNf.CapAdd, "SYS_ADMIN") + commonNf.CapAdd = append(commonNf.CapAdd, "SYS_PTRACE") + configYAML.CommonNfs = commonNf +} + +// creates the network information to be used by the services +func createNetwork() { + configYAML.Networks = make(map[string]Network, 1) + defaultNetwork := configYAML.Networks["default"] + + defaultNetwork.External = make(map[string]string, 1) + defaultNetwork.External["name"] = "oam" + + configYAML.Networks["default"] = defaultNetwork +} + +// creates an O-RU simulator instance as a service +func addORUasService(name string) { + service := configYAML.Services[name] + + service.Image = "${NEXUS3_DOCKER_REPO}nts-ng-o-ran-ru-fh:${NTS_BUILD_VERSION}" + service.ContainerName = "ntsim-ng-" + name + service.Hostname = name + + commonEnv := &CommonEnv{} + ruEnv := &RuEnv{} + env := &Env{commonEnv, nil, ruEnv, nil} + service.Environment = *env + + configYAML.Services[name] = service +} + +// creates an O-DU simulator instance as a service +func addODUasService(name string) { + service := configYAML.Services[name] + + service.Image = "${NEXUS3_DOCKER_REPO}nts-ng-o-ran-du:${NTS_BUILD_VERSION}" + service.ContainerName = "ntsim-ng-" + name + service.Hostname = name + + commonEnv := &CommonEnv{} + duEnv := &DuEnv{} + env := &Env{commonEnv, duEnv, nil, nil} + service.Environment = *env + + configYAML.Services[name] = service +} + +// iterates through the topology and creates associated services +func createServices(topologyJSON *TapiContext) { + topology := topologyJSON.TapiCommonContext.TapiTopologyTopologyContext.Topology[0] + + configYAML.Services = make(map[string]Service, 1) + + for _, node := range topology.Node { + if node.ORanScTopologyFunction == "o-ran-sc-topology-common:o-ru" { + name := getNodeNameFromUUID(node.UUID, topologyJSON) + addORUasService(name) + } else if node.ORanScTopologyFunction == "o-ran-sc-topology-common:o-du" { + name := getNodeNameFromUUID(node.UUID, topologyJSON) + addODUasService(name) + } + } +} + +// returns the type of O-RAN-SC Topology Function of the input TAPI Node +func getTypeOfNodeUUID(nodeUUID string, topologyJSON *TapiContext) string { + topology := topologyJSON.TapiCommonContext.TapiTopologyTopologyContext.Topology[0] + + for _, node := range topology.Node { + if node.UUID == nodeUUID { + return node.ORanScTopologyFunction + } + } + + return "" +} + +// returns the Node Name of the TAPI Node with the input UUID +func getNodeNameFromUUID(searchedUUID string, topologyJSON *TapiContext) string { + topology := topologyJSON.TapiCommonContext.TapiTopologyTopologyContext.Topology[0] + + for _, node := range topology.Node { + if node.UUID == searchedUUID { + for _, name := range node.Name { + if name.ValueName == "topology-node-name" { + return name.Value + } + } + } + } + + return "" +} + +func main() { + if len(os.Args) > 1 { + fmt.Printf("Parsing file %v...\n", os.Args[1]) + } else { + fmt.Printf("Usage: %v \nwhere input is the topology filename in JSON format.\n", os.Args[0]) + os.Exit(0) + } + + if _, err := os.Stat(os.Args[1]); errors.Is(err, os.ErrNotExist) { + fmt.Printf("File %v does not exist!\n", os.Args[1]) + os.Exit(1) + } + + topoJSONFile, err := os.Open(os.Args[1]) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer topoJSONFile.Close() + + byteValue, _ := ioutil.ReadAll(topoJSONFile) + + var topologyObject TapiContext + err = json.Unmarshal(byteValue, &topologyObject) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + if len(topologyObject.TapiCommonContext.TapiTopologyTopologyContext.Topology) < 1 { + fmt.Println("Could not find TAPI Topology object in the loaded JSON!") + os.Exit(1) + } + + createCommonParts() + createNetwork() + createServices(&topologyObject) + + yamlData, err := yaml.Marshal(&configYAML) + if err != nil { + fmt.Println(err) + } + + fileName := "docker-compose.yaml" + err = ioutil.WriteFile(fileName, yamlData, 0644) + if err != nil { + fmt.Println(err) + } + + fmt.Println("File docker-compose.yaml created successfully!") +}