2 ## Copyright (c) 2019-2020 Intel Corporation
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
8 ## http://www.apache.org/licenses/LICENSE-2.0
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.
18 from kubernetes import client, config
23 import ConfigParser as configparser
25 from logging import handlers
27 from rapid_k8s_pod import Pod
30 """Deployment class to create containers for test execution in Kubernetes
33 LOG_FILE_NAME = "createrapidk8s.log"
34 SSH_PRIVATE_KEY = "./rapid_rsa_key"
37 POD_YAML_TEMPLATE_FILE_NAME = "pod-rapid.yaml"
41 _runtime_config = None
42 _total_number_of_pods = 0
43 _namespace = "rapid-testing"
48 self._log = logging.getLogger("k8srapid")
49 self._log.setLevel(logging.DEBUG)
51 console_formatter = logging.Formatter("%(message)s")
52 console_handler = logging.StreamHandler(sys.stdout)
53 console_handler.setLevel(logging.DEBUG)
54 console_handler.setFormatter(console_formatter)
56 file_formatter = logging.Formatter("%(asctime)s - "
59 file_handler = logging.handlers.RotatingFileHandler(self.LOG_FILE_NAME,
61 file_handler.setLevel(logging.DEBUG)
62 file_handler.setFormatter(file_formatter)
64 self._log.addHandler(file_handler)
65 self._log.addHandler(console_handler)
67 # Initialize k8s plugin
69 config.load_kube_config()
71 config.load_incluster_config()
73 Pod.k8s_CoreV1Api = client.CoreV1Api()
75 def load_create_config(self, config_file_name):
76 """Read and parse configuration file for the test environment.
78 self._log.info("Loading configuration file %s", config_file_name)
79 self._create_config = configparser.RawConfigParser()
81 self._create_config.read(config_file_name)
82 except Exception as e:
83 self._log.error("Failed to read config file!\n%s\n" % e)
86 # Now parse config file content
87 # Parse [DEFAULT] section
88 if self._create_config.has_option("DEFAULT", "total_number_of_pods"):
89 self._total_number_of_pods = self._create_config.getint(
90 "DEFAULT", "total_number_of_pods")
92 self._log.error("No option total_number_of_pods in DEFAULT section")
95 self._log.debug("Total number of pods %d" % self._total_number_of_pods)
97 if self._create_config.has_option("DEFAULT", "namespace"):
98 self._namespace = self._create_config.get(
99 "DEFAULT", "namespace")
101 self._log.error("No option namespace in DEFAULT section")
104 self._log.debug("Using namespace %s" % self._total_number_of_pods)
106 # Parse [PODx] sections
107 for i in range(1, int(self._total_number_of_pods) + 1):
108 # Search for POD name
109 if self._create_config.has_option("POD%d" % i,
111 pod_name = self._create_config.get(
114 pod_name = "prox-pod-%d" % i
116 # Search for POD hostname
117 if self._create_config.has_option("POD%d" % i,
118 "nodeSelector_hostname"):
119 pod_nodeselector_hostname = self._create_config.get(
120 "POD%d" % i, "nodeSelector_hostname")
122 pod_nodeselector_hostname = None
124 # Search for POD spec
125 if self._create_config.has_option("POD%d" % i,
127 pod_spec_file_name = self._create_config.get(
128 "POD%d" % i, "spec_file_name")
130 pod_spec_file_name = K8sDeployment.POD_YAML_TEMPLATE_FILE_NAME
132 # Search for POD dataplane static IP
133 if self._create_config.has_option("POD%d" % i,
135 pod_dp_ip = self._create_config.get(
136 "POD%d" % i, "dp_ip")
140 # Search for POD dataplane subnet
141 if self._create_config.has_option("POD%d" % i,
143 pod_dp_subnet = self._create_config.get(
144 "POD%d" % i, "dp_subnet")
148 pod = Pod(pod_name, self._namespace)
149 pod.set_nodeselector(pod_nodeselector_hostname)
150 pod.set_spec_file_name(pod_spec_file_name)
151 pod.set_dp_ip(pod_dp_ip)
152 pod.set_dp_subnet(pod_dp_subnet)
155 # Add POD to the list of PODs which need to be created
156 self._pods.append(pod)
160 def create_pods(self):
161 """ Create test PODs and wait for them to start.
162 Collect information for tests to run.
164 self._log.info("Creating PODs...")
166 # Create PODs using template from yaml file
167 for pod in self._pods:
168 self._log.info("Creating POD %s...", pod.get_name())
169 pod.create_from_yaml()
171 # Wait for PODs to start
172 for pod in self._pods:
175 # Collect information from started PODs for test execution
176 for pod in self._pods:
177 pod.set_ssh_credentials(K8sDeployment.SSH_USER, K8sDeployment.SSH_PRIVATE_KEY)
178 pod.get_sriov_dev_mac()
181 def save_runtime_config(self, config_file_name):
182 self._log.info("Saving config %s for runrapid script...",
184 self._runtime_config = configparser.RawConfigParser()
187 # self._runtime_config.set("DEFAULT",
188 # "total_number_of_test_machines",
189 # self._total_number_of_pods)
192 self._runtime_config.add_section("ssh")
193 self._runtime_config.set("ssh",
195 K8sDeployment.SSH_PRIVATE_KEY)
196 self._runtime_config.set("ssh",
198 K8sDeployment.SSH_USER)
201 self._runtime_config.add_section("rapid")
202 self._runtime_config.set("rapid",
203 "total_number_of_machines",
204 self._total_number_of_pods)
206 # Export information about each pod
208 for pod in self._pods:
209 self._runtime_config.add_section("M%d" % pod.get_id())
210 self._runtime_config.set("M%d" % pod.get_id(),
211 "admin_ip", pod.get_admin_ip())
212 self._runtime_config.set("M%d" % pod.get_id(),
213 "dp_mac1", pod.get_dp_mac())
214 self._runtime_config.set("M%d" % pod.get_id(),
215 "dp_pci_dev", pod.get_dp_pci_dev())
216 if (pod.get_qat_pci_dev()):
217 for qat_index, qat_device in enumerate(pod.get_qat_pci_dev()):
218 self._runtime_config.set("M%d" % pod.get_id(),
219 "qat_pci_dev%d" % qat_index, qat_device)
220 self._runtime_config.set("M%d" % pod.get_id(),
221 "dp_ip1", pod.get_dp_ip() + "/" +
225 self._runtime_config.add_section("Varia")
226 self._runtime_config.set("Varia",
230 # Write runtime config file
231 with open(config_file_name, "w") as file:
232 self._runtime_config.write(file)
234 def delete_pods(self):
235 for pod in self._pods: