Automated deployment of helm charts with python 40/72940/7
authorshreyagupta30 <shreyagupta3011@gmail.com>
Mon, 27 Sep 2021 09:05:36 +0000 (14:35 +0530)
committershreyagupta30 <shreyagupta3011@gmail.com>
Mon, 11 Oct 2021 17:46:53 +0000 (23:16 +0530)
This patch adds demo helm charts and a python script that automatically deploys any helm chart of user's choice and print all the useful information about the chart.

Signed-off-by: Shreya Gupta <shreyagupta3011@gmail.com>
Change-Id: I06e3a8012602e09f601f70def386ef267c870e94

21 files changed:
.gitignore
docs/k8s/helm.rst [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/mynet.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/pod.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/proxchart/Chart.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/proxchart/templates/daemonset.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/proxchart/templates/deployment.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/proxchart/templates/service.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/proxchart/values.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/testpmdchart/Chart.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/testpmdchart/templates/daemonset.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/testpmdchart/templates/deployment.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/testpmdchart/templates/service.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/testpmdchart/values.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/trexchart/Chart.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/trexchart/templates/daemonset.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/trexchart/templates/deployment.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/trexchart/templates/service.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/charts/trexchart/values.yaml [new file with mode: 0644]
tools/k8s/app-deployment/helm/pyscript/Pipfile [new file with mode: 0644]
tools/k8s/app-deployment/helm/pyscript/main.py [new file with mode: 0644]

index c162c94..b8a4aa6 100644 (file)
@@ -77,3 +77,4 @@ tags
 !/src/l2fwd/Makefile
 
 docs/_build/*
+.DS_Store
diff --git a/docs/k8s/helm.rst b/docs/k8s/helm.rst
new file mode 100644 (file)
index 0000000..add15a7
--- /dev/null
@@ -0,0 +1,137 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. (c) Anuket, Spirent, AT&T, Ixia  and others.
+
+.. Anuket ViNePerf Documentation master file.
+
+============================================================
+Automated deployment of helm charts with python
+============================================================
+
+********************
+Directory Structure
+********************
+.. code-block:: console
+
+
+    ├── charts
+    │   ├── mynet.yaml
+    │   ├── pod.yaml
+    │   ├── proxchart
+    │   │   ├── Chart.yaml
+    │   │   ├── templates
+    │   │   │   ├── daemonset.yaml
+    │   │   │   ├── deployment.yaml
+    │   │   │   └── service.yaml
+    │   │   └── values.yaml
+    │   ├── testpmdchart
+    │   │   ├── Chart.yaml
+    │   │   ├── templates
+    │   │   │   ├── daemonset.yaml
+    │   │   │   ├── deployment.yaml
+    │   │   │   └── service.yaml
+    │   │   └── values.yaml
+    │   └── trexchart
+    │       ├── Chart.yaml
+    │       ├── templates
+    │       │   ├── daemonset.yaml
+    │       │   ├── deployment.yaml
+    │       │   └── service.yaml
+    │       └── values.yaml
+    └── pyscript
+        ├── Pipfile
+        ├── Pipfile.lock
+        └── main.py
+
+
+***************
+Using the tool
+***************
+
+Charts folder contains three different charts - ``proxchart, testpmd chart and trex chart``. Any of the one can be used for testing.
+Pyscript folder contains ``main.py`` - the main python script that depploys the helm chart of user's choice and returns important configuration of the charts, such as PodIP, Cluster IP, Interface IPs etc.
+
+************************
+Important Configurations
+************************
+
+In order to run the python script, we need to install Pipenv to create virtual environment.
+
+Steps:
+
+1. Install
+
+.. code-block:: console
+
+    pip install --user pipenv
+
+2. To activate the environment
+
+.. code-block:: console
+
+    pipenv shell
+
+The last command will automatically read Pipfile.lock and will create an virtual environment.
+
+Once this configuration is done. We can move on to run our python script.
+
+*************************************************
+Procedure to automatically deploy the helm chart
+*************************************************
+
+Steps:
+
+1. After activating your virtual environment, run the ``main.py``.
+
+.. code-block:: console
+
+    python main.python
+
+2. Enter the location of the chart you want to deploy.
+
+For example, lets deploy proxchart
+
+.. code-block:: console
+
+    Enter the location of helm chart: ../charts/proxchart
+
+3. The last command will execute the entire ``main.py`` and will return all the required information about the chart.
+
+*******
+Output
+*******
+
+.. code-block:: console
+
+    Status of helm charts
+
+    NAME       NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
+    proxchart  default         1               2021-09-27 13:22:21.864816 +0530 IST    deployed        proxchart-0.1.0 1.0
+    ----------------------------------------------------------------------------------------------------
+
+    POD DETAILS
+
+    ┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳
+    ┃ POD NAME              ┃ NAMESPACE ┃ HOST-IP      ┃ PHASE   ┃ POD-IP     ┃ POD-IPs                ┃
+    ┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
+    │ prox-6db7c6dc9b-l42v4 │ default   │ 192.168.49.2 │ Running │ 172.17.0.4 │ [{'ip': '172.17.0.4'}] │
+    └───────────────────────┴───────────┴──────────────┴─────────┴────────────┴────────────────────────┴
+    ┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
+    ┃ POD NAME              ┃ INTERFACE IPs                                                     ┃
+    ┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
+    │ prox-6db7c6dc9b-l42v4 │ 127.0.0.1/8, 172.17.0.4/16, 127.0.0.1, 172.17.0.4, 172.17.255.255 │
+    └───────────────────────┴───────────────────────────────────────────────────────────────────┘
+
+    DEPLOYMENT DETAILS
+
+    ┏━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
+    ┃ NAME      ┃ Type     ┃ CLUSTER-IP    ┃ EXTERNAL-IP ┃ PORT(S)        ┃
+    ┡━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
+    │ proxchart │ NodePort │ 10.103.156.83 │ {}          │ 8081:31036/TCP │
+    └───────────┴──────────┴───────────────┴─────────────┴────────────────┘
+
+********************
+Future Enhancements
+********************
+
+In future, more information can be extracted by adding new functions to the file. The process of getting interfaces using regex can be made more proficient.
\ No newline at end of file
diff --git a/tools/k8s/app-deployment/helm/charts/mynet.yaml b/tools/k8s/app-deployment/helm/charts/mynet.yaml
new file mode 100644 (file)
index 0000000..ca3af9a
--- /dev/null
@@ -0,0 +1,20 @@
+apiVersion: "k8s.cni.cncf.io/v1"
+kind: NetworkAttachmentDefinition
+metadata:
+  name: mynet
+spec:
+  config: '{
+    "cniVersion":"0.3.0"
+    "name":"mynet"
+    "plugins":[
+    {
+      "bridge":"kube-bridge",
+      "ipam":{
+        "subnet":10.244.0.0/24",
+        "type":"host-local"
+        },
+        "isDefaultGateway":true,
+        "type":"bridge"
+      }
+    ]
+  }'
diff --git a/tools/k8s/app-deployment/helm/charts/pod.yaml b/tools/k8s/app-deployment/helm/charts/pod.yaml
new file mode 100644 (file)
index 0000000..942c8f9
--- /dev/null
@@ -0,0 +1,18 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: nginx
+  annotations:
+    k8s.v1.cni.cncf.io/networks: mynet
+
+spec:
+  containers:
+    - name: prox
+      image: opnfv/rapid:latest
+      imagePullPolicy: IfNotPresent
+      ports:
+        - containerPort: 3000
+    - name: nginx
+      image: nginx:alpine
+      ports:
+        - containerPort: 80
diff --git a/tools/k8s/app-deployment/helm/charts/proxchart/Chart.yaml b/tools/k8s/app-deployment/helm/charts/proxchart/Chart.yaml
new file mode 100644 (file)
index 0000000..6acc06f
--- /dev/null
@@ -0,0 +1,5 @@
+apiVersion: v2
+name: proxchart
+version: 0.1.0
+appVersion: "1.0"
+description: To deploy prox
diff --git a/tools/k8s/app-deployment/helm/charts/proxchart/templates/daemonset.yaml b/tools/k8s/app-deployment/helm/charts/proxchart/templates/daemonset.yaml
new file mode 100644 (file)
index 0000000..e1d3a56
--- /dev/null
@@ -0,0 +1,25 @@
+{{- if eq .Values.kind "DaemonSet"}}
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  name: prox
+  annotations:
+    k8s.v1.cni.cncf.io/networks: "{{- join "\",\"" .Values.extraInterfaces }}"
+spec:
+  selector:
+    matchLabels:
+      app: prox
+  template:
+    metadata:
+      labels:
+        app: prox
+    spec:
+      containers:
+      - name: prox
+        image: opnfv/rapid:latest
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 3000
+      nodeSelector:
+        {{- .Values.nodeSelector.matchLables | toYaml | nindent 12 }}
+{{- end }}
diff --git a/tools/k8s/app-deployment/helm/charts/proxchart/templates/deployment.yaml b/tools/k8s/app-deployment/helm/charts/proxchart/templates/deployment.yaml
new file mode 100644 (file)
index 0000000..235b02c
--- /dev/null
@@ -0,0 +1,30 @@
+{{- if eq .Values.kind "Deployment"}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: prox
+  annotations:
+    k8s.v1.cni.cncf.io/networks: "{{- join "\",\"" .Values.extraInterfaces | toYaml | nindent 8}}"
+spec:
+  selector:
+    matchLabels:
+      app: prox
+  replicas: {{ .Values.replicas }}
+  template:
+    metadata:
+      labels:
+        app: prox
+    spec:
+      containers:
+      - name: prox
+        image: opnfv/rapid:latest
+        imagePullPolicy: IfNotPresent
+        ports:
+          - containerPort: 3000
+      - name: nginx
+        image: nginx:alpine
+        ports:
+          - containerPort: 80
+      nodeSelector:
+        {{- .Values.nodeSelector.matchLables | toYaml | nindent 12 }}
+{{- end }}
diff --git a/tools/k8s/app-deployment/helm/charts/proxchart/templates/service.yaml b/tools/k8s/app-deployment/helm/charts/proxchart/templates/service.yaml
new file mode 100644 (file)
index 0000000..15215f3
--- /dev/null
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: proxchart
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
diff --git a/tools/k8s/app-deployment/helm/charts/proxchart/values.yaml b/tools/k8s/app-deployment/helm/charts/proxchart/values.yaml
new file mode 100644 (file)
index 0000000..405e4c2
--- /dev/null
@@ -0,0 +1,20 @@
+# daemonset, deployment
+kind: Deployment
+
+# Nodes to deploy on
+nodeSelector: {}
+  # matchLables:
+  #   key1: value1
+  #   key2: value2
+
+# multus
+metacniType: multus
+extraInterfaces:
+  net-attach-def1
+  net-attach-def2
+
+replicas: 1
+
+service:
+  type: NodePort
+  port: 8081
diff --git a/tools/k8s/app-deployment/helm/charts/testpmdchart/Chart.yaml b/tools/k8s/app-deployment/helm/charts/testpmdchart/Chart.yaml
new file mode 100644 (file)
index 0000000..85e8f7d
--- /dev/null
@@ -0,0 +1,5 @@
+apiVersion: v2
+name: testpmdchart
+version: 0.1.0
+appVersion: "1.0"
+description: To deploy test pmd
diff --git a/tools/k8s/app-deployment/helm/charts/testpmdchart/templates/daemonset.yaml b/tools/k8s/app-deployment/helm/charts/testpmdchart/templates/daemonset.yaml
new file mode 100644 (file)
index 0000000..10a812f
--- /dev/null
@@ -0,0 +1,25 @@
+{{- if eq .Values.kind "DaemonSet"}}
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  name: testpmd
+  annotations:
+    k8s.v1.cni.cncf.io/networks: "{{- join "\",\"" .Values.extraInterfaces }}"
+spec:
+  selector:
+    matchLabels:
+      app: testpmd
+  template:
+    metadata:
+      labels:
+        app: testpmd
+    spec:
+      containers:
+      - name: testpmd
+        image: ovsperf/dpdkfwd:lakelse
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 3000
+      nodeSelector:
+        {{- .Values.nodeSelector.matchLables | toYaml | nindent 12 }}
+{{- end }}
diff --git a/tools/k8s/app-deployment/helm/charts/testpmdchart/templates/deployment.yaml b/tools/k8s/app-deployment/helm/charts/testpmdchart/templates/deployment.yaml
new file mode 100644 (file)
index 0000000..6df47ff
--- /dev/null
@@ -0,0 +1,26 @@
+{{- if eq .Values.kind "Deployment"}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: testpmd
+  annotations:
+    k8s.v1.cni.cncf.io/networks: "{{- join "\",\"" .Values.extraInterfaces | toYaml | nindent 8}}"
+spec:
+  selector:
+    matchLabels:
+      app: testpmd
+  replicas: {{ .Values.replicas }}
+  template:
+    metadata:
+      labels:
+        app: testpmd
+    spec:
+      containers:
+      - name: testpmd
+        image: vsperf/dpdkfwd:lakelse
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 3000
+      nodeSelector:
+        {{- .Values.nodeSelector.matchLables | toYaml | nindent 12 }}
+{{- end }}
diff --git a/tools/k8s/app-deployment/helm/charts/testpmdchart/templates/service.yaml b/tools/k8s/app-deployment/helm/charts/testpmdchart/templates/service.yaml
new file mode 100644 (file)
index 0000000..50f7562
--- /dev/null
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: testpmdchart
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
diff --git a/tools/k8s/app-deployment/helm/charts/testpmdchart/values.yaml b/tools/k8s/app-deployment/helm/charts/testpmdchart/values.yaml
new file mode 100644 (file)
index 0000000..af6be61
--- /dev/null
@@ -0,0 +1,20 @@
+# daemonset, deployment
+kind: Deployment
+
+# Nodes to deploy on
+nodeSelector:
+  # matchLables:
+  #   key1: value1
+  #   key2: value2
+
+# multus
+metacniType: multus
+extraInterfaces:
+  net-attach-def1
+  net-attach-def2
+
+replicas: 1
+
+service:
+  type: NodePort
+  port: 8081
diff --git a/tools/k8s/app-deployment/helm/charts/trexchart/Chart.yaml b/tools/k8s/app-deployment/helm/charts/trexchart/Chart.yaml
new file mode 100644 (file)
index 0000000..1dfb7b0
--- /dev/null
@@ -0,0 +1,5 @@
+apiVersion: v2
+name: trexchart
+description: A Helm chart for trex Deployment
+version: 0.1.0
+appVersion: "1.0"
diff --git a/tools/k8s/app-deployment/helm/charts/trexchart/templates/daemonset.yaml b/tools/k8s/app-deployment/helm/charts/trexchart/templates/daemonset.yaml
new file mode 100644 (file)
index 0000000..39d4662
--- /dev/null
@@ -0,0 +1,25 @@
+{{- if eq .Values.kind "DaemonSet"}}
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  name: trex
+  annotations:
+    k8s.v1.cni.cncf.io/networks: "{{- join "\",\"" .Values.extraInterfaces }}"
+spec:
+  selector:
+    matchLabels:
+      app: trex
+  template:
+    metadata:
+      labels:
+        app: trex
+    spec:
+      containers:
+      - name: trex
+        image: vsperf/trex:lakelse
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 3000
+      nodeSelector:
+        {{- .Values.nodeSelector.matchLables | toYaml | nindent 12 }}
+{{- end }}
diff --git a/tools/k8s/app-deployment/helm/charts/trexchart/templates/deployment.yaml b/tools/k8s/app-deployment/helm/charts/trexchart/templates/deployment.yaml
new file mode 100644 (file)
index 0000000..8b0f447
--- /dev/null
@@ -0,0 +1,26 @@
+{{- if eq .Values.kind "Deployment"}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: trex
+  annotations:
+    k8s.v1.cni.cncf.io/networks: "{{- join "\",\"" .Values.extraInterfaces | toYaml | nindent 8}}"
+spec:
+  selector:
+    matchLabels:
+      app: trex
+  replicas: {{ .Values.replicas }}
+  template:
+    metadata:
+      labels:
+        app: trex
+    spec:
+      containers:
+      - name: trex
+        image: vsperf/trex:lakelse
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 3000
+      nodeSelector:
+        {{- .Values.nodeSelector.matchLables | toYaml | nindent 12 }}
+{{- end }}
diff --git a/tools/k8s/app-deployment/helm/charts/trexchart/templates/service.yaml b/tools/k8s/app-deployment/helm/charts/trexchart/templates/service.yaml
new file mode 100644 (file)
index 0000000..8965194
--- /dev/null
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: trexchart
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
diff --git a/tools/k8s/app-deployment/helm/charts/trexchart/values.yaml b/tools/k8s/app-deployment/helm/charts/trexchart/values.yaml
new file mode 100644 (file)
index 0000000..ed289cf
--- /dev/null
@@ -0,0 +1,20 @@
+# daemonset, deployment
+kind: DaemonSet
+
+# Nodes to deploy on
+nodeSelector:
+  # matchLables:
+  #   key1: value1
+  #   key2: value2
+
+# multus
+metacniType: multus
+extraInterfaces:
+  net-attach-def1
+  net-attach-def2
+
+replicas: 1
+
+service:
+  type: NodePort
+  port: 8081
diff --git a/tools/k8s/app-deployment/helm/pyscript/Pipfile b/tools/k8s/app-deployment/helm/pyscript/Pipfile
new file mode 100644 (file)
index 0000000..dd60181
--- /dev/null
@@ -0,0 +1,18 @@
+[[source]]
+url = "https://pypi.org/simple"
+verify_ssl = true
+name = "pypi"
+
+[packages]
+kubernetes = "*"
+pyyaml = "*"
+pick = "*"
+simplejson = "*"
+nested-lookup = "*"
+rich = "*"
+pylint = "*"
+
+[dev-packages]
+
+[requires]
+python_version = "3.9"
diff --git a/tools/k8s/app-deployment/helm/pyscript/main.py b/tools/k8s/app-deployment/helm/pyscript/main.py
new file mode 100644 (file)
index 0000000..1419f34
--- /dev/null
@@ -0,0 +1,172 @@
+# Copyright 2015-2017 Intel Corporation.
+#
+# 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.
+
+'''
+This script automatically develop helm charts and returns
+useful informations
+'''
+
+import os
+import subprocess
+from subprocess import PIPE, STDOUT
+import time
+import re
+from ast import literal_eval
+import yaml
+from rich.console import Console
+from rich.table import Table
+
+console = Console()
+
+def check_system_installations():
+    ''' Check system installations necessary for successful run of this script '''
+    try:
+        subprocess.run("helm version",shell=True,check=True)
+        subprocess.run("kubectl version --client",shell=True,
+        check= True)
+        subprocess.run("minikube version",shell=True,check=True)
+
+    except subprocess.CalledProcessError as error:
+        print (error.output)
+
+
+def parse_helm_chart(helm_path):
+    ''' Extract name of the chart '''
+    values_file = os.path.join(helm_path,"Chart.yaml")
+    with open(values_file, 'r', encoding='utf-8') as file:
+        doc = yaml.load(file)
+    name_of_chart = doc['name']
+
+    values_file = os.path.join(helm_path,"values.yaml")
+    with open(values_file, 'r',encoding='utf-8') as file:
+        doc = yaml.load(file)
+    n_pods = doc['replicas']
+    return (name_of_chart, n_pods)
+
+
+def service_details(name):
+    ''' Extract Service Details'''
+    print("\nDEPLOYEMENT DETAILS\n")
+
+    with subprocess.Popen(f"kubectl get service -o json {name}",shell=True,
+                        stdin=PIPE, stdout=PIPE, stderr=STDOUT) as process:
+        output = process.stdout.read()
+        string = output.decode().replace("'", '"')
+        _j = literal_eval(string)
+
+    table = Table(show_header=True)
+
+    table.add_column("NAME")
+    table.add_column("Type")
+    table.add_column("CLUSTER-IP")
+    table.add_column("EXTERNAL-IP")
+    table.add_column("PORT(S)")
+
+    col=f'{_j["spec"]["ports"][0]["port"]}:{_j["spec"]["ports"][0]["nodePort"]}/{_j["spec"]["ports"][0]["protocol"]}'
+
+    table.add_row(
+        f'{_j["metadata"]["name"]}',
+        f'{_j["spec"]["type"]}',
+        f'{_j["spec"]["clusterIP"]}',
+        f'{_j["status"]["loadBalancer"]}',
+        col,
+    )
+    console.print(table)
+
+
+def pod_details(replicas):
+    ''' Extract Pod Details'''
+    print("\nPOD DETAILS\n")
+    with subprocess.Popen("kubectl get pods -o json", shell=True,
+                                stdin=PIPE, stdout=PIPE, stderr=STDOUT) as process:
+        output = process.stdout.read()
+        pod_string = output.decode().replace("'", '"')
+        # true = True
+        # null = None
+        # false = False
+        pod_json = literal_eval(pod_string)
+
+    table = Table(show_header=True)
+
+    table.add_column("POD NAME")
+    table.add_column("NAMESPACE")
+    table.add_column("HOST-IP")
+    table.add_column("PHASE")
+    table.add_column("POD-IP")
+    table.add_column("POD-IPs")
+    podname = pod_json["items"][0]["metadata"]["name"]
+
+    for i in range(replicas):
+        table.add_row(
+            f'{pod_json["items"][i]["metadata"]["name"]}',
+            f'{pod_json["items"][i]["metadata"]["namespace"]}',
+            f'{pod_json["items"][i]["status"]["hostIP"]}',
+            f'{pod_json["items"][i]["status"]["phase"]}',
+            f'{pod_json["items"][i]["status"]["podIP"]}',
+            f'{pod_json["items"][i]["status"]["podIPs"]}',
+        )
+    console.print(table)
+
+    ip_interface(podname)
+
+
+def ip_interface(podname):
+    ''' Extract Network IP'''
+    with subprocess.Popen(f"kubectl exec -i {podname} -c nginx -- ip -o a", shell=True,
+                                stdin=PIPE, stdout=PIPE, stderr=STDOUT) as process:
+        output = process.stdout.read()
+        _string = output.decode().replace("'", '"')
+        ipregex = r"((?:[0-9]{1,3}[.]){3}[0-9]{1,3}/[0-9]{1,2})"
+        ipregex2 = r"((?:[0-9]{1,3}[.]){3}[0-9]{1,3})"
+        list1=re.findall(ipregex, _string)
+        list2=re.findall(ipregex2 ,_string)
+        ip_list = list1 + list2
+        ip_string = ', '.join(ip_list)
+
+    table = Table(show_header=True)
+
+    table.add_column("POD NAME")
+    table.add_column("INTERFACE IPs")
+
+    table.add_row(
+        podname,
+        ip_string,
+    )
+    console.print(table)
+
+
+def main():
+    ''' Main Function '''
+    check_system_installations()
+
+    helm_location = input("Enter the location of helm chart:  ")
+    name,replicas = parse_helm_chart(helm_location)
+
+    subprocess.run(f"helm install {name} {helm_location}",shell=True,
+                        check = True).stdout.read()
+    time.sleep(10)
+
+    # status of helm charts
+    print("\nStatus of helm charts\n")
+    subprocess.Popen("helm list", shell =True,stdout=subprocess.PIPE,).communicate()
+    print("--" * 50)
+
+    #pod details
+    pod_details(replicas)
+
+    #deployment details
+    service_details(name)
+
+if __name__ == "__main__":
+    main()