Skip to content

Commit

Permalink
Merge pull request #84 from EliasDeHondt/Deployment-through-app
Browse files Browse the repository at this point in the history
Deployment through app
  • Loading branch information
VW03 authored Feb 19, 2025
2 parents 9a6755a + 5f5db40 commit 5e1e15a
Show file tree
Hide file tree
Showing 25 changed files with 689 additions and 44 deletions.
200 changes: 200 additions & 0 deletions App/Backend/cmd/kubernetes/Client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package kubernetes

import (
"context"
av1 "k8s.io/api/apps/v1"
cv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
Expand All @@ -25,6 +27,7 @@ type FakeMetricsClient struct {
}

type IClient interface {
GetNamespaces() corev1.NamespaceInterface
GetNodes() corev1.NodeInterface
GetPods(namespace string) corev1.PodInterface
GetServices(namespace string) corev1.ServiceInterface
Expand All @@ -34,6 +37,13 @@ type IClient interface {
GetDeployments(namespace string) appsv1.DeploymentInterface
GetTotalUsage() (*Metrics, error)
GetUsageForNode(nodeName string) (*Metrics, error)
CreateNamespace(namespace *cv1.Namespace) (Namespace, error)
CreateNode(node *cv1.Node) (Node, error)
CreatePod(pod *cv1.Pod) (Pod, error)
CreateDeployment(deployment *av1.Deployment) (Deployment, error)
CreateService(service *cv1.Service) (Service, error)
CreateConfigMap(configMap *cv1.ConfigMap) (ConfigMap, error)
CreateSecret(secret *cv1.Secret) (Secret, error)
}

type FakeClient struct {
Expand All @@ -46,6 +56,10 @@ type Client struct {
MetricsClient *metricsv.Clientset
}

func (client *FakeClient) GetNamespaces() corev1.NamespaceInterface {
return client.Client.CoreV1().Namespaces()
}

func (client *FakeClient) GetNodes() corev1.NodeInterface {
return client.Client.CoreV1().Nodes()
}
Expand Down Expand Up @@ -74,6 +88,101 @@ func (client *FakeClient) GetDeployments(namespace string) appsv1.DeploymentInte
return client.Client.AppsV1().Deployments(namespace)
}

func (client *FakeClient) CreateNamespace(namespace *cv1.Namespace) (Namespace, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

newNamespace, err := client.GetNamespaces().Create(ctx, namespace, metav1.CreateOptions{})

if err != nil {
return Namespace{}, err
}

return NewNamespace(*newNamespace), err
}

func (client *FakeClient) CreateNode(node *cv1.Node) (Node, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

node, err := client.GetNodes().Create(ctx, node, metav1.CreateOptions{})

if err != nil {
return Node{}, err
}

return NewNode(*node, client), err
}

func (client *FakeClient) CreatePod(pod *cv1.Pod) (Pod, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

pod, err := client.GetPods(pod.Namespace).Create(ctx, pod, metav1.CreateOptions{})

if err != nil {
return Pod{}, err
}

return NewPod(*pod, client), err
}

func (client *FakeClient) CreateDeployment(deployment *av1.Deployment) (Deployment, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

deployment, err := client.GetDeployments(deployment.Namespace).Create(ctx, deployment, metav1.CreateOptions{})

if err != nil {
return Deployment{}, err
}

return NewDeployment(*deployment), err
}

func (client *FakeClient) CreateService(service *cv1.Service) (Service, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

_, err := client.GetServices(service.Namespace).Create(ctx, service, metav1.CreateOptions{})

if err != nil {
return Service{}, err
}

return NewService(*service), err
}

func (client *FakeClient) CreateConfigMap(configMap *cv1.ConfigMap) (ConfigMap, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

_, err := client.GetConfigMaps(configMap.Namespace).Create(ctx, configMap, metav1.CreateOptions{})

if err != nil {
return ConfigMap{}, err
}

return NewConfigMap(*configMap), err
}

func (client *FakeClient) CreateSecret(secret *cv1.Secret) (Secret, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

_, err := client.GetSecrets(secret.Namespace).Create(ctx, secret, metav1.CreateOptions{})

if err != nil {
return Secret{}, err
}

return NewSecret(*secret), err
}

func (client *Client) GetNamespaces() corev1.NamespaceInterface {
return client.Client.CoreV1().Namespaces()
}

func (client *Client) GetNodes() corev1.NodeInterface {
return client.Client.CoreV1().Nodes()
}
Expand Down Expand Up @@ -225,3 +334,94 @@ func (client *Client) GetUsageForNode(nodeName string) (*Metrics, error) {

return &Metrics{CpuUsage: cpuUsagePercent, MemUsage: memoryUsagePercent, DiskUsage: usedDisk, DiskCapacity: totalDisk}, nil
}

func (client *Client) CreateNamespace(namespace *cv1.Namespace) (Namespace, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

newNamespace, err := client.GetNamespaces().Create(ctx, namespace, metav1.CreateOptions{})

if err != nil {
return Namespace{}, err
}

return NewNamespace(*newNamespace), err
}

func (client *Client) CreateNode(node *cv1.Node) (Node, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

node, err := client.GetNodes().Create(ctx, node, metav1.CreateOptions{})

if err != nil {
return Node{}, err
}

return NewNode(*node, client), err
}

func (client *Client) CreatePod(pod *cv1.Pod) (Pod, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

pod, err := client.GetPods(pod.Namespace).Create(ctx, pod, metav1.CreateOptions{})

if err != nil {
return Pod{}, err
}

return NewPod(*pod, client), err
}

func (client *Client) CreateDeployment(deployment *av1.Deployment) (Deployment, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

deployment, err := client.GetDeployments(deployment.Namespace).Create(ctx, deployment, metav1.CreateOptions{})

if err != nil {
return Deployment{}, err
}

return NewDeployment(*deployment), err
}

func (client *Client) CreateService(service *cv1.Service) (Service, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

_, err := client.GetServices(service.Namespace).Create(ctx, service, metav1.CreateOptions{})

if err != nil {
return Service{}, err
}

return NewService(*service), err
}

func (client *Client) CreateConfigMap(configMap *cv1.ConfigMap) (ConfigMap, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

_, err := client.GetConfigMaps(configMap.Namespace).Create(ctx, configMap, metav1.CreateOptions{})

if err != nil {
return ConfigMap{}, err
}

return NewConfigMap(*configMap), err
}

func (client *Client) CreateSecret(secret *cv1.Secret) (Secret, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

_, err := client.GetSecrets(secret.Namespace).Create(ctx, secret, metav1.CreateOptions{})

if err != nil {
return Secret{}, err
}

return NewSecret(*secret), err
}
13 changes: 13 additions & 0 deletions App/Backend/cmd/kubernetes/Namespace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package kubernetes

import corev1 "k8s.io/api/core/v1"

type Namespace struct {
Name string
}

func NewNamespace(namespace corev1.Namespace) Namespace {
return Namespace{
Name: namespace.Name,
}
}
6 changes: 3 additions & 3 deletions App/Backend/cmd/kubernetes/Node.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Node struct {

//TODO: remove fake clientset and use a real clientset

func NewNode(node v1.Node, clientset *IClient) Node {
func NewNode(node v1.Node, clientset IClient) Node {
return Node{
Name: node.Name,
Status: isNodeOnline(&node),
Expand All @@ -38,10 +38,10 @@ func calculateNodeAge(node *v1.Node) string {
return fmt.Sprintf("%d:%d:%d", int(age.Hours()/24), int(age.Hours())%24, int(age.Minutes())%60)
}

func getPodsInNode(nodeName string, clientset *IClient) int {
func getPodsInNode(nodeName string, clientset IClient) int {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
pods, err := (*clientset).GetPods("").List(ctx, metav1.ListOptions{
pods, err := (clientset).GetPods("").List(ctx, metav1.ListOptions{
FieldSelector: "spec.nodeName=" + nodeName,
})
if err != nil {
Expand Down
12 changes: 6 additions & 6 deletions App/Backend/cmd/kubernetes/Pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type Pod struct {

//TODO: remove fake clientset and use a real clientset

func NewPod(pod v1.Pod, clientset *IClient) Pod {
func NewPod(pod v1.Pod, clientset IClient) Pod {

runningServices, totalServices := getServiceHealthForPod(pod, clientset)

Expand Down Expand Up @@ -56,7 +56,7 @@ func isPodOnline(pod *v1.Pod) string {
return "NO STATUS ❓"
}

func getServiceHealthForPod(pod v1.Pod, clientset *IClient) (int, int) {
func getServiceHealthForPod(pod v1.Pod, clientset IClient) (int, int) {
services := getServicesForPod(pod, clientset)
totalServices := len(services)
runningServices := 0
Expand All @@ -70,12 +70,12 @@ func getServiceHealthForPod(pod v1.Pod, clientset *IClient) (int, int) {
return runningServices, totalServices
}

func getServicesForPod(pod v1.Pod, clientset *IClient) []string {
func getServicesForPod(pod v1.Pod, clientset IClient) []string {
var matchingServices []string
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

services, err := (*clientset).GetServices(pod.Namespace).List(ctx, metav1.ListOptions{})
services, err := clientset.GetServices(pod.Namespace).List(ctx, metav1.ListOptions{})
if err != nil {
log.Printf("Error listing services: %v", err)
return nil
Expand Down Expand Up @@ -106,11 +106,11 @@ func isPodMatchingService(pod v1.Pod, service v1.Service) bool {
return true
}

func isServiceRunning(namespace, serviceName string, clientset *IClient) bool {
func isServiceRunning(namespace, serviceName string, clientset IClient) bool {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

endpoints, err := (*clientset).GetEndpoints(namespace).Get(ctx, serviceName, metav1.GetOptions{})
endpoints, err := clientset.GetEndpoints(namespace).Get(ctx, serviceName, metav1.GetOptions{})
if err != nil {
log.Printf("Error getting endpoints for service %s: %v", serviceName, err)
return false
Expand Down
10 changes: 5 additions & 5 deletions App/Backend/cmd/kubernetes/Setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,28 @@ import (
"time"
)

func GetClients() *IClient {
func GetClients() IClient {
config, err := rest.InClusterConfig()

if err != nil {
client := TestFakeClient()
return &client
return client
}

c, err := kubernetes.NewForConfig(config)
if err != nil {
client := TestFakeClient()
return &client
return client
}

mc, err := metricsv.NewForConfig(config)
if err != nil {
client := TestFakeClient()
return &client
return client
}

var client IClient = &Client{c, mc}
return &client
return client
}

func TestFakeClient() IClient {
Expand Down
Loading

0 comments on commit 5e1e15a

Please sign in to comment.