summaryrefslogtreecommitdiffstats
path: root/pods
diff options
context:
space:
mode:
Diffstat (limited to 'pods')
-rw-r--r--pods/__init__.py19
-rw-r--r--pods/papi/__init__.py19
-rw-r--r--pods/papi/papi.py143
-rw-r--r--pods/pod/__init__.py18
-rw-r--r--pods/pod/pod.py63
5 files changed, 262 insertions, 0 deletions
diff --git a/pods/__init__.py b/pods/__init__.py
new file mode 100644
index 00000000..e3ce18d9
--- /dev/null
+++ b/pods/__init__.py
@@ -0,0 +1,19 @@
+# Copyright 2020 Spirent Communications
+#
+# 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.
+
+"""Package for POD wrappers for use with VSPERF.
+
+This package contains an interface the VSPERF core uses for controlling
+PODs and POD-specific implementation modules of this interface.
+"""
diff --git a/pods/papi/__init__.py b/pods/papi/__init__.py
new file mode 100644
index 00000000..16760b86
--- /dev/null
+++ b/pods/papi/__init__.py
@@ -0,0 +1,19 @@
+# Copyright 2020 Spirent Communications
+#
+# 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.
+
+"""Package for POD wrappers for use with VSPERF.
+
+This package contains an implementation of the interface the VSPERF core
+uses for controlling PODs using Kubernetes Python-API (PAPI)
+"""
diff --git a/pods/papi/papi.py b/pods/papi/papi.py
new file mode 100644
index 00000000..5a21f1d6
--- /dev/null
+++ b/pods/papi/papi.py
@@ -0,0 +1,143 @@
+# Copyright 2020 University Of Delhi.
+#
+# 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.
+
+
+"""
+Automation of Pod Deployment with Kubernetes Python API
+"""
+
+# import os
+import logging
+import json
+import time
+import yaml
+from kubernetes import client, config
+from kubernetes.client.rest import ApiException
+
+from conf import settings as S
+from pods.pod.pod import IPod
+
+class Papi(IPod):
+ """
+ Class for controlling the pod through PAPI
+ """
+
+ def __init__(self):
+ """
+ Initialisation function.
+ """
+ #super(Papi, self).__init__()
+ super().__init__()
+
+ self._logger = logging.getLogger(__name__)
+ self._sriov_config = None
+ self._sriov_config_ns = None
+ config.load_kube_config(S.getValue('K8S_CONFIG_FILEPATH'))
+
+ def create(self):
+ """
+ Creation Process
+ """
+ # create vswitchperf namespace
+ api = client.CoreV1Api()
+ namespace = 'default'
+ #namespace = 'vswitchperf'
+ # replace_namespace(api, namespace)
+
+ # sriov configmap
+ if S.getValue('PLUGIN') == 'sriov':
+ configmap = load_manifest(S.getValue('CONFIGMAP_FILEPATH'))
+ self._sriov_config = configmap['metadata']['name']
+ self._sriov_config_ns = configmap['metadata']['namespace']
+ api.create_namespaced_config_map(self._sriov_config_ns, configmap)
+
+
+ # create nad(network attachent definitions)
+ group = 'k8s.cni.cncf.io'
+ version = 'v1'
+ kind_plural = 'network-attachment-definitions'
+ api = client.CustomObjectsApi()
+
+ for nad_filepath in S.getValue('NETWORK_ATTACHMENT_FILEPATH'):
+ nad_manifest = load_manifest(nad_filepath)
+
+ try:
+ response = api.create_namespaced_custom_object(group, version, namespace,
+ kind_plural, nad_manifest)
+ self._logger.info(str(response))
+ self._logger.info("Created Network Attachment Definition: %s", nad_filepath)
+ except ApiException as err:
+ raise Exception from err
+
+ #create pod workloads
+ pod_manifest = load_manifest(S.getValue('POD_MANIFEST_FILEPATH'))
+ api = client.CoreV1Api()
+
+ try:
+ response = api.create_namespaced_pod(namespace, pod_manifest)
+ self._logger.info(str(response))
+ self._logger.info("Created POD %d ...", self._number)
+ except ApiException as err:
+ raise Exception from err
+
+ time.sleep(12)
+
+ def terminate(self):
+ """
+ Cleanup Process
+ """
+ #self._logger.info(self._log_prefix + "Cleaning vswitchperf namespace")
+ self._logger.info("Terminating Pod")
+ api = client.CoreV1Api()
+ # api.delete_namespace(name="vswitchperf", body=client.V1DeleteOptions())
+
+ if S.getValue('PLUGIN') == 'sriov':
+ api.delete_namespaced_config_map(self._sriov_config, self._sriov_config_ns)
+
+
+def load_manifest(filepath):
+ """
+ Reads k8s manifest files and returns as string
+
+ :param str filepath: filename of k8s manifest file to read
+
+ :return: k8s resource definition as string
+ """
+ with open(filepath) as handle:
+ data = handle.read()
+
+ try:
+ manifest = json.loads(data)
+ except ValueError:
+ try:
+ manifest = yaml.safe_load(data)
+ except yaml.parser.ParserError as err:
+ raise Exception from err
+
+ return manifest
+
+def replace_namespace(api, namespace):
+ """
+ Creates namespace if does not exists
+ """
+ namespaces = api.list_namespace()
+ for nsi in namespaces.items:
+ if namespace == nsi.metadata.name:
+ api.delete_namespace(name=namespace,
+ body=client.V1DeleteOptions())
+ break
+
+ time.sleep(0.5)
+ api.create_namespace(client.V1Namespace(
+ metadata=client.V1ObjectMeta(name=namespace)))
diff --git a/pods/pod/__init__.py b/pods/pod/__init__.py
new file mode 100644
index 00000000..b91706e2
--- /dev/null
+++ b/pods/pod/__init__.py
@@ -0,0 +1,18 @@
+# Copyright 2020 Spirent Communications
+#
+# 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.
+
+"""POD interface and helpers.
+"""
+
+import pods
diff --git a/pods/pod/pod.py b/pods/pod/pod.py
new file mode 100644
index 00000000..c25744d2
--- /dev/null
+++ b/pods/pod/pod.py
@@ -0,0 +1,63 @@
+# Copyright 2020 Spirent Communications, University Of Delhi.
+#
+# 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.
+
+"""
+Interface for POD
+"""
+
+#import time
+#import pexpect
+from tools import tasks
+
+class IPod(tasks.Process):
+ """
+ Interface for POD
+
+ Inheriting from Process helps in managing system process.
+ execute a command, wait, kill, etc.
+ """
+ _number_pods = 0
+
+ def __init__(self):
+ """
+ Initialization Method
+ """
+ self._number = IPod._number_pods
+ self._logger.debug('Initializing %s. Pod with index %s',
+ self._number + 1, self._number)
+ IPod._number_pods = IPod._number_pods + 1
+ self._log_prefix = 'pod_%d_cmd : ' % self._number
+ # raise NotImplementedError()
+
+ def create(self):
+ """
+ Start the Pod
+ """
+ raise NotImplementedError()
+
+
+ def terminate(self):
+ """
+ Stop the Pod
+ """
+ raise NotImplementedError()
+
+ @staticmethod
+ def reset_pod_counter():
+ """
+ Reset internal POD counter
+
+ This method is static
+ """
+ IPod._number_pods = 0