Skip to content

Commit

Permalink
Refractor challengedeployerservice
Browse files Browse the repository at this point in the history
  • Loading branch information
Bisht13 committed Jul 30, 2023
1 parent 8b80af5 commit 38ebbd8
Show file tree
Hide file tree
Showing 8 changed files with 392 additions and 414 deletions.
86 changes: 79 additions & 7 deletions lib/utils/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import (
g "github.com/sdslabs/katana/configs"
"github.com/sdslabs/katana/types"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
Expand Down Expand Up @@ -47,7 +49,7 @@ func GetKubeClient() (*kubernetes.Clientset, error) {
return kubernetes.NewForConfig(config)
}

func GetPods(lbls map[string]string, ns ...string) ([]v1.Pod, error) {
func GetPods(lbls map[string]string, ns ...string) ([]corev1.Pod, error) {
var namespace string
if len(ns) == 0 {
namespace = g.KatanaConfig.KubeNameSpace
Expand Down Expand Up @@ -122,7 +124,7 @@ func CopyIntoPod(podName string, containerName string, pathInPod string, localFi
}

// Find the container in the pod
var container *v1.Container
var container *corev1.Container
for _, c := range pod.Spec.Containers {
if c.Name == containerName {
container = &c
Expand All @@ -142,7 +144,7 @@ func CopyIntoPod(podName string, containerName string, pathInPod string, localFi
SubResource("exec").
Param("container", containerName)

req.VersionedParams(&v1.PodExecOptions{
req.VersionedParams(&corev1.PodExecOptions{
Container: containerName,
Command: []string{"bash", "-c", "cat > " + pathInPod},
Stdin: true,
Expand Down Expand Up @@ -241,7 +243,7 @@ func Podexecutor(command []string, kubeClientset *kubernetes.Clientset, kubeConf
Name("katana-team-master-pod-0").
Namespace(podNamespace + "-ns").
SubResource("exec")
req.VersionedParams(&v1.PodExecOptions{
req.VersionedParams(&corev1.PodExecOptions{
Command: command,
Stdin: false,
Stdout: true,
Expand Down Expand Up @@ -320,7 +322,7 @@ func DeleteConfigMapAndWait(kubeClientset *kubernetes.Clientset, kubeConfig *res

for event := range watcher.ResultChan() {
// Check if ConfigMap exists
configMapName := event.Object.(*v1.ConfigMap).Name
configMapName := event.Object.(*corev1.ConfigMap).Name
if configMapName == "" {
break
}
Expand Down Expand Up @@ -351,7 +353,7 @@ func WaitForLoadBalancerExternalIP(clientset *kubernetes.Clientset, serviceName
defer watcher.Stop()

for event := range watcher.ResultChan() {
service, ok := event.Object.(*v1.Service)
service, ok := event.Object.(*corev1.Service)
if !ok {
continue
}
Expand Down Expand Up @@ -395,3 +397,73 @@ func WaitForDeploymentReady(clientset *kubernetes.Clientset, deploymentName stri

return nil
}

func CreateService(clientset *kubernetes.Clientset, serviceName string, namespace string, port int32, targetPort int32, selector map[string]string) error {
service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: serviceName,
},
Spec: corev1.ServiceSpec{
Selector: selector,
Ports: []corev1.ServicePort{
{
Port: port,
TargetPort: intstr.FromInt(int(targetPort)),
},
},
},
}

_, err := clientset.CoreV1().Services(namespace).Create(context.Background(), service, metav1.CreateOptions{})
if err != nil {
return err
}

return nil
}

func CreateIngress(clientset *kubernetes.Clientset, ingressName string, namespace string, serviceName string, servicePort int32, host string) error {
ingressClassName := "nginx"

ingress := &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: ingressName,
},
Spec: networkingv1.IngressSpec{
IngressClassName: &ingressClassName,
Rules: []networkingv1.IngressRule{
{
Host: host,
IngressRuleValue: networkingv1.IngressRuleValue{
HTTP: &networkingv1.HTTPIngressRuleValue{
Paths: []networkingv1.HTTPIngressPath{
{
Path: "/",
PathType: func() *networkingv1.PathType {
pathType := networkingv1.PathTypePrefix
return &pathType
}(),
Backend: networkingv1.IngressBackend{
Service: &networkingv1.IngressServiceBackend{
Name: serviceName,
Port: networkingv1.ServiceBackendPort{
Number: servicePort,
},
},
},
},
},
},
},
},
},
},
}

_, err := clientset.NetworkingV1().Ingresses(namespace).Create(context.Background(), ingress, metav1.CreateOptions{})
if err != nil {
return err
}

return nil
}
183 changes: 183 additions & 0 deletions services/challengedeployerservice/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package challengedeployerservice

import (
"context"
"fmt"
"log"
"os"
"regexp"
"strconv"

"github.com/gofiber/fiber/v2"
archiver "github.com/mholt/archiver/v3"
g "github.com/sdslabs/katana/configs"
"github.com/sdslabs/katana/lib/utils"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func DeployChallenge(c *fiber.Ctx) error {

challengeType := "web"
folderName := ""
patch := false
replicas := g.KatanaConfig.TeamDeployment
log.Println("Starting")
if form, err := c.MultipartForm(); err == nil {

files := form.File["challenge"]

// Loops through all challenges, if multiple uploaded :
for _, file := range files {

//creates folders for each challenge
pattern := `([^/]+)\.tar\.gz$`
regex := regexp.MustCompile(pattern)
match := regex.FindStringSubmatch(file.Filename)
folderName = match[1]

response, challengePath := createFolder(folderName)
if response == 1 {
log.Println("Directory already exists with same name")
return c.SendString("Directory already exists with same name")
} else if response == 2 {
log.Println("Issue with creating chall directory.Check permissions")
return c.SendString("Issue with creating chall directory.Check permissions")
}

//save to disk in that directory
if err := c.SaveFile(file, fmt.Sprintf("./challenges/%s/%s", folderName, file.Filename)); err != nil {
return err
}

//Create folder inside the challenge folder
err = os.Mkdir(challengePath+"/"+folderName, 0777)
if err != nil {
log.Println("Error in creating folder inside challenge folder")
return c.SendString("Error in creating folder inside challenge folder")
}

//extract the tar.gz file
err := archiver.Unarchive("./challenges/"+folderName+"/"+file.Filename, "./challenges/"+folderName)
if err != nil {
log.Println("Error in unarchiving", err)
return c.SendString("Error in unarchiving")
}

//Update challenge path to get dockerfile
challengePath = challengePath + "/" + folderName

utils.BuildDockerImage(folderName, challengePath)

//Get no.of teams and DEPLOY CHALLENGE to each namespace (assuming they exist and /createTeams has been called)
clusterConfig := g.ClusterConfig
numberOfTeams := clusterConfig.TeamCount
res := make([][]string, 0)
for i := 0; i < int(numberOfTeams); i++ {
log.Println("-----------Deploying challenge for team: " + strconv.Itoa(i) + " --------")
teamName := "katana-team-" + strconv.Itoa(i)
utils.DeployChallenge(folderName, teamName, patch, replicas)
url, err := createServiceAndIngressForChallenge(folderName, teamName, 3000)
if err != nil {
res = append(res, []string{teamName, err.Error()})
} else {
res = append(res, []string{teamName, url})
}
}

//Copy challenge in pods and etc.
copyChallengeIntoTsuka(challengePath, folderName, challengeType)

return c.JSON(res)
}
}
log.Println("Ending")

return c.SendString("Wrong file")
}

func DeleteChallenge(c *fiber.Ctx) error {

challengeName := c.Params("challengeName")
//Delete chall directory also ?
log.Println("Challenge name is : " + challengeName)

dirPath, _ := os.Getwd()
challengePath := dirPath + "/challenges/" + challengeName
log.Println("Deleting challenge folder :", challengePath)
err := os.RemoveAll(challengePath)
if err != nil {
log.Println("Error in deleting challenge folder")
return err
}

totalTeams := utils.GetTeamNumber()

for i := 0; i < totalTeams; i++ {

teamName := "team-" + strconv.Itoa(i)

teamNamespace := "katana-" + teamName + "-ns"
kubeclient, err := utils.GetKubeClient()
if err != nil {
return err
}

log.Println("---------------Deleting challenge for team: ", teamNamespace)
serviceClient := kubeclient.CoreV1().Services(teamNamespace)
deploymentsClient := kubeclient.AppsV1().Deployments(teamNamespace)

//Get deployment
deps, err := deploymentsClient.Get(context.TODO(), challengeName, metav1.GetOptions{})
if err != nil {
log.Println(" Error in getting deployments associated with the challenge. ")
continue
//panic(err)
}

//Delete deployments
if deps.Name != challengeName {
log.Println("Deployment does not exist. Create one using /deploy route.")
return nil
} else {
log.Println("Deleting deployment...")
deletePolicy := metav1.DeletePropagationForeground
err = deploymentsClient.Delete(context.TODO(), challengeName, metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
if err != nil {
log.Println("Error in deleting deployment.")
continue
}
}

//Check if service exists
services, err := serviceClient.List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Println(" Error in getting services for" + challengeName + "in the namespace " + teamNamespace)
continue
//panic(err)
}

flag := 0
for _, service := range services.Items {
if service.Name == challengeName {
flag = 1
}
}
if flag == 0 {
log.Println("Service does not exist for the " + challengeName + " in namespace " + teamNamespace)
continue
}

//Delete service
log.Println("Deleting services associated with this challenge...")
err = serviceClient.Delete(context.TODO(), challengeName, metav1.DeleteOptions{})
if err != nil {
log.Println("Error in deleting service for "+challengeName+" in namespace "+teamNamespace, err)
continue
}

}

log.Println("Process completed")

return c.SendString("Deleted challenge" + challengeName + "in all namespaces.")
}
65 changes: 0 additions & 65 deletions services/challengedeployerservice/copyInPod.go

This file was deleted.

Loading

0 comments on commit 38ebbd8

Please sign in to comment.