mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-19 04:26:39 +00:00
Feat: add get and delete method for app and test (#2127)
This commit is contained in:
@@ -27,3 +27,11 @@ type ApplicationRequest struct {
|
||||
Policies []v1beta1.AppPolicy `json:"policies,omitempty"`
|
||||
Workflow *v1beta1.Workflow `json:"workflow,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationResponse represents application response for APIServer
|
||||
type ApplicationResponse struct {
|
||||
APIVersion string `json:"apiVersion"`
|
||||
Kind string `json:"kind"`
|
||||
Spec v1beta1.ApplicationSpec `json:"spec"`
|
||||
Status common.AppStatus `json:"status"`
|
||||
}
|
||||
|
||||
@@ -106,7 +106,9 @@ func (s *restServer) registerServices() error {
|
||||
|
||||
// application
|
||||
applicationService := services.NewApplicationService(s.k8sClient)
|
||||
openapi.GET("/namespaces/:namespace/applications/:appname", applicationService.GetApplication)
|
||||
openapi.POST("/namespaces/:namespace/applications/:appname", applicationService.CreateOrUpdateApplication)
|
||||
openapi.DELETE("/namespaces/:namespace/applications/:appname", applicationService.DeleteApplication)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -40,8 +40,34 @@ func NewApplicationService(kc client.Client) *ApplicationService {
|
||||
}
|
||||
}
|
||||
|
||||
// GetApplication will get application status
|
||||
// GET /namespaces/<namespace>/applications/<appname>
|
||||
func (s *ApplicationService) GetApplication(c echo.Context) error {
|
||||
namespace := c.Param("namespace")
|
||||
appName := c.Param("appname")
|
||||
|
||||
ctx := context.TODO()
|
||||
var existApp v1beta1.Application
|
||||
err := s.k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: appName}, &existApp)
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return c.JSON(http.StatusNotFound, map[string]string{"error": "application does not exist: " + err.Error()})
|
||||
}
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "fail to get application: " + err.Error()})
|
||||
}
|
||||
|
||||
var appResp = &apis.ApplicationResponse{
|
||||
APIVersion: existApp.APIVersion,
|
||||
Kind: existApp.Kind,
|
||||
Spec: existApp.Spec,
|
||||
Status: existApp.Status,
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, appResp)
|
||||
}
|
||||
|
||||
// CreateOrUpdateApplication will create or update application
|
||||
// POST /v1/namespaces/<namespace>/applications/<appname>
|
||||
// POST /namespaces/<namespace>/applications/<appname>
|
||||
func (s *ApplicationService) CreateOrUpdateApplication(c echo.Context) error {
|
||||
namespace := c.Param("namespace")
|
||||
name := c.Param("appname")
|
||||
@@ -74,3 +100,23 @@ func (s *ApplicationService) CreateOrUpdateApplication(c echo.Context) error {
|
||||
}
|
||||
return c.JSON(http.StatusOK, struct{}{})
|
||||
}
|
||||
|
||||
// DeleteApplication will delete application
|
||||
// delete /v1/namespaces/<namespace>/applications/<appname>
|
||||
func (s *ApplicationService) DeleteApplication(c echo.Context) error {
|
||||
namespace := c.Param("namespace")
|
||||
appName := c.Param("appname")
|
||||
|
||||
ctx := context.TODO()
|
||||
var existApp v1beta1.Application
|
||||
existApp.Namespace = namespace
|
||||
existApp.Name = appName
|
||||
err := s.k8sClient.Delete(ctx, &existApp)
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return c.JSON(http.StatusNotFound, map[string]string{"error": "application does not exist: " + err.Error()})
|
||||
}
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "fail to delete application: " + err.Error()})
|
||||
}
|
||||
return c.JSON(http.StatusOK, struct{}{})
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
@@ -112,19 +113,160 @@ func TestApplicationCreateOrUpdate(t *testing.T) {
|
||||
|
||||
// check response
|
||||
assert.Equal(t, c.expHttpCode, rec.Code, casename)
|
||||
gotResp := map[string]string{}
|
||||
err = json.Unmarshal(rec.Body.Bytes(), &gotResp)
|
||||
assert.NoError(t, err, casename)
|
||||
if c.expErr != "" {
|
||||
if c.expErr != "" { // compare return error with map type
|
||||
gotResp := map[string]string{}
|
||||
err = json.Unmarshal(rec.Body.Bytes(), &gotResp)
|
||||
assert.NoError(t, err, casename)
|
||||
assert.True(t, strings.Contains(gotResp["error"], c.expErr), casename)
|
||||
} else { // check app spec in fake cluster
|
||||
var appObj v1beta1.Application
|
||||
err = cw.Get(context.TODO(), client.ObjectKey{Namespace: c.namespace, Name: c.name}, &appObj)
|
||||
assert.NoError(t, err, casename)
|
||||
assert.Equal(t, c.expApp.Spec, appObj.Spec, casename)
|
||||
}
|
||||
|
||||
if len(c.expErr) > 0 {
|
||||
continue
|
||||
}
|
||||
var appObj v1beta1.Application
|
||||
err = cw.Get(context.TODO(), client.ObjectKey{Namespace: c.namespace, Name: c.name}, &appObj)
|
||||
assert.NoError(t, err, casename)
|
||||
assert.Equal(t, c.expApp.Spec, appObj.Spec, casename)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplicationGet(t *testing.T) {
|
||||
cw := fake.NewClientBuilder().WithScheme(common.Scheme).Build()
|
||||
appSvc := NewApplicationService(cw)
|
||||
|
||||
tests := map[string]struct {
|
||||
rawReq []byte
|
||||
name string
|
||||
namespace string
|
||||
expHttpCode int
|
||||
expErr string
|
||||
expApp *v1beta1.Application
|
||||
}{
|
||||
"normal get method for application": {
|
||||
expHttpCode: 200,
|
||||
name: "commonName",
|
||||
namespace: "commonNamespace",
|
||||
},
|
||||
"get app failed with resource not found": {
|
||||
expHttpCode: 404,
|
||||
name: "notExistName",
|
||||
namespace: "commonNamespace",
|
||||
expErr: "application does not exist",
|
||||
},
|
||||
}
|
||||
// create an application for get
|
||||
createAppForTest(t, appSvc)
|
||||
|
||||
for casename, c := range tests {
|
||||
var err error
|
||||
req := httptest.NewRequest(http.MethodGet, "/", bytes.NewBuffer(c.rawReq))
|
||||
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
||||
rec := httptest.NewRecorder()
|
||||
echoCtx := echo.New().NewContext(req, rec)
|
||||
echoCtx.SetParamNames("namespace", "appname")
|
||||
echoCtx.SetParamValues(c.namespace, c.name)
|
||||
|
||||
err = appSvc.GetApplication(echoCtx)
|
||||
assert.NoError(t, err, casename)
|
||||
|
||||
// check response
|
||||
assert.Equal(t, c.expHttpCode, rec.Code, casename)
|
||||
if c.expErr != "" { // compare return error with map type
|
||||
gotResp := map[string]string{}
|
||||
err = json.Unmarshal(rec.Body.Bytes(), &gotResp)
|
||||
assert.NoError(t, err, casename)
|
||||
assert.True(t, strings.Contains(gotResp["error"], c.expErr), casename)
|
||||
} else { // check app spec in fake cluster
|
||||
var gotResp apis.ApplicationResponse
|
||||
err = json.Unmarshal(rec.Body.Bytes(), &gotResp)
|
||||
assert.NoError(t, err, casename)
|
||||
|
||||
var appObj v1beta1.Application
|
||||
err = cw.Get(context.TODO(), client.ObjectKey{Namespace: c.namespace, Name: c.name}, &appObj)
|
||||
assert.NoError(t, err, casename)
|
||||
assert.Equal(t, gotResp.APIVersion, appObj.APIVersion, casename)
|
||||
assert.Equal(t, gotResp.Kind, appObj.Kind, casename)
|
||||
assert.Equal(t, gotResp.Spec, appObj.Spec, casename)
|
||||
assert.Equal(t, gotResp.Status, appObj.Status, casename)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplicationDelete(t *testing.T) {
|
||||
cw := fake.NewClientBuilder().WithScheme(common.Scheme).Build()
|
||||
appSvc := NewApplicationService(cw)
|
||||
|
||||
tests := map[string]struct {
|
||||
rawReq []byte
|
||||
name string
|
||||
namespace string
|
||||
expHttpCode int
|
||||
expErr string
|
||||
}{
|
||||
"normal delete method for application": {
|
||||
expHttpCode: 200,
|
||||
name: "commonName",
|
||||
namespace: "commonNamespace",
|
||||
},
|
||||
"delete app failed with resource not found": {
|
||||
expHttpCode: 404,
|
||||
name: "notExistName",
|
||||
namespace: "commonNamespace",
|
||||
expErr: "application does not exist",
|
||||
},
|
||||
}
|
||||
for casename, c := range tests {
|
||||
// create common app
|
||||
createAppForTest(t, appSvc)
|
||||
var err error
|
||||
req := httptest.NewRequest(http.MethodDelete, "/", bytes.NewBuffer(c.rawReq))
|
||||
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
||||
rec := httptest.NewRecorder()
|
||||
echoCtx := echo.New().NewContext(req, rec)
|
||||
echoCtx.SetParamNames("namespace", "appname")
|
||||
echoCtx.SetParamValues(c.namespace, c.name)
|
||||
|
||||
err = appSvc.DeleteApplication(echoCtx)
|
||||
assert.NoError(t, err, casename)
|
||||
|
||||
// check response
|
||||
assert.Equal(t, c.expHttpCode, rec.Code, casename)
|
||||
if c.expErr != "" {
|
||||
gotResp := map[string]string{}
|
||||
err = json.Unmarshal(rec.Body.Bytes(), &gotResp)
|
||||
assert.NoError(t, err, casename)
|
||||
assert.True(t, strings.Contains(gotResp["error"], c.expErr), casename)
|
||||
} else {
|
||||
// checkout app status in fake cluster
|
||||
var appObj v1beta1.Application
|
||||
err = cw.Get(context.TODO(), client.ObjectKey{Namespace: c.namespace, Name: c.name}, &appObj)
|
||||
assert.Equal(t, apierrors.IsNotFound(err), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createAppForTest(t *testing.T, appSvc *ApplicationService) {
|
||||
appComp := common2.ApplicationComponent{
|
||||
Name: "mycomp",
|
||||
Type: "webservice",
|
||||
Properties: runtime.RawExtension{Raw: []byte(`{"image":"nginx:v1"}`)},
|
||||
}
|
||||
|
||||
var appReq = &apis.ApplicationRequest{
|
||||
Components: []common2.ApplicationComponent{appComp},
|
||||
}
|
||||
|
||||
var rawReq []byte
|
||||
var err error
|
||||
if appReq != nil {
|
||||
rawReq, err = json.Marshal(appReq)
|
||||
assert.NoError(t, err, "marshal request for create app")
|
||||
}
|
||||
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(rawReq))
|
||||
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
||||
rec := httptest.NewRecorder()
|
||||
echoCtx := echo.New().NewContext(req, rec)
|
||||
echoCtx.SetParamNames("namespace", "appname")
|
||||
echoCtx.SetParamValues("commonNamespace", "commonName")
|
||||
|
||||
err = appSvc.CreateOrUpdateApplication(echoCtx)
|
||||
assert.NoError(t, err, "craete application in service")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user