mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-19 04:26:39 +00:00
Feat: add the oam application api in apiserver (#2492)
* Feat: oam application api in apiserver * Feat: enable unit-test and e2e-test
This commit is contained in:
@@ -5,11 +5,13 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
- apiserver
|
||||
workflow_dispatch: {}
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
- apiserver
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
|
||||
@@ -48,7 +48,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
kubeClient: k8sClient,
|
||||
}
|
||||
})
|
||||
It("Test CreateApplication funtion", func() {
|
||||
It("Test CreateApplication function", func() {
|
||||
By("test sample create")
|
||||
req := v1.CreateApplicationRequest{
|
||||
Name: "test-app",
|
||||
@@ -106,13 +106,13 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(equal).Should(BeTrue())
|
||||
})
|
||||
|
||||
It("Test ListApplications funtion", func() {
|
||||
It("Test ListApplications function", func() {
|
||||
apps, err := appUsecase.ListApplications(context.TODO())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(len(apps), 2)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test DetailApplication funtion", func() {
|
||||
It("Test DetailApplication function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -123,7 +123,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(cmp.Diff(len(detail.Policies), 1)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test GetWorkflow funtion", func() {
|
||||
It("Test GetWorkflow function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -134,7 +134,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(cmp.Diff(detail.Enable, true)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test ListPolicies funtion", func() {
|
||||
It("Test ListPolicies function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -146,7 +146,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect((*policies[0].Properties)["envs"]).ShouldNot(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test ListComponents funtion", func() {
|
||||
It("Test ListComponents function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -158,7 +158,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(components[1].UpdateTime).ShouldNot(BeNil())
|
||||
})
|
||||
|
||||
It("Test DetailComponent funtion", func() {
|
||||
It("Test DetailComponent function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -170,7 +170,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(cmp.Diff(strings.Contains((*detail.Properties)["image"].(string), "crccheck/hello-world"), true)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test DetailPolicy funtion", func() {
|
||||
It("Test DetailPolicy function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -180,7 +180,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(cmp.Diff(detail.Type, "env-binding")).Should(BeEmpty())
|
||||
Expect((*detail.Properties)["envs"]).ShouldNot(BeEmpty())
|
||||
})
|
||||
It("Test AddComponent funtion", func() {
|
||||
It("Test AddComponent function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -195,7 +195,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(base.ComponentType, "worker")).Should(BeEmpty())
|
||||
})
|
||||
It("Test DetailComponent funtion", func() {
|
||||
It("Test DetailComponent function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -206,7 +206,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(cmp.Diff((*detailResponse.Properties)["image"], "busybox")).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test AddPolicy funtion", func() {
|
||||
It("Test AddPolicy function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -225,7 +225,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
It("Test DetailPolicy funtion", func() {
|
||||
It("Test DetailPolicy function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -234,7 +234,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(detail.Properties).ShouldNot(BeNil())
|
||||
Expect((*detail.Properties)["envs"]).ShouldNot(BeEmpty())
|
||||
})
|
||||
It("Test UpdatePolicy funtion", func() {
|
||||
It("Test UpdatePolicy function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -246,21 +246,21 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(base.Properties).ShouldNot(BeNil())
|
||||
Expect((*base.Properties)["envs"]).Should(BeEmpty())
|
||||
})
|
||||
It("Test DeletePolicy funtion", func() {
|
||||
It("Test DeletePolicy function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
err = appUsecase.DeletePolicy(context.TODO(), appModel, "env-binding-2")
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
It("Test DeleteComponent funtion", func() {
|
||||
It("Test DeleteComponent function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
err = appUsecase.DeleteComponent(context.TODO(), appModel, "test2")
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
It("Test Deploy Application funtion", func() {
|
||||
It("Test Deploy Application function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(appModel.Namespace, "test-app-namespace")).Should(BeEmpty())
|
||||
@@ -277,7 +277,7 @@ var _ = Describe("Test application usecase function", func() {
|
||||
Expect(cmp.Diff(len(oam.Spec.Components), 2)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(len(oam.Spec.Policies), 1)).Should(BeEmpty())
|
||||
})
|
||||
It("Test DeleteApplication funtion", func() {
|
||||
It("Test DeleteApplication function", func() {
|
||||
appModel, err := appUsecase.GetApplication(context.TODO(), "test-app-sadasd")
|
||||
Expect(err).Should(BeNil())
|
||||
err = appUsecase.DeleteApplication(context.TODO(), appModel)
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
Copyright 2021. The KubeVela Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/clients"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
)
|
||||
|
||||
// OAMApplicationUsecase oam_application usecase
|
||||
type OAMApplicationUsecase interface {
|
||||
CreateOrUpdateOAMApplication(context.Context, apisv1.ApplicationRequest, string, string) error
|
||||
GetOAMApplication(context.Context, string, string) (*apisv1.ApplicationResponse, error)
|
||||
DeleteOAMApplication(context.Context, string, string) error
|
||||
}
|
||||
|
||||
// NewOAMApplicationUsecase new oam_application usecase
|
||||
func NewOAMApplicationUsecase() OAMApplicationUsecase {
|
||||
kubeClient, _ := clients.GetKubeClient()
|
||||
return &oamApplicationUsecaseImpl{kubeClient: kubeClient}
|
||||
}
|
||||
|
||||
type oamApplicationUsecaseImpl struct {
|
||||
kubeClient client.Client
|
||||
}
|
||||
|
||||
// CreateOrUpdateOAMApplication create or update application
|
||||
func (o oamApplicationUsecaseImpl) CreateOrUpdateOAMApplication(ctx context.Context, request apisv1.ApplicationRequest, name, namespace string) error {
|
||||
ns := new(v1.Namespace)
|
||||
err := o.kubeClient.Get(ctx, client.ObjectKey{Name: namespace}, ns)
|
||||
if kerrors.IsNotFound(err) {
|
||||
ns.Name = namespace
|
||||
if err = o.kubeClient.Create(ctx, ns); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
app := &v1beta1.Application{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: v1beta1.ApplicationSpec{
|
||||
Components: request.Components,
|
||||
Policies: request.Policies,
|
||||
Workflow: request.Workflow,
|
||||
},
|
||||
}
|
||||
|
||||
existApp := new(v1beta1.Application)
|
||||
err = o.kubeClient.Get(ctx, client.ObjectKey{Name: name, Namespace: namespace}, existApp)
|
||||
if err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
return o.kubeClient.Create(ctx, app)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
existApp.Spec = app.Spec
|
||||
return o.kubeClient.Update(ctx, existApp)
|
||||
}
|
||||
|
||||
// GetOAMApplication get application
|
||||
func (o oamApplicationUsecaseImpl) GetOAMApplication(ctx context.Context, name, namespace string) (*apisv1.ApplicationResponse, error) {
|
||||
app := new(v1beta1.Application)
|
||||
if err := o.kubeClient.Get(ctx, client.ObjectKey{Name: name, Namespace: namespace}, app); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &apisv1.ApplicationResponse{
|
||||
APIVersion: app.APIVersion,
|
||||
Kind: app.Kind,
|
||||
Spec: app.Spec,
|
||||
Status: app.Status,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteOAMApplication delete application
|
||||
func (o oamApplicationUsecaseImpl) DeleteOAMApplication(ctx context.Context, name, namespace string) error {
|
||||
return client.IgnoreNotFound(o.kubeClient.Delete(ctx, &v1beta1.Application{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
}))
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright 2021. The KubeVela Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
apiv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
)
|
||||
|
||||
var _ = Describe("Test oam application usecase function", func() {
|
||||
var oamAppUsecase *oamApplicationUsecaseImpl
|
||||
var ctx context.Context
|
||||
var baseApp v1beta1.Application
|
||||
var ns corev1.Namespace
|
||||
var namespace string
|
||||
|
||||
BeforeEach(func() {
|
||||
ctx = context.Background()
|
||||
namespace = randomNamespaceName("test-oam-app")
|
||||
ns = corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}
|
||||
oamAppUsecase = &oamApplicationUsecaseImpl{
|
||||
kubeClient: k8sClient,
|
||||
}
|
||||
Expect(common.ReadYamlToObject("./testdata/example-app.yaml", &baseApp)).Should(BeNil())
|
||||
|
||||
Eventually(func() error {
|
||||
return k8sClient.Create(ctx, &ns)
|
||||
}, time.Second*3, time.Microsecond*300).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
baseApp.SetNamespace(namespace)
|
||||
Eventually(func() error {
|
||||
return k8sClient.Create(ctx, &baseApp)
|
||||
}, time.Second*3, time.Microsecond*300).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
By("Clean up resources after a test")
|
||||
k8sClient.DeleteAllOf(ctx, &v1beta1.Application{}, client.InNamespace(namespace))
|
||||
baseApp = v1beta1.Application{}
|
||||
By(fmt.Sprintf("Delete the entire namespaceName %s", ns.Name))
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(Succeed())
|
||||
})
|
||||
|
||||
It("Test CreateOrUpdateOAMApplication function", func() {
|
||||
By("test create application")
|
||||
appName := "test-new-app"
|
||||
appNs := randomNamespaceName("test-new-app")
|
||||
req := apiv1.ApplicationRequest{
|
||||
Components: baseApp.Spec.Components,
|
||||
Policies: baseApp.Spec.Policies,
|
||||
Workflow: baseApp.Spec.Workflow,
|
||||
}
|
||||
Expect(oamAppUsecase.CreateOrUpdateOAMApplication(ctx, req, appName, appNs)).Should(BeNil())
|
||||
|
||||
app := new(v1beta1.Application)
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: appNs, Name: appName}, app)).Should(BeNil())
|
||||
Expect(app.Spec.Components).Should(Equal(req.Components))
|
||||
Expect(app.Spec.Policies).Should(Equal(req.Policies))
|
||||
Expect(app.Spec.Workflow).Should(Equal(req.Workflow))
|
||||
|
||||
By("test update application")
|
||||
updateReq := apiv1.ApplicationRequest{
|
||||
Components: baseApp.Spec.Components[1:],
|
||||
}
|
||||
Expect(oamAppUsecase.CreateOrUpdateOAMApplication(ctx, updateReq, appName, appNs)).Should(BeNil())
|
||||
|
||||
updatedApp := new(v1beta1.Application)
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: appNs, Name: appName}, updatedApp)).Should(BeNil())
|
||||
Expect(updatedApp.Spec.Components).Should(Equal(updateReq.Components))
|
||||
Expect(updatedApp.Spec.Policies).Should(BeNil())
|
||||
Expect(updatedApp.Spec.Workflow).Should(BeNil())
|
||||
})
|
||||
|
||||
It("Test GetOAMApplication function", func() {
|
||||
By("test get an existed application")
|
||||
resp, err := oamAppUsecase.GetOAMApplication(ctx, baseApp.Name, namespace)
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
Expect(resp.Spec.Components).Should(Equal(baseApp.Spec.Components))
|
||||
Expect(resp.Spec.Policies).Should(Equal(baseApp.Spec.Policies))
|
||||
Expect(resp.Spec.Workflow).Should(Equal(baseApp.Spec.Workflow))
|
||||
})
|
||||
|
||||
It("Test DeleteOAMApplication function", func() {
|
||||
By("test delete application")
|
||||
app := new(v1beta1.Application)
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: baseApp.Name}, app)).Should(BeNil())
|
||||
|
||||
Expect(oamAppUsecase.DeleteOAMApplication(ctx, baseApp.Name, namespace)).Should(BeNil())
|
||||
err := k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: baseApp.Name}, app)
|
||||
Expect(kerrors.IsNotFound(err)).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -100,3 +101,7 @@ func TestUsecase(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Usecase Suite")
|
||||
}
|
||||
|
||||
func randomNamespaceName(basic string) string {
|
||||
return fmt.Sprintf("%s-%s", basic, strconv.FormatInt(rand.Int63(), 16))
|
||||
}
|
||||
|
||||
@@ -18,12 +18,23 @@ package webservice
|
||||
|
||||
import (
|
||||
restfulspec "github.com/emicklei/go-restful-openapi/v2"
|
||||
restful "github.com/emicklei/go-restful/v3"
|
||||
"github.com/emicklei/go-restful/v3"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/log"
|
||||
apis "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/usecase"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils/bcode"
|
||||
)
|
||||
|
||||
type oamApplicationWebService struct {
|
||||
oamApplicationUsecase usecase.OAMApplicationUsecase
|
||||
}
|
||||
|
||||
// NewOAMApplication new oam application
|
||||
func NewOAMApplication(oamApplicationUsecase usecase.OAMApplicationUsecase) WebService {
|
||||
return &oamApplicationWebService{
|
||||
oamApplicationUsecase: oamApplicationUsecase,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *oamApplicationWebService) GetWebService() *restful.WebService {
|
||||
@@ -35,24 +46,82 @@ func (c *oamApplicationWebService) GetWebService() *restful.WebService {
|
||||
|
||||
tags := []string{"oam"}
|
||||
|
||||
ws.Route(ws.GET("/{namespace}/applications/:appname").To(noop).
|
||||
ws.Route(ws.GET("/namespaces/{namespace}/applications/{appname}").To(c.getApplication).
|
||||
Doc("get the specified oam application in the specified namespace").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Param(ws.PathParameter("namespace", "identifier of the namespace").DataType("string")).
|
||||
Param(ws.PathParameter("appname", "identifier of the oam application").DataType("string")).
|
||||
Writes(apis.ApplicationResponse{}))
|
||||
|
||||
ws.Route(ws.POST("/{namespace}/applications/{appname}").To(noop).
|
||||
ws.Route(ws.POST("/namespaces/{namespace}/applications/{appname}").To(c.createOrUpdateApplication).
|
||||
Doc("create or update oam application in the specified namespace").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Param(ws.PathParameter("namespace", "identifier of the namespace").DataType("string")).
|
||||
Param(ws.PathParameter("appname", "identifier of the oam application").DataType("string")).
|
||||
Reads(apis.ApplicationRequest{}))
|
||||
|
||||
ws.Route(ws.DELETE("/{namespace}/applications/:appname").To(noop).
|
||||
ws.Route(ws.DELETE("/namespaces/{namespace}/applications/{appname}").To(c.deleteApplication).
|
||||
Doc("create or update oam application in the specified namespace").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Param(ws.PathParameter("namespace", "identifier of the namespace").DataType("string")).
|
||||
Param(ws.PathParameter("appname", "identifier of the oam application").DataType("string")))
|
||||
|
||||
return ws
|
||||
}
|
||||
|
||||
func (c *oamApplicationWebService) getApplication(req *restful.Request, res *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
appName := req.PathParameter("appname")
|
||||
appRes, err := c.oamApplicationUsecase.GetOAMApplication(req.Request.Context(), appName, namespace)
|
||||
if err != nil {
|
||||
log.Logger.Errorf("get application failure %s", err.Error())
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Write back response data
|
||||
if err := res.WriteEntity(appRes); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (c *oamApplicationWebService) createOrUpdateApplication(req *restful.Request, res *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
appName := req.PathParameter("appname")
|
||||
|
||||
var createReq apis.ApplicationRequest
|
||||
if err := req.ReadEntity(&createReq); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
|
||||
err := c.oamApplicationUsecase.CreateOrUpdateOAMApplication(req.Request.Context(), createReq, appName, namespace)
|
||||
if err != nil {
|
||||
log.Logger.Errorf("create application failure %s", err.Error())
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := res.WriteEntity(apis.EmptyResponse{}); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (c *oamApplicationWebService) deleteApplication(req *restful.Request, res *restful.Response) {
|
||||
namespace := req.PathParameter("namespace")
|
||||
appName := req.PathParameter("appname")
|
||||
|
||||
err := c.oamApplicationUsecase.DeleteOAMApplication(req.Request.Context(), appName, namespace)
|
||||
if err != nil {
|
||||
log.Logger.Errorf("delete application failure %s", err.Error())
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := res.WriteEntity(apis.EmptyResponse{}); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,12 +62,13 @@ func Init(ctx context.Context, ds datastore.DataStore) {
|
||||
clusterUsecase := usecase.NewClusterUsecase(ds)
|
||||
workflowUsecase := usecase.NewWorkflowUsecase(ds)
|
||||
applicationUsecase := usecase.NewApplicationUsecase(ds, workflowUsecase)
|
||||
oamApplicationUsecase := usecase.NewOAMApplicationUsecase()
|
||||
RegistWebService(NewClusterWebService(clusterUsecase))
|
||||
RegistWebService(NewApplicationWebService(applicationUsecase))
|
||||
RegistWebService(&namespaceWebService{})
|
||||
RegistWebService(&componentDefinitionWebservice{})
|
||||
RegistWebService(&addonWebService{})
|
||||
RegistWebService(&oamApplicationWebService{})
|
||||
RegistWebService(NewOAMApplication(oamApplicationUsecase))
|
||||
RegistWebService(&policyDefinitionWebservice{})
|
||||
RegistWebService(NewWorkflowWebService(workflowUsecase, applicationUsecase))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright 2021. The KubeVela Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package e2e_apiserver_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
apiv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
)
|
||||
|
||||
var _ = Describe("Test oam application rest api", func() {
|
||||
namespace := "test-oam-app"
|
||||
appName := "example-app"
|
||||
var app v1beta1.Application
|
||||
|
||||
It("Test create and update oam app", func() {
|
||||
defer GinkgoRecover()
|
||||
By("test create app")
|
||||
|
||||
Expect(common.ReadYamlToObject("./testdata/example-app.yaml", &app)).Should(BeNil())
|
||||
req := apiv1.ApplicationRequest{
|
||||
Components: app.Spec.Components,
|
||||
Policies: app.Spec.Policies,
|
||||
Workflow: app.Spec.Workflow,
|
||||
}
|
||||
bodyByte, err := json.Marshal(req)
|
||||
Expect(err).Should(BeNil())
|
||||
res, err := http.Post(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/v1/namespaces/%s/applications/%s", namespace, appName),
|
||||
"application/json",
|
||||
bytes.NewBuffer(bodyByte),
|
||||
)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
Expect(cmp.Diff(res.StatusCode, 200)).Should(BeEmpty())
|
||||
Expect(res.Body).ShouldNot(BeNil())
|
||||
defer res.Body.Close()
|
||||
|
||||
ctx := context.Background()
|
||||
oldApp := new(v1beta1.Application)
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{Name: appName, Namespace: namespace}, oldApp)).Should(BeNil())
|
||||
Expect(oldApp.Spec.Components).Should(Equal(req.Components))
|
||||
Expect(oldApp.Spec.Policies).Should(Equal(req.Policies))
|
||||
Expect(oldApp.Spec.Workflow).Should(Equal(req.Workflow))
|
||||
|
||||
By("test update app")
|
||||
updateReq := apiv1.ApplicationRequest{
|
||||
Components: app.Spec.Components[1:],
|
||||
}
|
||||
bodyByte, err = json.Marshal(updateReq)
|
||||
Expect(err).Should(BeNil())
|
||||
res, err = http.Post(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/v1/namespaces/%s/applications/%s", namespace, appName),
|
||||
"application/json",
|
||||
bytes.NewBuffer(bodyByte),
|
||||
)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
Expect(cmp.Diff(res.StatusCode, 200)).Should(BeEmpty())
|
||||
Expect(res.Body).ShouldNot(BeNil())
|
||||
defer res.Body.Close()
|
||||
|
||||
newApp := new(v1beta1.Application)
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{Name: appName, Namespace: namespace}, newApp)).Should(BeNil())
|
||||
Expect(newApp.Spec.Components).Should(Equal(updateReq.Components))
|
||||
Expect(newApp.Spec.Policies).Should(BeNil())
|
||||
Expect(newApp.Spec.Workflow).Should(BeNil())
|
||||
})
|
||||
|
||||
It("Test get oam app", func() {
|
||||
defer GinkgoRecover()
|
||||
res, err := http.Get(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/v1/namespaces/%s/applications/%s", namespace, appName),
|
||||
)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
|
||||
defer res.Body.Close()
|
||||
var appResp apiv1.ApplicationResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&appResp)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
|
||||
Expect(len(appResp.Spec.Components)).Should(Equal(1))
|
||||
})
|
||||
|
||||
It("Test delete oam app", func() {
|
||||
defer GinkgoRecover()
|
||||
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("http://127.0.0.1:8000/v1/namespaces/%s/applications/%s", namespace, appName), nil)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
Expect(cmp.Diff(res.StatusCode, 200)).Should(BeEmpty())
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user