Nodeport service and modified ssh and socket ports 44/74644/1
authorLuc Provoost <luc.provoost@gmail.com>
Sat, 9 Nov 2024 14:55:26 +0000 (15:55 +0100)
committerLuc Provoost <luc.provoost@gmail.com>
Sat, 9 Nov 2024 14:55:26 +0000 (15:55 +0100)
We support now the use of K8s Nodeport services and non standard ssh and
prox socket ports.
In order to use Nodeport service, you need to specify the name of the
service for each prox pod in the rapid.pods file.

Signed-off-by: Luc Provoost <luc.provoost@gmail.com>
Change-Id: I2873b7e22fee042a14b575e772267a9128b7c4f2

VNFs/DPPD-PROX/helper-scripts/rapid/prox_ctrl.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_k8s_deployment.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_k8s_pod.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_machine.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_parser.py
VNFs/DPPD-PROX/helper-scripts/rapid/rapid_sshclient.py

index 8754ebc..e2a634f 100644 (file)
@@ -29,14 +29,17 @@ from rapid_log import RapidLog
 from rapid_sshclient import SSHClient
 
 class prox_ctrl(object):
-    def __init__(self, ip, key=None, user=None, password = None):
+    def __init__(self, ip, key=None, user=None, password = None, \
+            admin_port = 22, socket_port = 8474):
         self._ip   = ip
+        self._admin_port = admin_port
+        self._socket_port = socket_port
         self._key  = key
         self._user = user
         self._password = password
         self._proxsock = []
         self._sshclient = SSHClient(ip = ip, user = user, password = password,
-                rsa_private_key = key, timeout = None)
+                rsa_private_key = key, timeout = None, ssh_port = admin_port)
 
     def ip(self):
         return self._ip
@@ -65,8 +68,8 @@ class prox_ctrl(object):
 
     def connect_socket(self):
         attempts = 1
-        RapidLog.debug("Trying to connect to PROX (just launched) on %s, \
-                attempt: %d" % (self._ip, attempts))
+        RapidLog.debug("Trying to connect to PROX (just launched) on %s:%d, \
+                attempt: %d" % (self._ip, self._socket_port, attempts))
         sock = None
         while True:
             sock = self.prox_sock()
@@ -74,11 +77,11 @@ class prox_ctrl(object):
                 break
             attempts += 1
             if attempts > 20:
-                RapidLog.exception("Failed to connect to PROX on %s after %d \
-                        attempts" % (self._ip, attempts))
+                RapidLog.exception("Failed to connect to PROX on %s:%d after %d \
+                        attempts" % (self._ip, self._socket_port, attempts))
             time.sleep(2)
-            RapidLog.debug("Trying to connect to PROX (just launched) on %s, \
-                    attempt: %d" % (self._ip, attempts))
+            RapidLog.debug("Trying to connect to PROX (just launched) on %s:%d, \
+                    attempt: %d" % (self._ip, self._socket_port, attempts))
         RapidLog.info("Connected to PROX on %s" % self._ip)
         return sock
 
@@ -90,13 +93,13 @@ class prox_ctrl(object):
         self._sshclient.run_cmd(command)
         return self._sshclient.get_output()
 
-    def prox_sock(self, port=8474):
+    def prox_sock(self):
         """Connect to the PROX instance on remote system.
         Return a prox_sock object on success, None on failure.
         """
         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         try:
-            sock.connect((self._ip, port))
+            sock.connect((self._ip, self._socket_port))
             prox = prox_sock(sock)
             self._proxsock.append(prox)
             return prox
index 1d1112f..66ebfeb 100644 (file)
@@ -145,7 +145,15 @@ class K8sDeployment:
             else:
                 pod_dp_subnet = "24"
 
-            pod = Pod(pod_name, self._namespace)
+            # Search for POD nodeport service
+            if self._create_config.has_option("POD%d" % i,
+                                              "nodeport"):
+                pod_nodeport = self._create_config.get(
+                    "POD%d" % i, "nodeport")
+            else:
+                pod_nodeport = None
+
+            pod = Pod(pod_name, pod_nodeport, self._namespace)
             pod.set_nodeselector(pod_nodeselector_hostname)
             pod.set_spec_file_name(pod_spec_file_name)
             pod.set_dp_ip(pod_dp_ip)
@@ -209,6 +217,10 @@ class K8sDeployment:
             self._runtime_config.add_section("M%d" % pod.get_id())
             self._runtime_config.set("M%d" % pod.get_id(),
                                      "admin_ip", pod.get_admin_ip())
