github.com/kubeshop/testkube@v1.17.23/pkg/tcl/apitcl/v1/testworkflowtemplates.go (about)

     1  // Copyright 2024 Testkube.
     2  //
     3  // Licensed as a Testkube Pro file under the Testkube Community
     4  // License (the "License"); you may not use this file except in compliance with
     5  // the License. You may obtain a copy of the License at
     6  //
     7  //	https://github.com/kubeshop/testkube/blob/main/licenses/TCL.txt
     8  
     9  package v1
    10  
    11  import (
    12  	"fmt"
    13  	"net/http"
    14  	"strings"
    15  
    16  	"github.com/gofiber/fiber/v2"
    17  	"github.com/pkg/errors"
    18  
    19  	testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1"
    20  	"github.com/kubeshop/testkube/internal/common"
    21  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
    22  	mappers2 "github.com/kubeshop/testkube/pkg/tcl/mapperstcl/testworkflows"
    23  )
    24  
    25  func (s *apiTCL) ListTestWorkflowTemplatesHandler() fiber.Handler {
    26  	errPrefix := "failed to list test workflow templates"
    27  	return func(c *fiber.Ctx) (err error) {
    28  		templates, err := s.getFilteredTestWorkflowTemplateList(c)
    29  		if err != nil {
    30  			return s.BadGateway(c, errPrefix, "client problem", err)
    31  		}
    32  		err = SendResourceList(c, "TestWorkflowTemplate", testworkflowsv1.GroupVersion, mappers2.MapTestWorkflowTemplateKubeToAPI, templates.Items...)
    33  		if err != nil {
    34  			return s.InternalError(c, errPrefix, "serialization problem", err)
    35  		}
    36  		return
    37  	}
    38  }
    39  
    40  func (s *apiTCL) GetTestWorkflowTemplateHandler() fiber.Handler {
    41  	return func(c *fiber.Ctx) (err error) {
    42  		name := c.Params("id")
    43  		errPrefix := fmt.Sprintf("failed to get test workflow template '%s'", name)
    44  		template, err := s.TestWorkflowTemplatesClient.Get(name)
    45  		if err != nil {
    46  			return s.ClientError(c, errPrefix, err)
    47  		}
    48  		err = SendResource(c, "TestWorkflowTemplate", testworkflowsv1.GroupVersion, mappers2.MapTemplateKubeToAPI, template)
    49  		if err != nil {
    50  			return s.InternalError(c, errPrefix, "serialization problem", err)
    51  		}
    52  		return
    53  	}
    54  }
    55  
    56  func (s *apiTCL) DeleteTestWorkflowTemplateHandler() fiber.Handler {
    57  	return func(c *fiber.Ctx) error {
    58  		name := c.Params("id")
    59  		errPrefix := fmt.Sprintf("failed to delete test workflow template '%s'", name)
    60  		err := s.TestWorkflowTemplatesClient.Delete(name)
    61  		s.Metrics.IncDeleteTestWorkflowTemplate(err)
    62  		if err != nil {
    63  			return s.ClientError(c, errPrefix, err)
    64  		}
    65  		return c.SendStatus(http.StatusNoContent)
    66  	}
    67  }
    68  
    69  func (s *apiTCL) DeleteTestWorkflowTemplatesHandler() fiber.Handler {
    70  	errPrefix := "failed to delete test workflow templates"
    71  	return func(c *fiber.Ctx) error {
    72  		selector := c.Query("selector")
    73  		err := s.TestWorkflowTemplatesClient.DeleteByLabels(selector)
    74  		if err != nil {
    75  			return s.ClientError(c, errPrefix, err)
    76  		}
    77  		return c.SendStatus(http.StatusNoContent)
    78  	}
    79  }
    80  
    81  func (s *apiTCL) CreateTestWorkflowTemplateHandler() fiber.Handler {
    82  	errPrefix := "failed to create test workflow template"
    83  	return func(c *fiber.Ctx) (err error) {
    84  		// Deserialize resource
    85  		obj := new(testworkflowsv1.TestWorkflowTemplate)
    86  		if HasYAML(c) {
    87  			err = common.DeserializeCRD(obj, c.Body())
    88  			if err != nil {
    89  				return s.BadRequest(c, errPrefix, "invalid body", err)
    90  			}
    91  		} else {
    92  			var v *testkube.TestWorkflowTemplate
    93  			err = c.BodyParser(&v)
    94  			if err != nil {
    95  				return s.BadRequest(c, errPrefix, "invalid body", err)
    96  			}
    97  			obj = mappers2.MapTemplateAPIToKube(v)
    98  		}
    99  
   100  		// Validate resource
   101  		if obj == nil || obj.Name == "" {
   102  			return s.BadRequest(c, errPrefix, "invalid body", errors.New("name is required"))
   103  		}
   104  		obj.Namespace = s.Namespace
   105  
   106  		// Create the resource
   107  		obj, err = s.TestWorkflowTemplatesClient.Create(obj)
   108  		s.Metrics.IncCreateTestWorkflowTemplate(err)
   109  		if err != nil {
   110  			return s.BadRequest(c, errPrefix, "client error", err)
   111  		}
   112  		s.sendCreateWorkflowTemplateTelemetry(c.Context(), obj)
   113  
   114  		err = SendResource(c, "TestWorkflowTemplate", testworkflowsv1.GroupVersion, mappers2.MapTemplateKubeToAPI, obj)
   115  		if err != nil {
   116  			return s.InternalError(c, errPrefix, "serialization problem", err)
   117  		}
   118  		return
   119  	}
   120  }
   121  
   122  func (s *apiTCL) UpdateTestWorkflowTemplateHandler() fiber.Handler {
   123  	errPrefix := "failed to update test workflow template"
   124  	return func(c *fiber.Ctx) (err error) {
   125  		name := c.Params("id")
   126  
   127  		// Deserialize resource
   128  		obj := new(testworkflowsv1.TestWorkflowTemplate)
   129  		if HasYAML(c) {
   130  			err = common.DeserializeCRD(obj, c.Body())
   131  			if err != nil {
   132  				return s.BadRequest(c, errPrefix, "invalid body", err)
   133  			}
   134  		} else {
   135  			var v *testkube.TestWorkflowTemplate
   136  			err = c.BodyParser(&v)
   137  			if err != nil {
   138  				return s.BadRequest(c, errPrefix, "invalid body", err)
   139  			}
   140  			obj = mappers2.MapTemplateAPIToKube(v)
   141  		}
   142  
   143  		// Read existing resource
   144  		template, err := s.TestWorkflowTemplatesClient.Get(name)
   145  		if err != nil {
   146  			return s.ClientError(c, errPrefix, err)
   147  		}
   148  
   149  		// Validate resource
   150  		if obj == nil {
   151  			return s.BadRequest(c, errPrefix, "invalid body", errors.New("body is required"))
   152  		}
   153  		obj.Namespace = template.Namespace
   154  		obj.Name = template.Name
   155  		obj.ResourceVersion = template.ResourceVersion
   156  
   157  		// Update the resource
   158  		obj, err = s.TestWorkflowTemplatesClient.Update(obj)
   159  		s.Metrics.IncUpdateTestWorkflowTemplate(err)
   160  		if err != nil {
   161  			return s.BadRequest(c, errPrefix, "client error", err)
   162  		}
   163  
   164  		err = SendResource(c, "TestWorkflowTemplate", testworkflowsv1.GroupVersion, mappers2.MapTemplateKubeToAPI, obj)
   165  		if err != nil {
   166  			return s.InternalError(c, errPrefix, "serialization problem", err)
   167  		}
   168  		return
   169  	}
   170  }
   171  
   172  func (s *apiTCL) getFilteredTestWorkflowTemplateList(c *fiber.Ctx) (*testworkflowsv1.TestWorkflowTemplateList, error) {
   173  	crTemplates, err := s.TestWorkflowTemplatesClient.List(c.Query("selector"))
   174  	if err != nil {
   175  		return nil, err
   176  	}
   177  
   178  	search := c.Query("textSearch")
   179  	if search != "" {
   180  		search = strings.ReplaceAll(search, "/", "--")
   181  		for i := len(crTemplates.Items) - 1; i >= 0; i-- {
   182  			if !strings.Contains(crTemplates.Items[i].Name, search) {
   183  				crTemplates.Items = append(crTemplates.Items[:i], crTemplates.Items[i+1:]...)
   184  			}
   185  		}
   186  	}
   187  
   188  	return crTemplates, nil
   189  }