1 #!/usr/bin/env python2.7
4 ## Copyright (c) 2019 Intel Corporation
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
10 ## http://www.apache.org/licenses/LICENSE-2.0
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.
22 from kubernetes import client, config
24 from sshclient import SSHClient
27 """Class which represents test pods.
28 For example with traffic gen, forward/swap applications, etc
35 _namespace = "default"
36 _nodeSelector_hostname = None
47 def __init__(self, name, namespace = "default", logger_name = "k8srapid"):
48 self._log = logging.getLogger(logger_name)
51 self._namespace = namespace
52 self._ssh_client = SSHClient(logger_name = logger_name)
55 """Destroy POD. Do a cleanup.
57 if self._ssh_client is not None:
58 self._ssh_client.disconnect()
60 def create_from_yaml(self, file_name):
61 """Load POD description from yaml file.
63 with open(path.join(path.dirname(__file__), file_name)) as yaml_file:
64 self.body = yaml.safe_load(yaml_file)
66 self.body["metadata"]["name"] = self._name
68 if (self._nodeSelector_hostname is not None):
69 if ("nodeSelector" not in self.body["spec"]):
70 self.body["spec"]["nodeSelector"] = {}
71 self.body["spec"]["nodeSelector"]["kubernetes.io/hostname"] = self._nodeSelector_hostname
72 self._log.debug("Creating POD, body:\n%s" % self.body)
75 self.k8s_CoreV1Api.create_namespaced_pod(body = self.body,
76 namespace = self._namespace)
77 except client.rest.ApiException as e:
78 self._log.error("Couldn't create POD %s!\n%s\n" % (self._name, e))
81 """Terminate POD. Close SSH connection.
83 if self._ssh_client is not None:
84 self._ssh_client.disconnect()
87 self.k8s_CoreV1Api.delete_namespaced_pod(name = self._name,
88 namespace = self._namespace)
89 except client.rest.ApiException as e:
90 if e.reason != "Not Found":
91 self._log.error("Couldn't delete POD %s!\n%s\n" % (self._name, e.reason))
93 def update_admin_ip(self):
94 """Check for admin IP address assigned by k8s.
97 pod = self.k8s_CoreV1Api.read_namespaced_pod_status(name = self._name, namespace = self._namespace)
98 self._admin_ip = pod.status.pod_ip
99 except client.rest.ApiException as e:
100 self._log.error("Couldn't update POD %s admin IP!\n%s\n" % (self._name, e))
102 def wait_for_start(self):
103 """Wait for POD to start.
105 self._log.info("Waiting for POD %s to start..." % self._name)
108 if (self._last_status == "Running" or self._last_status == "Failed"
109 or self._last_status == "Unknown"):
114 self.update_admin_ip()
116 return self._last_status
118 def ssh_run_cmd(self, cmd):
119 """Execute command for POD via SSH connection.
120 SSH credentials should be configured before use of this function.
122 self._ssh_client.run_cmd(cmd)
127 def get_admin_ip(self):
128 return self._admin_ip
133 def get_dp_mac(self):
134 return self._sriov_vf_mac
136 def get_dp_pci_dev(self):
137 return self._sriov_vf
142 def get_status(self):
143 """Get current status fro the pod.
146 pod = self.k8s_CoreV1Api.read_namespaced_pod_status(name = self._name,
147 namespace = self._namespace)
148 except client.rest.ApiException as e:
149 self._log.error("Couldn't read POD %s status!\n%s\n" % (self._name, e))
151 self._last_status = pod.status.phase
152 return self._last_status
154 def get_sriov_dev_mac(self):
155 """Get assigned by k8s SRIOV network device plugin SRIOV VF devices.
156 Return 0 in case of sucessfull configuration.
159 self._log.info("Checking assigned SRIOV VF for POD %s" % self._name)
160 ret = self._ssh_client.run_cmd("cat /opt/rapid/k8s_sriov_device_plugin_envs")
162 self._log.error("Failed to check assigned SRIOV VF!"
163 "Error %s" % self._ssh_client.get_error())
166 cmd_output = self._ssh_client.get_output().decode("utf-8").rstrip()
167 self._log.debug("Environment variable %s" % cmd_output)
169 # Parse environment variable
170 cmd_output = cmd_output.split("=")[1]
171 self._sriov_vf = cmd_output.split(",")[0]
172 self._log.debug("Using first SRIOV VF %s" % self._sriov_vf)
174 self._log.info("Getting MAC address for assigned SRIOV VF %s" % self._sriov_vf)
175 self._ssh_client.run_cmd("sudo /opt/rapid/port_info_app -n 4 -w %s" % self._sriov_vf)
177 self._log.error("Failed to get MAC address!"
178 "Error %s" % self._ssh_client.get_error())
182 cmd_output = self._ssh_client.get_output().decode("utf-8").rstrip()
183 self._log.debug(cmd_output)
184 cmd_output = cmd_output.splitlines()
185 for line in cmd_output:
186 if line.startswith("Port 0 MAC: "):
187 self._sriov_vf_mac = line[12:]
189 self._log.debug("MAC %s" % self._sriov_vf_mac)
191 def set_dp_ip(self, dp_ip):
194 def set_id(self, pod_id):
197 def set_nodeselector(self, hostname):
198 """Set hostname on which POD will be executed.
200 self._nodeSelector_hostname = hostname
202 def set_ssh_credentials(self, user, rsa_private_key):
203 """Set SSH credentials for the SSH connection to the POD.
205 self.update_admin_ip()
206 self._ssh_client.set_credentials(ip = self._admin_ip,
208 rsa_private_key = rsa_private_key)