aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--deployment/heat/onap-oom/onap-oom.yaml4
-rw-r--r--deployment/heat/onap-oom/parts/onap-oom-1.yaml4
-rw-r--r--test/mocks/datafilecollector-testharness/dr-sim/dmaapBusController.js91
-rw-r--r--test/mocks/mass-pnf-sim/README.md12
-rwxr-xr-xtest/mocks/mass-pnf-sim/mass-pnf-sim.py37
-rw-r--r--test/mocks/mass-pnf-sim/pnf-sim-lightweight/README.md14
-rw-r--r--test/mocks/mass-pnf-sim/pnf-sim-lightweight/docker-compose-template.yml4
-rwxr-xr-xtest/mocks/mass-pnf-sim/pnf-sim-lightweight/simulator.sh19
-rw-r--r--test/mocks/mass-pnf-sim/pnf-sim-lightweight/src/main/java/org/onap/pnfsimulator/message/MessageProvider.java68
-rwxr-xr-xtest/security/check_for_jdwp.sh93
10 files changed, 255 insertions, 91 deletions
diff --git a/deployment/heat/onap-oom/onap-oom.yaml b/deployment/heat/onap-oom/onap-oom.yaml
index c2c08f6d9..dfea00418 100644
--- a/deployment/heat/onap-oom/onap-oom.yaml
+++ b/deployment/heat/onap-oom/onap-oom.yaml
@@ -73,7 +73,7 @@ parameters:
rancher_version:
type: string
- default: "1.6.25"
+ default: "1.6.26"
rancher_agent_version:
type: string
@@ -81,7 +81,7 @@ parameters:
kubectl_version:
type: string
- default: "1.11.5"
+ default: "1.11.6"
helm_version:
type: string
diff --git a/deployment/heat/onap-oom/parts/onap-oom-1.yaml b/deployment/heat/onap-oom/parts/onap-oom-1.yaml
index bff17c05b..7ffd2f4d5 100644
--- a/deployment/heat/onap-oom/parts/onap-oom-1.yaml
+++ b/deployment/heat/onap-oom/parts/onap-oom-1.yaml
@@ -70,7 +70,7 @@ parameters:
rancher_version:
type: string
- default: "1.6.25"
+ default: "1.6.26"
rancher_agent_version:
type: string
@@ -78,7 +78,7 @@ parameters:
kubectl_version:
type: string
- default: "1.11.5"
+ default: "1.11.6"
helm_version:
type: string
diff --git a/test/mocks/datafilecollector-testharness/dr-sim/dmaapBusController.js b/test/mocks/datafilecollector-testharness/dr-sim/dmaapBusController.js
index cca85f98b..a1b2770cf 100644
--- a/test/mocks/datafilecollector-testharness/dr-sim/dmaapBusController.js
+++ b/test/mocks/datafilecollector-testharness/dr-sim/dmaapBusController.js
@@ -6,35 +6,38 @@ const stream = require('stream');
var app = express();
var fs = require("fs");
var path = require('path');
-var privateKey = fs.readFileSync('cert/private.key', 'utf8');
+var privateKey = fs.readFileSync('cert/private.key', 'utf8');
var certificate = fs.readFileSync('cert/certificate.crt', 'utf8');
-var credentials = {key: privateKey, cert: certificate};
+var credentials = {
+ key: privateKey,
+ cert: certificate
+};
var parser = new ArgumentParser({
- version: '0.0.1',
- addHelp:true,
- description: 'Datarouter simulator'
- });
+ version: '0.0.1',
+ addHelp: true,
+ description: 'Datarouter simulator'
+});
-parser.addArgument('--tc' , { help: 'TC $NoOfTc' } );
-parser.addArgument('--printtc' ,
- {
- help: 'Print complete usage help',
- action: 'storeTrue'
- }
- );
+parser.addArgument('--tc', {
+ help: 'TC $NoOfTc'
+});
+parser.addArgument('--printtc', {
+ help: 'Print complete usage help',
+ action: 'storeTrue'
+});
var args = parser.parseArgs();
-if (args.tc=="100") {
+if (args.tc == "100") {
console.log("TC: 100")
}
-if (args.tc=="101") {
+if (args.tc == "101") {
console.log("TC: 101")
//preparations
}
-if (args.tc=="102") {
+if (args.tc == "102") {
console.log("TC: 102")
//preparations
}
@@ -47,30 +50,66 @@ if (args.printtc) {
}
var bodyParser = require('body-parser')
-app.use(bodyParser.urlencoded({ extended: false }))
+app.use(bodyParser.urlencoded({
+ extended: false
+}))
// parse application/json
app.use(bodyParser.json())
// parse application/vnd.api+json as json
-app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
+app.use(bodyParser.json({
+ type: 'application/vnd.api+json'
+}))
// parse some custom thing into a Buffer
-app.use(bodyParser.raw({limit:1024*1024*20, type: 'application/octet-stream' }))
+app.use(bodyParser.raw({
+ limit: 1024 * 1024 * 20,
+ type: 'application/octet-stream'
+}))
// parse an HTML body into a string
-app.use(bodyParser.text({ type: 'text/html' }))
-app.get("/",function(req, res){
+app.use(bodyParser.text({
+ type: 'text/html'
+}))
+app.get("/", function (req, res) {
res.send("ok");
})
app.post('/webapi/feeds/', function (req, res) {
- res.send("ok");
+ res.setHeader('Content-Type', 'application/json');
+ var feedName = req.body.feedName;
+ console.log(feedName);
+ res.end(JSON.stringify({
+ "type": "feed",
+ "lastMod": "2019-03-21T16:00:40.489",
+ "status": "VALID",
+ "asprClassification": "unclassified",
+ "feedDescription": "generated for CSIT",
+ "feedId": "3",
+ "feedName": feedName,
+ "feedVersion": "csit",
+ "logURL": "https://dmaap-dr-prov/feedlog/3",
+ "owner": "dgl",
+ "publishURL": "https://dmaap-dr-prov/publish/3",
+ "pubs": [{
+ "lastMod": "2019-01-24T16:00:40.484",
+ "status": "VALID",
+ "dcaeLocationName": "san-francisco",
+ "feedId": "3",
+ "pubId": "3.4gh53",
+ "username": "tmp_i63w8psh6ycnoqu",
+ "userpwd": "6jkc1uwywrc8q4w"
+ }],
+ "subs": [],
+ "subscribeURL": "https://dmaap-dr-prov/subscribe/3",
+ "suspended": false
+ }));
})
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
-var httpPort=6665
-var httpsPort=6666
+var httpPort = 6665
+var httpsPort = 6666
httpServer.listen(httpPort);
-console.log("DR-simulator listening (http) at "+httpPort)
+console.log("DR-simulator listening (http) at " + httpPort)
httpsServer.listen(httpsPort);
-console.log("DR-simulator listening (https) at "+httpsPort) \ No newline at end of file
+console.log("DR-simulator listening (https) at " + httpsPort) \ No newline at end of file
diff --git a/test/mocks/mass-pnf-sim/README.md b/test/mocks/mass-pnf-sim/README.md
index 1ed90b55d..ffa82c118 100644
--- a/test/mocks/mass-pnf-sim/README.md
+++ b/test/mocks/mass-pnf-sim/README.md
@@ -15,19 +15,21 @@ The ipstart should align to a /28 Ip address range start (e.g. 10.11.0.16, 10.11
For debug purposes, you can use your own IP address as VES collector, use "ip" command to determine it.
Example:
-python3 ./mass-pnf-sim.py --bootstrap 2 --ipves http://10.148.95.??:10000 --ipstart 10.11.0.16
+./mass-pnf-sim.py --bootstrap 2 --ipves http://10.148.95.??:10000 --ipfileserver 10.148.95.??? --ipstart 10.11.0.16
###Replacing VES for test purposes
-`nc -l 10000`
+`sudo nc -vv -l -k -p 10000`
###Start
Define the amount of simulators to be launched
-python3 ./mass-pnf-sim.py --start 2
+./mass-pnf-sim.py --start 2
+###Trigger
+./mass-pnf-sim.py --trigger 2
###Stop and clean
-python3 ./mass-pnf-sim.py --stop 2
-python3 ./mass-pnf-sim.py --clean
+./mass-pnf-sim.py --stop 2
+./mass-pnf-sim.py --clean
###Cleaning and recovery after incorrect configuration
docker stop $(docker ps -aq); docker rm $(docker ps -aq)
diff --git a/test/mocks/mass-pnf-sim/mass-pnf-sim.py b/test/mocks/mass-pnf-sim/mass-pnf-sim.py
index ba0598671..898cd650f 100755
--- a/test/mocks/mass-pnf-sim/mass-pnf-sim.py
+++ b/test/mocks/mass-pnf-sim/mass-pnf-sim.py
@@ -14,11 +14,21 @@ parser.add_argument(
)
parser.add_argument(
+ '--trigger',
+ help='Trigger one single VES event from each simulator',
+)
+
+parser.add_argument(
'--ipves',
help='IP of the VES collector',
)
parser.add_argument(
+ '--ipfileserver',
+ help='Visible IP of the file server (SFTP/FTPS) to be included in the VES event',
+)
+
+parser.add_argument(
'--ipstart',
help='IP address range beginning',
)
@@ -49,6 +59,8 @@ args = parser.parse_args()
if args.bootstrap and args.ipstart and args.ipves:
print("Bootstrap:")
+ start_port=2000
+
for i in range(int(args.bootstrap)):
print("PNF simulator instance: " + str(i) + ".")
@@ -63,9 +75,15 @@ if args.bootstrap and args.ipstart and args.ipves:
IpPnfSim = ipaddress.ip_address(args.ipstart) + int(2 + (i * 16))
print("\tIp Pnf SIM:" + str(IpPnfSim))
+ IpFileServer = args.ipfileserver
+
+
+ PortSftp=start_port +1
+ PortFtps=start_port +2
+ start_port +=2
IpFtps = ipaddress.ip_address(args.ipstart) + int(3 + (i * 16))
print("\tIp Ftps: " + str(IpFtps))
-
+
IpSftp = ipaddress.ip_address(args.ipstart) + int(4 + (i * 16))
print("\tIp Sftp:" + str(IpSftp))
@@ -84,6 +102,9 @@ if args.bootstrap and args.ipstart and args.ipves:
str(i) + " " +\
str(args.ipves) + " " +\
str(IpPnfSim) + " " +\
+ str(IpFileServer) + " " +\
+ str(PortSftp) + " " +\
+ str(PortFtps) + " " +\
str(IpFtps) + " " +\
str(IpSftp)
@@ -139,6 +160,20 @@ if args.stop:
shell=True)
print('Stopping:', completed.stdout)
+
+if args.trigger:
+ print("Triggering VES sending:")
+
+ for i in range(int(args.trigger)):
+ foldername = "pnf-sim-lw-" + str(i)
+
+ completed = subprocess.run(
+ 'cd ' +
+ foldername +
+ "; ./simulator.sh trigger-simulator",
+ shell=True)
+ print('Status:', completed.stdout)
+
else:
print("No instruction was defined")
sys.exit()
diff --git a/test/mocks/mass-pnf-sim/pnf-sim-lightweight/README.md b/test/mocks/mass-pnf-sim/pnf-sim-lightweight/README.md
index 2b20d261e..2940b65db 100644
--- a/test/mocks/mass-pnf-sim/pnf-sim-lightweight/README.md
+++ b/test/mocks/mass-pnf-sim/pnf-sim-lightweight/README.md
@@ -1,6 +1,6 @@
##Local development shortcuts:
####To start listening on port 10000 for test purposes
-`nc -l 10000`
+`nc -l -k -p 10000`
####Test the command above:
`echo "Hello World" | nc localhost 10000`
@@ -27,10 +27,12 @@ Accept-Encoding: gzip,deflate
```
```javascript
-{"commonEventHeader":{"startEpochMicrosec":"1551865758690","sourceId":"val13","eventId":"registration_51865758",
+{"event":{"commonEventHeader":{"startEpochMicrosec":"1551865758690","sourceId":"val13","eventId":"registration_51865758",
"nfcNamingCode":"oam","internalHeaderFields":{},"priority":"Normal","version":"4.0.1","reportingEntityName":"NOK6061ZW3",
-"sequence":"0","domain":"notification","lastEpochMicrosec":"1551865758690","eventName":"pnfRegistration_Nokia_5gDu","vesEventListenerVersion":"7.0.1",
-"sourceName":"NOK6061ZW3","nfNamingCode":"gNB"},"notificationFields":{"notificationFieldsVersion":"2.0","changeType":"FileReady",
-"changeIdentifier":"PM_MEAS_FILES","arrayOfNamedHashMap":{"name":"10MB.tar.gz",
-"hashMap":{"location":"10.11.0.68/10MB.tar.gz","fileFormatType":"org.3GPP.32.435#measCollec","fileFormatVersion":"V10","compression":"gzip"}}}}
+"sequence":"0","domain":"notification","lastEpochMicrosec":"1551865758690","eventName":"pnfRegistration_Nokia_5gDu",
+"vesEventListenerVersion":"7.0.1","sourceName":"NOK6061ZW3","nfNamingCode":"gNB"},
+"notificationFields":{"notificationFieldsVersion":"2.0","changeType":"FileReady","changeIdentifier":"PM_MEAS_FILES",
+"arrayOfNamedHashMap":[{"name":"10MB.tar.gz","hashMap":{
+"location":"ftpes://10.11.0.68/10MB.tar.gz","fileFormatType":"org.3GPP.32.435#measCollec",
+"fileFormatVersion":"V10","compression":"gzip"}}]}}}
``` \ No newline at end of file
diff --git a/test/mocks/mass-pnf-sim/pnf-sim-lightweight/docker-compose-template.yml b/test/mocks/mass-pnf-sim/pnf-sim-lightweight/docker-compose-template.yml
index f53226867..aa0261c0a 100644
--- a/test/mocks/mass-pnf-sim/pnf-sim-lightweight/docker-compose-template.yml
+++ b/test/mocks/mass-pnf-sim/pnf-sim-lightweight/docker-compose-template.yml
@@ -29,6 +29,8 @@ services:
networks:
front-${I}:
ipv4_address: "${IPSFTP}"
+ ports:
+ - "${PORTSFTP}:22"
volumes:
- ./files/onap/:/home/onap/
restart: on-failure
@@ -40,6 +42,8 @@ services:
networks:
front-${I}:
ipv4_address: "${IPFTPS}"
+ ports:
+ - "${PORTFTPS}:21"
environment:
FTP_USER: onap
FTP_PASSWORD: pano
diff --git a/test/mocks/mass-pnf-sim/pnf-sim-lightweight/simulator.sh b/test/mocks/mass-pnf-sim/pnf-sim-lightweight/simulator.sh
index bed64b0b7..86f15a8e2 100755
--- a/test/mocks/mass-pnf-sim/pnf-sim-lightweight/simulator.sh
+++ b/test/mocks/mass-pnf-sim/pnf-sim-lightweight/simulator.sh
@@ -20,8 +20,8 @@ function main(){
case $COMMAND in
"compose")
- compose $2 $3 $4 $5 $6 $7 $8;;
- #IPGW, #IPSUBNET, #I, #IPVES, #IPPNFSIM, #IPFTP, #IPSFTP,
+ compose $2 $3 $4 $5 $6 $7 $8 $9 "${10}" "${11}" ;;
+ #IPGW, #IPSUBNET, #I, #IPVES, #IPPNFSIM, #IPFILESERVER, #PORTSFTP, #PORTFTPS, #IPFTPS, #IPSFTP
"build")
build_image;;
"start")
@@ -64,8 +64,11 @@ function compose(){
export I=$3
export IPVES=$4
export IPPNFSIM=$5
- export IPFTPS=$6
- export IPSFTP=$7
+ export IPFILESERVER=$6
+ export PORTSFTP=$7
+ export PORTFTPS=$8
+ export IPFTPS=$9
+ export IPSFTP=${10}
#will insert $I to distinguish containers, networks properly
#docker compose cannot substitute these, as they are keys, not values.
@@ -78,7 +81,7 @@ function compose(){
set_vsftpd_file_owner
- write_config $IPVES $IPFTPS $IPSFTP $IPPNFSIM
+ write_config $IPVES $IPFILESERVER $PORTSFTP $PORTFTPS $IPPNFSIM
}
@@ -99,9 +102,9 @@ function set_vsftpd_file_owner() {
function write_config(){
#building a YML file for usage in Java
echo "vesip: $1" > config/config.yml
- echo "ipftps: $2" >> config/config.yml
- echo "ipsftp: $3" >> config/config.yml
- echo "ippnfsim: $4" >> config/config.yml
+ echo "ipsftp: $2:$3" >> config/config.yml
+ echo "ipftps: $2:$4" >> config/config.yml
+ echo "ippnfsim: $5" >> config/config.yml
}
function start(){
diff --git a/test/mocks/mass-pnf-sim/pnf-sim-lightweight/src/main/java/org/onap/pnfsimulator/message/MessageProvider.java b/test/mocks/mass-pnf-sim/pnf-sim-lightweight/src/main/java/org/onap/pnfsimulator/message/MessageProvider.java
index d59e82968..839d40269 100644
--- a/test/mocks/mass-pnf-sim/pnf-sim-lightweight/src/main/java/org/onap/pnfsimulator/message/MessageProvider.java
+++ b/test/mocks/mass-pnf-sim/pnf-sim-lightweight/src/main/java/org/onap/pnfsimulator/message/MessageProvider.java
@@ -114,24 +114,6 @@ public class MessageProvider {
JSONArray jsonArrayOfNamedHashMap = new JSONArray();
jsonArrayOfNamedHashMap.put(jsonHashMap);
-
-
- // // notification.put("name", "NAME_DUMMY");
- // JSONObject notification = new JSONObject();
- //
- // notificationParams.ifPresent(jsonObject -> {
- // copyParametersToFields(notification, notificationFields);
- // commonEventHeader.put(DOMAIN, DOMAIN_NOTIFICATION);
- // event.put(NOTIFICATION_FIELDS, notificationFields);
- // });
-
-
- // notificationParams.ifPresent(jsonObject -> {
- // copyParametersToFields(jsonObject.toMap(), notificationFields);
- // commonEventHeader.put(DOMAIN, DOMAIN_NOTIFICATION);
- // event.put(NOTIFICATION_FIELDS, notificationFields);
- // });
-
event.put(COMMON_EVENT_HEADER, commonEventHeader);
JSONObject root = new JSONObject();
root.put(EVENT, event);
@@ -141,7 +123,6 @@ public class MessageProvider {
public JSONObject createOneVesEvent(String xnfUrl, String fileName) {
- String notificationFields;
JSONObject nof = new JSONObject();
nof.put("notificationFieldsVersion", "2.0");
@@ -150,20 +131,20 @@ public class MessageProvider {
nof.put("changeIdentifier", "PM_MEAS_FILES");
JSONObject hm = new JSONObject();
- hm.put("location", xnfUrl.concat(fileName));
+ hm.put("location", "ftpes://".concat(xnfUrl).concat(fileName));
hm.put("fileFormatType", "org.3GPP.32.435#measCollec");
hm.put("fileFormatVersion", "V10");
hm.put("compression", "gzip");
- JSONObject aonh = new JSONObject();
- aonh.put("name", fileName);
+ JSONObject aonhElement = new JSONObject();
+ aonhElement.put("name", fileName);
+ aonhElement.put("hashMap", hm);
- aonh.put("hashMap", hm);
+ JSONArray aonh = new JSONArray();
+ aonh.put(aonhElement);
nof.put("arrayOfNamedHashMap", aonh);
- String nofString = nof.toString();
-
JSONObject ceh = new JSONObject(); // commonEventHandler
ceh.put("startEpochMicrosec", "1551865758690");
ceh.put("sourceId", "val13");
@@ -183,18 +164,23 @@ public class MessageProvider {
JSONObject ihf = new JSONObject(); // internalHeaderFields
ceh.put("internalHeaderFields", ihf);
+ JSONObject eventContent = new JSONObject();
+ eventContent.put("commonEventHeader", ceh);
+ eventContent.put("notificationFields", nof);
+
+
JSONObject event = new JSONObject();
- event.put("commonEventHeader", ceh);
- event.put("notificationFields", nof);
+ event.put("event", eventContent);
- System.out.println("event: ");
+ System.out.println("VES messages to be sent: ");
System.out.println(event.toString());
return event;
// @formatter:off
/*
- {
+ {
+ "event": {
"commonEventHeader": { <== "ceh"
"startEpochMicrosec": "1551865758690",
"sourceId": "val13",
@@ -217,21 +203,21 @@ public class MessageProvider {
"notificationFieldsVersion": "2.0",
"changeType": "FileReady",
"changeIdentifier": "PM_MEAS_FILES",
- "arrayOfNamedHashMap": { <== "aonh"
- "name": "A20161224.1030-1045.bin.gz",
- "hashMap": { <== "hm"
- "location": "ftpes://192.169.0.1:22/ftp/rop/A20161224.1030-1045.bin.gz",
- "fileFormatType": "org.3GPP.32.435#measCollec",
- "fileFormatVersion": "V10",
- "compression": "gzip"
+ "arrayOfNamedHashMap": [ <== "aonh"
+ { <== "aonhElement"
+ "name": "A20161224.1030-1045.bin.gz",
+ "hashMap": { <== "hm"
+ "location": "ftpes://192.169.0.1:22/ftp/rop/A20161224.1030-1045.bin.gz",
+ "fileFormatType": "org.3GPP.32.435#measCollec",
+ "fileFormatVersion": "V10",
+ "compression": "gzip"
+ }
}
- }
+ ]
}
}
-
- */
+ }
+ */
// @formatter:on
-
}
-
}
diff --git a/test/security/check_for_jdwp.sh b/test/security/check_for_jdwp.sh
new file mode 100755
index 000000000..7bcbade64
--- /dev/null
+++ b/test/security/check_for_jdwp.sh
@@ -0,0 +1,93 @@
+#!/usr/bin/env bash
+
+# COPYRIGHT NOTICE STARTS HERE
+#
+# Copyright 2019 Samsung Electronics Co., Ltd.
+#
+# 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.
+#
+# COPYRIGHT NOTICE ENDS HERE
+
+# Check all ports exposed by pods to internal network and look for
+# open JDWP ports
+#
+# Dependencies:
+# kubectl + config
+# netcat
+#
+# Return value: Number of discovered JDWP ports
+# Output: List of pods and exposing JDWP interface
+#
+
+if [ "$#" -lt 1 ]; then
+ echo "Usage: $0 <k8s-namespace>"
+ exit 1
+fi
+
+K8S_NAMESPACE=$1
+LOCAL_PORT=12543
+
+list_pods() {
+ kubectl get po --namespace=$K8S_NAMESPACE | grep Running | awk '{print $1}' | grep -v NAME
+}
+
+do_jdwp_handshake() {
+ local ip="127.0.0.1"
+ local port=$1
+ local jdwp_challenge="JDWP-Handshake\n"
+ local jdwp_response="JDWP-Handshake"
+
+ local response=`nc $ip $port <<<$jdwp_challenge`
+ if [[ $response == *"$jdwp_response"* ]]; then
+ return 0
+ fi
+
+ return 1
+}
+# get open ports from procfs as netstat is not always available
+get_open_ports_on_pod() {
+ local pod=$1
+ local open_ports_hex=`kubectl exec --namespace=$K8S_NAMESPACE $pod cat /proc/net/tcp 2>/dev/null| grep -v "local_address" | awk '{ print $2" "$4 }' | grep '0A$' | tr ":" " " | awk '{ print $2 }' | sort | uniq`
+ for hex_port in $open_ports_hex; do
+ echo $((16#$hex_port))
+ done
+}
+
+N_PORTS=0
+
+# go through all pods
+for pod in `list_pods`; do
+ open_ports=`get_open_ports_on_pod $pod`
+ # if there is no open ports just go to next pod
+ if [ -z "$open_ports" ]; then
+ continue
+ fi
+
+ # let's setup a proxy and check every open port
+ for port in $open_ports; do
+ # run proxy
+ kubectl port-forward --namespace=$K8S_NAMESPACE $pod $LOCAL_PORT:$port &>/dev/null &
+ sleep 1
+ proxy_pid=$!
+
+ do_jdwp_handshake $LOCAL_PORT
+ if [ $? -eq 0 ]; then
+ echo $pod $port
+ ((++N_PORTS))
+ fi
+ kill $proxy_pid 2>/dev/null
+ wait $proxy_pid 2>/dev/null
+ done
+done
+
+exit $N_PORTS