+            self._runtime_config.set("M%d" % pod.get_id(),
+                                     "admin_port", pod.get_admin_port())
+            self._runtime_config.set("M%d" % pod.get_id(),
+                                     "socket_port", pod.get_socket_port())
             self._runtime_config.set("M%d" % pod.get_id(),
                                      "dp_mac1", pod.get_dp_mac())
             self._runtime_config.set("M%d" % pod.get_id(),
index beaedd6..1bf715a 100644 (file)
@@ -43,14 +43,18 @@ class Pod:
 
     _sriov_vf = None
     _sriov_vf_mac = None
+    _ssh_port = 22
+    _socket_port = 8474
 
-    def __init__(self, name, namespace = "default", logger_name = "k8srapid"):
+    def __init__(self, name, pod_nodeport = None, namespace = "default",
+            logger_name = "k8srapid"):
         self._log = logging.getLogger(logger_name)
 
         self._name = name
         self._namespace = namespace
         self._ssh_client = SSHClient(logger_name = logger_name)
         self.qat_vf = []
+        self._pod_nodeport = pod_nodeport
 
     def __del__(self):
         """Destroy POD. Do a cleanup.
@@ -66,6 +70,7 @@ class Pod:
             self.body = yaml.safe_load(yaml_file)
 
             self.body["metadata"]["name"] = self._name
+            self.body["metadata"]["labels"] = {'app': self._pod_nodeport}
 
             if (self._nodeSelector_hostname is not None):
                 if ("nodeSelector" not in self.body["spec"]):
@@ -98,8 +103,17 @@ class Pod:
         """Check for admin IP address assigned by k8s.
         """
         try:
-            pod = self.k8s_CoreV1Api.read_namespaced_pod_status(name = self._name, namespace = self._namespace)
-            self._admin_ip = pod.status.pod_ip
+            if self._pod_nodeport:
+                service= self.k8s_CoreV1Api.read_namespaced_service_status(name = self._pod_nodeport, namespace = self._namespace)
+                self._admin_ip = service.spec.cluster_ip
+                for service_port in service.spec.ports:
+                    if service_port.name == 'control-port':
+                        self._ssh_port = service_port.node_port
+                    if service_port.name == 'socket-port':
+                        self._socket_port = service_port.node_port
+            else:
+                pod = self.k8s_CoreV1Api.read_namespaced_pod_status(name = self._name, namespace = self._namespace)
+                self._admin_ip = pod.status.pod_ip
         except client.rest.ApiException as e:
             self._log.error("Couldn't update POD %s admin IP!\n%s\n" % (self._name, e))
 
@@ -131,6 +145,12 @@ class Pod:
     def get_admin_ip(self):
         return self._admin_ip
 
+    def get_admin_port(self):
+        return self._ssh_port
+
+    def get_socket_port(self):
+        return self._socket_port
+
     def get_dp_ip(self):
         return self._dp_ip
 
@@ -261,4 +281,5 @@ class Pod:
         self.update_admin_ip()
         self._ssh_client.set_credentials(ip = self._admin_ip,
                                          user = user,
-                                         rsa_private_key = rsa_private_key)
+                                         rsa_private_key = rsa_private_key,
+                                         ssh_port = self._ssh_port)
index 47f858d..b95f4ff 100644 (file)
@@ -30,6 +30,8 @@ class RapidMachine(object):
             machine_params, configonly):
         self.name = machine_params['name']
         self.ip = machine_params['admin_ip']
+        self.admin_port = machine_params['admin_port']
+        self.socket_port = machine_params['socket_port']
         self.key = key
         self.user = user
         self.password = password
@@ -148,7 +150,7 @@ class RapidMachine(object):
                 RapidLog.debug('devbind.sh running for port {} on {} {}'.format(index, self.name, result))
 
     def generate_lua(self, appendix = ''):
-        self.LuaFileName = 'parameters-{}.lua'.format(self.ip)
+        self.LuaFileName = 'parameters-{}-{}.lua'.format(self.ip, self.admin_port)
         with open(self.LuaFileName, "w") as LuaFile:
             LuaFile.write('require "helper"\n')
             LuaFile.write('name="%s"\n'% self.name)
@@ -210,7 +212,7 @@ class RapidMachine(object):
     def start_prox(self, autostart=''):
         if self.machine_params['prox_socket']:
             self._client = prox_ctrl(self.ip, self.key, self.user,
-                    self.password)
+                    self.password, self.admin_port, self.socket_port)
             self._client.test_connection()
             if self.vim in ['OpenStack']:
                 self.devbind()
index 143323b..8583479 100644 (file)
@@ -156,7 +156,10 @@ class RapidConfigParser(object):
             section = 'M%d'%machine_index[test_machine-1]
             options = config.options(section)
             for option in options:
-                machine[option] = config.get(section, option)
+                if option in ['admin_port','socket_port']:
+                    machine[option] = int(config.get(section, option))
+                else:
+                    machine[option] = config.get(section, option)
             machines.append(dict(machine))
         for machine in machines:
             dp_ports = []
index d8aeacc..e519ebd 100644 (file)
@@ -26,6 +26,7 @@ class SSHClient:
     _ip = None
     _user = None
     _rsa_private_key = None
+    _ssh_port = 22
     _timeout = None
     _ssh = None
     _connected = False
@@ -34,8 +35,9 @@ class SSHClient:
     _error = None
 
     def __init__(self, ip=None, user=None, rsa_private_key=None, timeout=15,
-            logger_name=None, password = None):
+            logger_name=None, password = None, ssh_port = 22):
         self._ip = ip
+        self._ssh_port = ssh_port
         self._user = user
         self._password = password
         self._rsa_private_key = rsa_private_key
@@ -46,11 +48,12 @@ class SSHClient:
 
         self._connected = False
 
-    def set_credentials(self, ip, user, rsa_private_key, password = None):
+    def set_credentials(self, ip, user, rsa_private_key, password = None, ssh_port = 22):
         self._ip = ip
         self._user = user
         self._password = password
         self._rsa_private_key = rsa_private_key
+        self._ssh_port = ssh_port
 
     def connect(self):
 
@@ -76,7 +79,7 @@ class SSHClient:
 
         try:
             self._ssh.connect(hostname = self._ip, username = self._user,
-                    password = self._password, pkey = private_key)
+                    password = self._password, pkey = private_key, port = self._ssh_port)
         except Exception as e:
             if (self._log is not None):
                 self._log.error("Failed to connect to the host! IP %s, user %s, RSA private key %s\n%s"