blob: 6fdbf38ec696a306c70d2cb64d63c3ec90ef313e [file] [log] [blame]
Alex Stancuce0a6e12022-03-04 18:03:41 +02001/************************************************************************
2* Copyright 2022 highstreet technologies GmbH
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15************************************************************************/
16
17package main
18
19import (
20 "encoding/json"
21 "errors"
22 "fmt"
23 "io/ioutil"
24 "os"
25
26 "github.com/goccy/go-yaml"
27)
28
29var configYAML Config
30
31// common parts consist of the anchors that are reused for the services
32func createCommonParts() {
33 configYAML.Version = "3.8"
34
35 configYAML.CommonEnvs = make(map[string]string, 1)
36
37 configYAML.CommonEnvs["IPv6_ENABLED"] = "${IPv6_ENABLED}"
38 configYAML.CommonEnvs["SSH_CONNECTIONS"] = "${SSH_CONNECTIONS}"
39 configYAML.CommonEnvs["TLS_CONNECTIONS"] = "${TLS_CONNECTIONS}"
40 configYAML.CommonEnvs["NTS_NF_MOUNT_POINT_ADDRESSING_METHOD"] = "${NTS_NF_MOUNT_POINT_ADDRESSING_METHOD}"
41 configYAML.CommonEnvs["NTS_HOST_IP"] = "${NTS_HOST_IP}"
42 configYAML.CommonEnvs["NTS_HOST_BASE_PORT"] = "${NTS_HOST_BASE_PORT}"
43 configYAML.CommonEnvs["NTS_HOST_NETCONF_SSH_BASE_PORT"] = "${NTS_HOST_NETCONF_SSH_BASE_PORT}"
44 configYAML.CommonEnvs["NTS_HOST_NETCONF_TLS_BASE_PORT"] = "${NTS_HOST_NETCONF_TLS_BASE_PORT}"
45 configYAML.CommonEnvs["NTS_HOST_TRANSFER_FTP_BASE_PORT"] = "${NTS_HOST_TRANSFER_FTP_BASE_PORT}"
46 configYAML.CommonEnvs["NTS_HOST_TRANSFER_SFTP_BASE_PORT"] = "${NTS_HOST_TRANSFER_SFTP_BASE_PORT}"
47 configYAML.CommonEnvs["SDN_CONTROLLER_PROTOCOL"] = "${SDN_CONTROLLER_PROTOCOL}"
48 configYAML.CommonEnvs["SDN_CONTROLLER_IP"] = "${SDNC_OAM_IPv6}"
49 configYAML.CommonEnvs["SDN_CONTROLLER_PORT"] = "${SDNC_REST_PORT}"
50 configYAML.CommonEnvs["SDN_CONTROLLER_CALLHOME_IP"] = "${SDNC_OAM_IPv6}"
51 configYAML.CommonEnvs["SDN_CONTROLLER_CALLHOME_PORT"] = "${SDN_CONTROLLER_CALLHOME_PORT}"
52 configYAML.CommonEnvs["SDN_CONTROLLER_USERNAME"] = "${ADMIN_USERNAME}"
53 configYAML.CommonEnvs["SDN_CONTROLLER_PASSWORD"] = "${ADMIN_PASSWORD}"
54 configYAML.CommonEnvs["VES_COMMON_HEADER_VERSION"] = "${VES_COMMON_HEADER_VERSION}"
55 configYAML.CommonEnvs["VES_ENDPOINT_PROTOCOL"] = "${VES_ENDPOINT_PROTOCOL}"
56 configYAML.CommonEnvs["VES_ENDPOINT_IP"] = "${VES_COLLECTOR_OAM_IPv6}"
57 configYAML.CommonEnvs["VES_ENDPOINT_PORT"] = "${VES_ENDPOINT_PORT}"
58 configYAML.CommonEnvs["VES_ENDPOINT_AUTH_METHOD"] = "${VES_ENDPOINT_AUTH_METHOD}"
59 configYAML.CommonEnvs["VES_ENDPOINT_USERNAME"] = "${VES_ENDPOINT_USERNAME}"
60 configYAML.CommonEnvs["VES_ENDPOINT_PASSWORD"] = "${VES_ENDPOINT_PASSWORD}"
61
62 configYAML.DuEnv = make(map[string]string, 1)
63 configYAML.DuEnv["NTS_NF_STANDALONE_START_FEATURES"] = "datastore-populate ves-heartbeat ves-file-ready ves-pnf-registration web-cut-through"
64
65 configYAML.RuEnv = make(map[string]string, 1)
66 configYAML.RuEnv["NTS_NF_STANDALONE_START_FEATURES"] = "datastore-populate netconf-call-home web-cut-through"
67
68 configYAML.TopoEnv = make(map[string]string, 1)
69 configYAML.TopoEnv["NTS_NF_STANDALONE_START_FEATURES"] = "datastore-populate netconf-call-home web-cut-through"
70
71 var commonNf CommonNf
72 commonNf.StopGracePeriod = "5m"
73 commonNf.CapAdd = append(commonNf.CapAdd, "SYS_ADMIN")
74 commonNf.CapAdd = append(commonNf.CapAdd, "SYS_PTRACE")
75 configYAML.CommonNfs = commonNf
76}
77
78// creates the network information to be used by the services
79func createNetwork() {
80 configYAML.Networks = make(map[string]Network, 1)
81 defaultNetwork := configYAML.Networks["default"]
82
83 defaultNetwork.External = make(map[string]string, 1)
84 defaultNetwork.External["name"] = "oam"
85
86 configYAML.Networks["default"] = defaultNetwork
87}
88
89// creates an O-RU simulator instance as a service
90func addORUasService(name string) {
91 service := configYAML.Services[name]
92
93 service.Image = "${NEXUS3_DOCKER_REPO}nts-ng-o-ran-ru-fh:${NTS_BUILD_VERSION}"
94 service.ContainerName = "ntsim-ng-" + name
95 service.Hostname = name
96
97 commonEnv := &CommonEnv{}
98 ruEnv := &RuEnv{}
99 env := &Env{commonEnv, nil, ruEnv, nil}
100 service.Environment = *env
101
102 configYAML.Services[name] = service
103}
104
105// creates an O-DU simulator instance as a service
106func addODUasService(name string) {
107 service := configYAML.Services[name]
108
109 service.Image = "${NEXUS3_DOCKER_REPO}nts-ng-o-ran-du:${NTS_BUILD_VERSION}"
110 service.ContainerName = "ntsim-ng-" + name
111 service.Hostname = name
112
113 commonEnv := &CommonEnv{}
114 duEnv := &DuEnv{}
115 env := &Env{commonEnv, duEnv, nil, nil}
116 service.Environment = *env
117
118 configYAML.Services[name] = service
119}
120
121// iterates through the topology and creates associated services
122func createServices(topologyJSON *TapiContext) {
123 topology := topologyJSON.TapiCommonContext.TapiTopologyTopologyContext.Topology[0]
124
125 configYAML.Services = make(map[string]Service, 1)
126
127 for _, node := range topology.Node {
128 if node.ORanScTopologyFunction == "o-ran-sc-topology-common:o-ru" {
129 name := getNodeNameFromUUID(node.UUID, topologyJSON)
130 addORUasService(name)
131 } else if node.ORanScTopologyFunction == "o-ran-sc-topology-common:o-du" {
132 name := getNodeNameFromUUID(node.UUID, topologyJSON)
133 addODUasService(name)
134 }
135 }
136}
137
138// returns the type of O-RAN-SC Topology Function of the input TAPI Node
139func getTypeOfNodeUUID(nodeUUID string, topologyJSON *TapiContext) string {
140 topology := topologyJSON.TapiCommonContext.TapiTopologyTopologyContext.Topology[0]
141
142 for _, node := range topology.Node {
143 if node.UUID == nodeUUID {
144 return node.ORanScTopologyFunction
145 }
146 }
147
148 return ""
149}
150
151// returns the Node Name of the TAPI Node with the input UUID
152func getNodeNameFromUUID(searchedUUID string, topologyJSON *TapiContext) string {
153 topology := topologyJSON.TapiCommonContext.TapiTopologyTopologyContext.Topology[0]
154
155 for _, node := range topology.Node {
156 if node.UUID == searchedUUID {
157 for _, name := range node.Name {
158 if name.ValueName == "topology-node-name" {
159 return name.Value
160 }
161 }
162 }
163 }
164
165 return ""
166}
167
168func main() {
169 if len(os.Args) > 1 {
170 fmt.Printf("Parsing file %v...\n", os.Args[1])
171 } else {
172 fmt.Printf("Usage: %v <input>\nwhere input is the topology filename in JSON format.\n", os.Args[0])
173 os.Exit(0)
174 }
175
176 if _, err := os.Stat(os.Args[1]); errors.Is(err, os.ErrNotExist) {
177 fmt.Printf("File %v does not exist!\n", os.Args[1])
178 os.Exit(1)
179 }
180
181 topoJSONFile, err := os.Open(os.Args[1])
182 if err != nil {
183 fmt.Println(err)
184 os.Exit(1)
185 }
186 defer topoJSONFile.Close()
187
188 byteValue, _ := ioutil.ReadAll(topoJSONFile)
189
190 var topologyObject TapiContext
191 err = json.Unmarshal(byteValue, &topologyObject)
192 if err != nil {
193 fmt.Println(err)
194 os.Exit(1)
195 }
196
197 if len(topologyObject.TapiCommonContext.TapiTopologyTopologyContext.Topology) < 1 {
198 fmt.Println("Could not find TAPI Topology object in the loaded JSON!")
199 os.Exit(1)
200 }
201
202 createCommonParts()
203 createNetwork()
204 createServices(&topologyObject)
205
206 yamlData, err := yaml.Marshal(&configYAML)
207 if err != nil {
208 fmt.Println(err)
209 }
210
211 fileName := "docker-compose.yaml"
212 err = ioutil.WriteFile(fileName, yamlData, 0644)
213 if err != nil {
214 fmt.Println(err)
215 }
216
217 fmt.Println("File docker-compose.yaml created successfully!")
218}