mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-27 16:17:34 +00:00
Merge branch 'apiserver' into merge
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
package e2e_apiserver_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/addon"
|
||||
apis "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
const baseURL = "http://127.0.0.1:8000"
|
||||
|
||||
func post(path string, body interface{}) *http.Response {
|
||||
b, err := json.Marshal(body)
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
res, err := http.Post(baseURL+path, "application/json", bytes.NewBuffer(b))
|
||||
Expect(err).Should(BeNil())
|
||||
return res
|
||||
}
|
||||
|
||||
func get(path string) *http.Response {
|
||||
res, err := http.Get(baseURL + path)
|
||||
Expect(err).Should(BeNil())
|
||||
return res
|
||||
}
|
||||
|
||||
var _ = Describe("Test addon rest api", func() {
|
||||
createReq := apis.CreateAddonRegistryRequest{
|
||||
Name: "test-addon-registry-1",
|
||||
Git: &addon.GitAddonSource{
|
||||
URL: "https://github.com/oam-dev/catalog",
|
||||
Path: "addons/",
|
||||
Token: os.Getenv("GITHUB_TOKEN"),
|
||||
},
|
||||
}
|
||||
It("should add a registry and list addons from it", func() {
|
||||
defer GinkgoRecover()
|
||||
|
||||
By("add registry")
|
||||
createRes := post("/api/v1/addon_registries", createReq)
|
||||
Expect(createRes).ShouldNot(BeNil())
|
||||
Expect(createRes.Body).ShouldNot(BeNil())
|
||||
Expect(createRes.StatusCode).Should(Equal(200))
|
||||
|
||||
defer createRes.Body.Close()
|
||||
|
||||
var rmeta apis.AddonRegistryMeta
|
||||
err := json.NewDecoder(createRes.Body).Decode(&rmeta)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(rmeta.Name).Should(Equal(createReq.Name))
|
||||
Expect(rmeta.Git).Should(Equal(createReq.Git))
|
||||
|
||||
By("list addons")
|
||||
listRes := get("/api/v1/addons/")
|
||||
defer listRes.Body.Close()
|
||||
|
||||
var lres apis.ListAddonResponse
|
||||
err = json.NewDecoder(listRes.Body).Decode(&lres)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(lres.Addons).ShouldNot(BeZero())
|
||||
firstAddon := lres.Addons[0]
|
||||
Expect(firstAddon.Name).Should(Equal("example"))
|
||||
|
||||
})
|
||||
|
||||
It("should enable and disable an addon", func() {
|
||||
defer GinkgoRecover()
|
||||
req := apis.EnableAddonRequest{
|
||||
Args: map[string]string{
|
||||
"example": "test-args",
|
||||
},
|
||||
}
|
||||
testAddon := "example"
|
||||
res := post("/api/v1/addons/"+testAddon+"/enable", req)
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
Expect(res.StatusCode).Should(Equal(200))
|
||||
Expect(res.Body).ShouldNot(BeNil())
|
||||
|
||||
defer res.Body.Close()
|
||||
|
||||
var statusRes apis.AddonStatusResponse
|
||||
err := json.NewDecoder(res.Body).Decode(&statusRes)
|
||||
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(statusRes.Phase).Should(Equal(apis.AddonPhaseEnabling))
|
||||
|
||||
// Wait for addon enabled
|
||||
|
||||
period := 10 * time.Second
|
||||
timeout := 2 * time.Minute
|
||||
Eventually(func() error {
|
||||
res = get("/api/v1/addons/" + testAddon + "/status")
|
||||
err = json.NewDecoder(res.Body).Decode(&statusRes)
|
||||
Expect(err).Should(BeNil())
|
||||
if statusRes.Phase == apis.AddonPhaseEnabled {
|
||||
return nil
|
||||
}
|
||||
var app v1beta1.Application
|
||||
err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "addon-example", Namespace: "vela-system"}, &app)
|
||||
Expect(err).Should(BeNil())
|
||||
data, err := json.Marshal(app)
|
||||
Expect(err).Should(BeNil())
|
||||
fmt.Println(data)
|
||||
return errors.New("not ready")
|
||||
}, timeout, period).Should(BeNil())
|
||||
|
||||
res = post("/api/v1/addons/"+testAddon+"/disable", req)
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
Expect(res.StatusCode).Should(Equal(200))
|
||||
Expect(res.Body).ShouldNot(BeNil())
|
||||
|
||||
err = json.NewDecoder(res.Body).Decode(&statusRes)
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
|
||||
It("should delete test registry", func() {
|
||||
defer GinkgoRecover()
|
||||
deleteReq, err := http.NewRequest(http.MethodDelete, baseURL+"/api/v1/addon_registries/"+createReq.Name, nil)
|
||||
Expect(err).Should(BeNil())
|
||||
deleteRes, err := http.DefaultClient.Do(deleteReq)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(deleteRes).ShouldNot(BeNil())
|
||||
Expect(deleteRes.StatusCode).Should(Equal(200))
|
||||
})
|
||||
})
|
||||
@@ -18,26 +18,34 @@ package e2e_apiserver_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/model"
|
||||
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
)
|
||||
|
||||
var appName = "app-e2e"
|
||||
var appProject = "test-app-project"
|
||||
|
||||
var _ = Describe("Test application rest api", func() {
|
||||
It("Test create app", func() {
|
||||
defer GinkgoRecover()
|
||||
var req = apisv1.CreateApplicationRequest{
|
||||
Name: "test-app-sadasd",
|
||||
Namespace: "test-app-namesapce",
|
||||
Name: appName,
|
||||
Namespace: appProject,
|
||||
Description: "this is a test app",
|
||||
Icon: "",
|
||||
Labels: map[string]string{"test": "true"},
|
||||
ClusterList: []string{},
|
||||
EnvBinding: []*apisv1.EnvBinding{{Name: "dev-env", TargetNames: []string{"test-target"}}},
|
||||
}
|
||||
bodyByte, err := json.Marshal(req)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
@@ -52,6 +60,309 @@ var _ = Describe("Test application rest api", func() {
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(appBase.Name, req.Name)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(appBase.Description, req.Description)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(appBase.Namespace, req.Namespace)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(appBase.Labels["test"], req.Labels["test"])).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test delete app", func() {
|
||||
defer GinkgoRecover()
|
||||
req, err := http.NewRequest(http.MethodDelete, "http://127.0.0.1:8000/api/v1/applications/"+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())
|
||||
})
|
||||
|
||||
It("Test create app with oamspec", func() {
|
||||
defer GinkgoRecover()
|
||||
bs, err := ioutil.ReadFile("./testdata/example-app.yaml")
|
||||
Expect(err).Should(Succeed())
|
||||
var req = apisv1.CreateApplicationRequest{
|
||||
Name: appName,
|
||||
Namespace: appProject,
|
||||
Description: "this is a test app",
|
||||
Icon: "",
|
||||
Labels: map[string]string{"test": "true"},
|
||||
YamlConfig: string(bs),
|
||||
}
|
||||
bodyByte, err := json.Marshal(req)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err := http.Post("http://127.0.0.1:8000/api/v1/applications", "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()
|
||||
var appBase apisv1.ApplicationBase
|
||||
err = json.NewDecoder(res.Body).Decode(&appBase)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(appBase.Name, req.Name)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(appBase.Description, req.Description)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(appBase.Namespace, req.Namespace)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(appBase.Labels["test"], req.Labels["test"])).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test list components", func() {
|
||||
defer GinkgoRecover()
|
||||
res, err := http.Get("http://127.0.0.1:8000/api/v1/applications/" + appName + "/components")
|
||||
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()
|
||||
var components apisv1.ComponentListResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&components)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(len(components.Components), 2)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test detail application", func() {
|
||||
defer GinkgoRecover()
|
||||
res, err := http.Get("http://127.0.0.1:8000/api/v1/applications/" + appName)
|
||||
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()
|
||||
var detail apisv1.DetailApplicationResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&detail)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(len(detail.Policies), 0)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test deploy application", func() {
|
||||
defer GinkgoRecover()
|
||||
var targetName = "dev-default"
|
||||
var envName = "dev"
|
||||
var namespace = "default"
|
||||
// create target
|
||||
var createTarget = apisv1.CreateDeliveryTargetRequest{
|
||||
Name: targetName,
|
||||
Namespace: appProject,
|
||||
Cluster: &apisv1.ClusterTarget{
|
||||
ClusterName: "local",
|
||||
Namespace: namespace,
|
||||
},
|
||||
}
|
||||
bodyByte, err := json.Marshal(createTarget)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err := http.Post("http://127.0.0.1:8000/api/v1/deliveryTargets", "application/json", bytes.NewBuffer(bodyByte))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
Expect(cmp.Diff(res.StatusCode, 200)).Should(BeEmpty())
|
||||
|
||||
// create env
|
||||
var createEnvReq = apisv1.CreateApplicationEnvRequest{
|
||||
EnvBinding: apisv1.EnvBinding{
|
||||
Name: envName,
|
||||
TargetNames: []string{targetName},
|
||||
},
|
||||
}
|
||||
bodyByte, err = json.Marshal(createEnvReq)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err = http.Post("http://127.0.0.1:8000/api/v1/applications/"+appName+"/envs", "application/json", bytes.NewBuffer(bodyByte))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
|
||||
// deploy app
|
||||
var req = apisv1.ApplicationDeployRequest{
|
||||
Note: "test apply",
|
||||
TriggerType: "web",
|
||||
WorkflowName: "dev",
|
||||
Force: false,
|
||||
}
|
||||
bodyByte, err = json.Marshal(req)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err = http.Post("http://127.0.0.1:8000/api/v1/applications/"+appName+"/deploy", "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()
|
||||
var response apisv1.ApplicationDeployResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&response)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(response.Status, model.RevisionStatusRunning)).Should(BeEmpty())
|
||||
|
||||
var oam v1beta1.Application
|
||||
err = k8sClient.Get(context.TODO(), types.NamespacedName{Name: appName + "-" + envName, Namespace: appProject}, &oam)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(len(oam.Spec.Components), 2)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(len(oam.Spec.Policies), 1)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test create component", func() {
|
||||
defer GinkgoRecover()
|
||||
var req = apisv1.CreateComponentRequest{
|
||||
Name: "test2",
|
||||
Description: "this is a test2 component",
|
||||
Labels: map[string]string{},
|
||||
ComponentType: "worker",
|
||||
Properties: `{"image": "busybox","cmd":["sleep", "1000"],"lives": "3","enemies": "alien"}`,
|
||||
DependsOn: []string{"data-worker"},
|
||||
}
|
||||
bodyByte, err := json.Marshal(req)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err := http.Post("http://127.0.0.1:8000/api/v1/applications/"+appName+"/components", "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()
|
||||
var response apisv1.ComponentBase
|
||||
err = json.NewDecoder(res.Body).Decode(&response)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(response.ComponentType, "worker")).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test detail component", func() {
|
||||
defer GinkgoRecover()
|
||||
res, err := http.Get("http://127.0.0.1:8000/api/v1/applications/" + appName + "/components/test2")
|
||||
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()
|
||||
var response apisv1.DetailComponentResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&response)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(len(response.DependsOn), 1)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test add trait", func() {
|
||||
defer GinkgoRecover()
|
||||
var req = apisv1.CreateApplicationTraitRequest{
|
||||
Type: "ingress",
|
||||
Properties: `{"domain": "www.test.com"}`,
|
||||
}
|
||||
bodyByte, err := json.Marshal(req)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err := http.Post("http://127.0.0.1:8000/api/v1/applications/"+appName+"/components/test2/traits", "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()
|
||||
var response apisv1.ApplicationTrait
|
||||
err = json.NewDecoder(res.Body).Decode(&response)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(response.Properties.JSON(), `{"domain":"www.test.com"}`)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test update trait", func() {
|
||||
defer GinkgoRecover()
|
||||
var req2 = apisv1.CreateApplicationTraitRequest{
|
||||
Type: "ingress",
|
||||
Properties: `{"domain": "www.test1.com"}`,
|
||||
}
|
||||
bodyByte, err := json.Marshal(req2)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
req, err := http.NewRequest(http.MethodPut, "http://127.0.0.1:8000/api/v1/applications/"+appName+"/components/test2/traits/ingress", bytes.NewBuffer(bodyByte))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
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()
|
||||
var response apisv1.ApplicationTrait
|
||||
err = json.NewDecoder(res.Body).Decode(&response)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(response.Properties.JSON(), `{"domain":"www.test1.com"}`)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test delete trait", func() {
|
||||
defer GinkgoRecover()
|
||||
req, err := http.NewRequest(http.MethodDelete, "http://127.0.0.1:8000/api/v1/applications/"+appName+"/components/test2/traits/ingress", 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())
|
||||
})
|
||||
|
||||
It("Test create application policy", func() {
|
||||
defer GinkgoRecover()
|
||||
var req = apisv1.CreatePolicyRequest{
|
||||
Name: "test2",
|
||||
Description: "this is a test2 component",
|
||||
Properties: `{"image": "busybox","cmd":["sleep", "1000"],"lives": "3","enemies": "alien"}`,
|
||||
}
|
||||
bodyByte, err := json.Marshal(req)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err := http.Post("http://127.0.0.1:8000/api/v1/applications/"+appName+"/policies", "application/json", bytes.NewBuffer(bodyByte))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
Expect(cmp.Diff(res.StatusCode, 400)).Should(BeEmpty())
|
||||
var req2 = apisv1.CreatePolicyRequest{
|
||||
Name: "test2",
|
||||
Description: "this is a test2 policy",
|
||||
Type: "wqsdasd",
|
||||
Properties: `{"image": "busybox","cmd":["sleep", "1000"],"lives": "3","enemies": "alien"}`,
|
||||
}
|
||||
bodyByte2, err := json.Marshal(req2)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err = http.Post("http://127.0.0.1:8000/api/v1/applications/"+appName+"/policies", "application/json", bytes.NewBuffer(bodyByte2))
|
||||
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()
|
||||
var response apisv1.PolicyBase
|
||||
err = json.NewDecoder(res.Body).Decode(&response)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(response.Type, "wqsdasd")).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test detail application policy", func() {
|
||||
defer GinkgoRecover()
|
||||
res, err := http.Get("http://127.0.0.1:8000/api/v1/applications/" + appName + "/policies/test2")
|
||||
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()
|
||||
var response apisv1.DetailPolicyResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&response)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(response.Description, "this is a test2 policy")).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test update application policy", func() {
|
||||
var req2 = apisv1.UpdatePolicyRequest{
|
||||
Description: "this is a test2 policy update",
|
||||
Type: "wqsdasd",
|
||||
Properties: `{"image": "busybox","cmd":["sleep", "1000"],"lives": "3","enemies": "alien"}`,
|
||||
}
|
||||
bodyByte2, err := json.Marshal(req2)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
req, err := http.NewRequest(http.MethodPut, "http://127.0.0.1:8000/api/v1/applications/"+appName+"/policies/test2", bytes.NewBuffer(bodyByte2))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
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()
|
||||
var response apisv1.PolicyBase
|
||||
err = json.NewDecoder(res.Body).Decode(&response)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(response.Description, "this is a test2 policy update")).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test delete application policy", func() {
|
||||
defer GinkgoRecover()
|
||||
req, err := http.NewRequest(http.MethodDelete, "http://127.0.0.1:8000/api/v1/applications/"+appName+"/policies/test2", 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())
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
v1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/multicluster"
|
||||
util "github.com/oam-dev/kubevela/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
WorkerClusterName = "cluster-worker"
|
||||
WorkerClusterKubeConfigPath = "/tmp/worker.kubeconfig"
|
||||
)
|
||||
|
||||
var _ = Describe("Test cluster rest api", func() {
|
||||
|
||||
Context("Test basic cluster CURD", func() {
|
||||
|
||||
var clusterName string
|
||||
|
||||
BeforeEach(func() {
|
||||
clusterName = WorkerClusterName + "-" + util.RandomString(8)
|
||||
kubeconfigBytes, err := ioutil.ReadFile(WorkerClusterKubeConfigPath)
|
||||
Expect(err).Should(Succeed())
|
||||
resp, err := CreateRequest(http.MethodPost, "/clusters", v1.CreateClusterRequest{
|
||||
Name: clusterName,
|
||||
KubeConfig: string(kubeconfigBytes),
|
||||
})
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(resp.StatusCode).Should(Equal(200))
|
||||
Expect(resp.Body).ShouldNot(BeNil())
|
||||
Expect(resp.Body.Close()).Should(Succeed())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
resp, err := CreateRequest(http.MethodDelete, "/clusters/"+clusterName, nil)
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(resp.StatusCode).Should(Equal(200))
|
||||
Expect(resp.Body).ShouldNot(BeNil())
|
||||
Expect(resp.Body.Close()).Should(Succeed())
|
||||
})
|
||||
|
||||
It("Test get cluster", func() {
|
||||
resp, err := CreateRequest(http.MethodGet, "/clusters/"+clusterName, nil)
|
||||
clusterResp := &v1.DetailClusterResponse{}
|
||||
Expect(DecodeResponseBody(resp, err, clusterResp)).Should(Succeed())
|
||||
Expect(clusterResp.Status).Should(Equal("Healthy"))
|
||||
})
|
||||
|
||||
It("Test list clusters", func() {
|
||||
resp, err := CreateRequest(http.MethodGet, "/clusters/?page=1&pageSize=5", nil)
|
||||
clusterResp := &v1.ListClusterResponse{}
|
||||
Expect(DecodeResponseBody(resp, err, clusterResp)).Should(Succeed())
|
||||
Expect(len(clusterResp.Clusters) >= 2).Should(BeTrue())
|
||||
Expect(clusterResp.Clusters[0].Name).Should(Equal(multicluster.ClusterLocalName))
|
||||
Expect(clusterResp.Clusters[1].Name).Should(Equal(clusterName))
|
||||
resp, err = CreateRequest(http.MethodGet, "/clusters/?page=1&pageSize=5&query="+WorkerClusterName, nil)
|
||||
clusterResp = &v1.ListClusterResponse{}
|
||||
Expect(DecodeResponseBody(resp, err, clusterResp)).Should(Succeed())
|
||||
Expect(len(clusterResp.Clusters) >= 1).Should(BeTrue())
|
||||
Expect(clusterResp.Clusters[0].Name).Should(Equal(clusterName))
|
||||
})
|
||||
|
||||
It("Test modify cluster", func() {
|
||||
kubeconfigBytes, err := ioutil.ReadFile(WorkerClusterKubeConfigPath)
|
||||
Expect(err).Should(Succeed())
|
||||
resp, err := CreateRequest(http.MethodPut, "/clusters/"+clusterName, v1.CreateClusterRequest{
|
||||
Name: clusterName,
|
||||
KubeConfig: string(kubeconfigBytes),
|
||||
Description: "Example description",
|
||||
})
|
||||
clusterResp := &v1.ClusterBase{}
|
||||
Expect(DecodeResponseBody(resp, err, clusterResp)).Should(Succeed())
|
||||
Expect(clusterResp.Description).ShouldNot(Equal(""))
|
||||
})
|
||||
|
||||
It("Test create ns in cluster", func() {
|
||||
testNamespace := fmt.Sprintf("test-%d", time.Now().Unix())
|
||||
resp, err := CreateRequest(http.MethodPost, "/clusters/"+clusterName+"/namespaces", v1.CreateClusterNamespaceRequest{Namespace: testNamespace})
|
||||
Expect(err).Should(Succeed())
|
||||
nsResp := &v1.CreateClusterNamespaceResponse{}
|
||||
Expect(DecodeResponseBody(resp, err, nsResp)).Should(Succeed())
|
||||
Expect(nsResp.Exists).Should(Equal(false))
|
||||
resp, err = CreateRequest(http.MethodPost, "/clusters/"+clusterName+"/namespaces", v1.CreateClusterNamespaceRequest{Namespace: testNamespace})
|
||||
Expect(err).Should(Succeed())
|
||||
nsResp = &v1.CreateClusterNamespaceResponse{}
|
||||
Expect(DecodeResponseBody(resp, err, nsResp)).Should(Succeed())
|
||||
Expect(nsResp.Exists).Should(Equal(true))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
PContext("Test cloud cluster rest api", func() {
|
||||
|
||||
var clusterName string
|
||||
|
||||
BeforeEach(func() {
|
||||
clusterName = WorkerClusterName + "-" + util.RandomString(8)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
resp, err := CreateRequest(http.MethodDelete, "/clusters/"+clusterName, nil)
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(resp.StatusCode).Should(Equal(200))
|
||||
Expect(resp.Body).ShouldNot(BeNil())
|
||||
Expect(resp.Body.Close()).Should(Succeed())
|
||||
})
|
||||
|
||||
It("Test list aliyun cloud cluster and connect", func() {
|
||||
AccessKeyID := os.Getenv("ALIYUN_ACCESS_KEY_ID")
|
||||
AccessKeySecret := os.Getenv("ALIYUN_ACCESS_KEY_SECRET")
|
||||
resp, err := CreateRequest(http.MethodPost, "/clusters/cloud-clusters/aliyun/?page=1&pageSize=5", v1.AccessKeyRequest{
|
||||
AccessKeyID: AccessKeyID,
|
||||
AccessKeySecret: AccessKeySecret,
|
||||
})
|
||||
clusterResp := &v1.ListCloudClusterResponse{}
|
||||
Expect(DecodeResponseBody(resp, err, clusterResp)).Should(Succeed())
|
||||
Expect(len(clusterResp.Clusters)).ShouldNot(Equal(0))
|
||||
|
||||
ClusterID := clusterResp.Clusters[0].ID
|
||||
resp, err = CreateRequest(http.MethodPost, "/clusters/cloud-clusters/aliyun/connect", v1.ConnectCloudClusterRequest{
|
||||
AccessKeyID: AccessKeyID,
|
||||
AccessKeySecret: AccessKeySecret,
|
||||
ClusterID: ClusterID,
|
||||
Name: clusterName,
|
||||
})
|
||||
clusterBase := &v1.ClusterBase{}
|
||||
Expect(DecodeResponseBody(resp, err, clusterBase)).Should(Succeed())
|
||||
Expect(clusterBase.Status).Should(Equal("Healthy"))
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
)
|
||||
|
||||
var _ = Describe("Test definitions rest api", func() {
|
||||
|
||||
It("Test list definitions", func() {
|
||||
defer GinkgoRecover()
|
||||
res, err := http.Get("http://127.0.0.1:8000/api/v1/definitions?type=component")
|
||||
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()
|
||||
var definitions apisv1.ListDefinitionResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&definitions)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
|
||||
})
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
|
||||
)
|
||||
|
||||
var _ = Describe("Test namespace rest api", func() {
|
||||
It("Test create namespace", func() {
|
||||
defer GinkgoRecover()
|
||||
var req = apisv1.CreateNamespaceRequest{
|
||||
Name: "dev-team",
|
||||
Description: "开发环境租户",
|
||||
}
|
||||
bodyByte, err := json.Marshal(req)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
res, err := http.Post("http://127.0.0.1:8000/api/v1/namespaces", "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()
|
||||
var namespaceBase apisv1.NamespaceBase
|
||||
err = json.NewDecoder(res.Body).Decode(&namespaceBase)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cmp.Diff(namespaceBase.Name, req.Name)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(namespaceBase.Description, req.Description)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test list namespace", func() {
|
||||
defer GinkgoRecover()
|
||||
res, err := http.Get("http://127.0.0.1:8000/api/v1/namespaces")
|
||||
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()
|
||||
var namespaces apisv1.ListNamespaceResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&namespaces)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
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"
|
||||
"time"
|
||||
|
||||
"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())
|
||||
Eventually(func(g Gomega) {
|
||||
res, err = http.Post(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/v1/namespaces/%s/applications/%s", namespace, appName),
|
||||
"application/json",
|
||||
bytes.NewBuffer(bodyByte),
|
||||
)
|
||||
g.Expect(err).ShouldNot(HaveOccurred())
|
||||
g.Expect(res).ShouldNot(BeNil())
|
||||
g.Expect(cmp.Diff(res.StatusCode, 200)).Should(BeEmpty())
|
||||
g.Expect(res.Body).ShouldNot(BeNil())
|
||||
defer res.Body.Close()
|
||||
}, time.Minute).Should(Succeed())
|
||||
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())
|
||||
})
|
||||
})
|
||||
@@ -18,81 +18,68 @@ package e2e_apiserver_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/clients"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/datastore"
|
||||
arest "github.com/oam-dev/kubevela/pkg/apiserver/rest"
|
||||
)
|
||||
|
||||
var cfg *rest.Config
|
||||
var k8sClient client.Client
|
||||
var testEnv *envtest.Environment
|
||||
var testScheme = runtime.NewScheme()
|
||||
|
||||
func TestE2eApiserverTest(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "E2eApiserverTest Suite")
|
||||
}
|
||||
|
||||
// Suite test in e2e-apiserver-test relies on the pre-setup kubernetes environment
|
||||
var _ = BeforeSuite(func() {
|
||||
|
||||
By("bootstrapping test environment")
|
||||
|
||||
testEnv = &envtest.Environment{
|
||||
ControlPlaneStartTimeout: time.Minute * 3,
|
||||
ControlPlaneStopTimeout: time.Minute,
|
||||
UseExistingCluster: pointer.BoolPtr(false),
|
||||
}
|
||||
|
||||
By("start kube test env")
|
||||
var err error
|
||||
cfg, err = testEnv.Start()
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(cfg).ToNot(BeNil())
|
||||
|
||||
err = scheme.AddToScheme(testScheme)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("new kube client")
|
||||
cfg.Timeout = time.Minute * 2
|
||||
k8sClient, err = client.New(cfg, client.Options{Scheme: testScheme})
|
||||
var err error
|
||||
k8sClient, err = clients.GetKubeClient()
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(k8sClient).ToNot(BeNil())
|
||||
By("new kube client success")
|
||||
clients.SetKubeClient(k8sClient)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
server, err := arest.New(arest.Config{
|
||||
cfg := arest.Config{
|
||||
BindAddr: "127.0.0.1:8000",
|
||||
Datastore: datastore.Config{
|
||||
Type: "kubeapi",
|
||||
Database: "kubevela",
|
||||
},
|
||||
})
|
||||
}
|
||||
cfg.LeaderConfig.ID = uuid.New().String()
|
||||
cfg.LeaderConfig.LockName = "apiserver-lock"
|
||||
cfg.LeaderConfig.Duration = time.Second * 10
|
||||
|
||||
server, err := arest.New(cfg)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(server).ShouldNot(BeNil())
|
||||
go func() {
|
||||
err = server.Run(ctx)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
}()
|
||||
By("wait for api server to start")
|
||||
Eventually(
|
||||
func() error {
|
||||
res, err := http.Get("http://127.0.0.1:8000/api/v1/namespaces")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if res.StatusCode == http.StatusOK {
|
||||
return nil
|
||||
}
|
||||
return errors.New("rest service not ready")
|
||||
}, time.Second*5, time.Millisecond*200).Should(BeNil())
|
||||
By("api server started")
|
||||
time.Sleep(time.Second * 2)
|
||||
})
|
||||
|
||||
var _ = AfterSuite(func() {
|
||||
By("tearing down the test environment")
|
||||
err := testEnv.Stop()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: test-component-pod-view
|
||||
namespace: vela-system
|
||||
data:
|
||||
template: |
|
||||
import (
|
||||
"vela/ql"
|
||||
"vela/op"
|
||||
)
|
||||
|
||||
parameter: {
|
||||
appName: string
|
||||
appNs: string
|
||||
name: string
|
||||
cluster?: string
|
||||
clusterNs?: string
|
||||
}
|
||||
|
||||
application: ql.#ListResourcesInApp & {
|
||||
app: {
|
||||
name: parameter.appName
|
||||
namespace: parameter.appNs
|
||||
components: [parameter.name]
|
||||
filter: {
|
||||
if parameter.cluster != _|_ {
|
||||
cluster: parameter.cluster
|
||||
}
|
||||
if parameter.clusterNs != _|_ {
|
||||
clusterNamespace: parameter.clusterNs
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app: application.list[0]
|
||||
resources: app.components[0].resources
|
||||
|
||||
podsMap: op.#Steps & {
|
||||
for i, resource in resources {
|
||||
"\(i)": ql.#CollectPods & {
|
||||
value: resource.object
|
||||
cluster: resource.cluster
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
podsWithCluster: [ for i, pods in podsMap for podObj in pods.list {
|
||||
cluster: pods.cluster
|
||||
obj: podObj
|
||||
}]
|
||||
|
||||
podStatus: op.#Steps & {
|
||||
for i, pod in podsWithCluster {
|
||||
"\(i)": op.#Steps & {
|
||||
name: pod.obj.metadata.name
|
||||
containers: {for container in pod.obj.status.containerStatuses {
|
||||
"\(container.name)": {
|
||||
image: container.image
|
||||
state: container.state
|
||||
}
|
||||
}}
|
||||
events: ql.#SearchEvents & {
|
||||
value: pod.obj
|
||||
cluster: pod.cluster
|
||||
}
|
||||
metrics: ql.#Read & {
|
||||
cluster: pod.cluster
|
||||
value: {
|
||||
apiVersion: "metrics.k8s.io/v1beta1"
|
||||
kind: "PodMetrics"
|
||||
metadata: {
|
||||
name: pod.obj.metadata.name
|
||||
namespace: pod.obj.metadata.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status: {
|
||||
podList: [ for podInfo in podStatus {
|
||||
name: podInfo.name
|
||||
containers: [ for containerName, container in podInfo.containers {
|
||||
containerName
|
||||
}]
|
||||
events: podInfo.events.list
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: example-app
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: hello-world-server
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
port: 8000
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 1
|
||||
- name: data-worker
|
||||
type: worker
|
||||
properties:
|
||||
image: busybox
|
||||
cmd:
|
||||
- sleep
|
||||
- '1000000'
|
||||
policies:
|
||||
- name: example-multi-env-policy
|
||||
type: env-binding
|
||||
properties:
|
||||
envs:
|
||||
- name: test
|
||||
placement: # selecting the namespace (in local cluster) to deploy to
|
||||
namespaceSelector:
|
||||
name: TEST_NAMESPACE
|
||||
selector:
|
||||
components:
|
||||
- data-worker
|
||||
|
||||
- name: staging
|
||||
placement: # selecting the cluster to deploy to
|
||||
clusterSelector:
|
||||
name: cluster-worker
|
||||
|
||||
- name: prod
|
||||
placement: # selecting both namespace and cluster to deploy to
|
||||
clusterSelector:
|
||||
name: cluster-worker
|
||||
namespaceSelector:
|
||||
name: PROD_NAMESPACE
|
||||
patch: # overlay patch on above components
|
||||
components:
|
||||
- name: hello-world-server
|
||||
type: webservice
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 3
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
# deploy to test env
|
||||
- name: deploy-test
|
||||
type: deploy2env
|
||||
properties:
|
||||
policy: example-multi-env-policy
|
||||
env: test
|
||||
|
||||
# deploy to staging env
|
||||
- name: deploy-staging
|
||||
type: deploy2env
|
||||
properties:
|
||||
policy: example-multi-env-policy
|
||||
env: staging
|
||||
|
||||
# deploy to prod env
|
||||
- name: deploy-prod
|
||||
type: deploy2env
|
||||
properties:
|
||||
policy: example-multi-env-policy
|
||||
env: prod
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: read-view
|
||||
namespace: vela-system
|
||||
data:
|
||||
template: |
|
||||
import (
|
||||
"vela/op"
|
||||
)
|
||||
|
||||
output: {
|
||||
if parameter.apiVersion == _|_ && parameter.kind == _|_ {
|
||||
op.#Read & {
|
||||
value: {
|
||||
apiVersion: "core.oam.dev/v1beta1"
|
||||
kind: "Application"
|
||||
metadata: {
|
||||
name: parameter.name
|
||||
if parameter.namespace != _|_ {
|
||||
namespace: parameter.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if parameter.apiVersion != _|_ || parameter.kind != _|_ {
|
||||
op.#Read & {
|
||||
value: {
|
||||
apiVersion: parameter.apiVersion
|
||||
kind: parameter.kind
|
||||
metadata: {
|
||||
name: parameter.name
|
||||
if parameter.namespace != _|_ {
|
||||
namespace: parameter.namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parameter: {
|
||||
// +usage=Specify the apiVersion of the object, defaults to core.oam.dev/v1beta1
|
||||
apiVersion?: string
|
||||
// +usage=Specify the kind of the object, defaults to Application
|
||||
kind?: string
|
||||
// +usage=Specify the name of the object
|
||||
name: string
|
||||
// +usage=Specify the namespace of the object
|
||||
namespace?: string
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"appName": "appName",
|
||||
"name": "workflowName",
|
||||
"alias": "workflowAlias",
|
||||
"description": "workflow description",
|
||||
"enable": true,
|
||||
"default": true,
|
||||
"steps": [
|
||||
{
|
||||
"name": "deploy-test",
|
||||
"type": "deploy2env",
|
||||
"properties": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
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
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CreateRequest wraps request
|
||||
func CreateRequest(method string, path string, body interface{}) (*http.Response, error) {
|
||||
if body == nil {
|
||||
body = map[string]string{}
|
||||
}
|
||||
bs, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := http.NewRequest(method, "http://127.0.0.1:8000/api/v1"+path, bytes.NewBuffer(bs))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
return http.DefaultClient.Do(req)
|
||||
}
|
||||
|
||||
// DecodeResponseBody decode response and close response
|
||||
func DecodeResponseBody(resp *http.Response, err error, dst interface{}) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return fmt.Errorf("response code is not 200: %d", resp.StatusCode)
|
||||
}
|
||||
if resp.Body == nil {
|
||||
return fmt.Errorf("response body is nil")
|
||||
}
|
||||
err = json.NewDecoder(resp.Body).Decode(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return resp.Body.Close()
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
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"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/pkg/errors"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
common2 "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"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"
|
||||
)
|
||||
|
||||
type PodStatus struct {
|
||||
Name string `json:"name"`
|
||||
Containers []string `json:"containers"`
|
||||
Events interface{} `json:"events"`
|
||||
}
|
||||
type Status struct {
|
||||
PodList []PodStatus `json:"podList"`
|
||||
}
|
||||
|
||||
var _ = Describe("Test velaQL rest api", func() {
|
||||
namespace := "test-velaql"
|
||||
appName := "example-app"
|
||||
component1Name := "ql-webservice"
|
||||
component2Name := "ql-worker"
|
||||
var app v1beta1.Application
|
||||
var readView corev1.ConfigMap
|
||||
|
||||
It("Test query application status via view", func() {
|
||||
Expect(common.ReadYamlToObject("./testdata/read-view.yaml", &readView)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.Background(), &readView)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
Expect(common.ReadYamlToObject("./testdata/example-app.yaml", &app)).Should(BeNil())
|
||||
app.Spec.Components[0].Name = component1Name
|
||||
app.Spec.Components[1].Name = component2Name
|
||||
|
||||
req := apiv1.ApplicationRequest{
|
||||
Components: app.Spec.Components,
|
||||
}
|
||||
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(res.StatusCode).Should(Equal(200))
|
||||
|
||||
oldApp := new(v1beta1.Application)
|
||||
Eventually(func() error {
|
||||
if err := k8sClient.Get(context.Background(), client.ObjectKey{Name: appName, Namespace: namespace}, oldApp); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(oldApp.Status.AppliedResources) != 2 {
|
||||
return errors.Errorf("expect the applied resources number is %d, but get %d", 2, len(oldApp.Status.AppliedResources))
|
||||
}
|
||||
return nil
|
||||
}, 3*time.Second, 300*time.Microsecond).Should(BeNil())
|
||||
|
||||
queryRes, err := http.Get(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/api/v1/query?velaql=%s{name=%s,namespace=%s}.%s", "read-view", appName, namespace, "output.value.spec"),
|
||||
)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(queryRes.StatusCode).Should(Equal(200))
|
||||
|
||||
defer queryRes.Body.Close()
|
||||
var appSpec v1beta1.ApplicationSpec
|
||||
err = json.NewDecoder(queryRes.Body).Decode(&appSpec)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
|
||||
var existApp v1beta1.Application
|
||||
Expect(k8sClient.Get(context.Background(), client.ObjectKey{Name: appName, Namespace: namespace}, &existApp)).Should(BeNil())
|
||||
|
||||
Expect(len(appSpec.Components)).Should(Equal(len(existApp.Spec.Components)))
|
||||
})
|
||||
|
||||
It("Test query application status with wrong velaQL", func() {
|
||||
queryRes, err := http.Get(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/api/v1/query?velaql=%s{err=,name=%s,namespace=%s}.%s", "read-object", appName, namespace, "output.value.spec"),
|
||||
)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(queryRes.StatusCode).Should(Equal(400))
|
||||
})
|
||||
|
||||
It("Test query application component view", func() {
|
||||
componentView := new(corev1.ConfigMap)
|
||||
Expect(common.ReadYamlToObject("./testdata/component-pod-view.yaml", componentView)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.Background(), componentView)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
oldApp := new(v1beta1.Application)
|
||||
Eventually(func() error {
|
||||
if err := k8sClient.Get(context.Background(), client.ObjectKey{Name: appName, Namespace: namespace}, oldApp); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(oldApp.Status.AppliedResources) != 2 {
|
||||
return errors.Errorf("expect the applied resources number is %d, but get %d", 2, len(oldApp.Status.AppliedResources))
|
||||
}
|
||||
return nil
|
||||
}, 3*time.Second, 300*time.Microsecond).Should(BeNil())
|
||||
|
||||
queryRes, err := http.Get(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/api/v1/query?velaql=%s{appName=%s,appNs=%s,name=%s}.%s", "test-component-pod-view", appName, namespace, component1Name, "status"),
|
||||
)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(queryRes.StatusCode).Should(Equal(200))
|
||||
|
||||
defer queryRes.Body.Close()
|
||||
status := new(Status)
|
||||
err = json.NewDecoder(queryRes.Body).Decode(status)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(len(status.PodList)).Should(Equal(1))
|
||||
Expect(status.PodList[0].Containers[0]).Should(Equal(component1Name))
|
||||
|
||||
Eventually(func() error {
|
||||
queryRes1, err := http.Get(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/api/v1/query?velaql=%s{appName=%s,appNs=%s,name=%s}.%s", "test-component-pod-view", appName, namespace, component2Name, "status"),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if queryRes1.StatusCode != 200 {
|
||||
return errors.Errorf("status code is %d", queryRes1.StatusCode)
|
||||
}
|
||||
defer queryRes1.Body.Close()
|
||||
status1 := new(Status)
|
||||
err = json.NewDecoder(queryRes1.Body).Decode(status1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(status1.PodList) != 1 {
|
||||
return errors.New("pod number is zero")
|
||||
}
|
||||
if status1.PodList[0].Containers[0] != component2Name {
|
||||
return errors.New("container name is not correct")
|
||||
}
|
||||
return nil
|
||||
}, 10*time.Second, 300*time.Microsecond).Should(BeNil())
|
||||
})
|
||||
|
||||
It("Test collect pod from cronJob", func() {
|
||||
cronJob := new(v1beta1.ComponentDefinition)
|
||||
Expect(yaml.Unmarshal([]byte(cronJobComponentDefinition), cronJob)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.Background(), cronJob)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
oldApp := new(v1beta1.Application)
|
||||
Eventually(func() error {
|
||||
if err := k8sClient.Get(context.Background(), client.ObjectKey{Name: appName, Namespace: namespace}, oldApp); err != nil {
|
||||
return err
|
||||
}
|
||||
oldApp.Spec.Components[1].Type = "cronjob"
|
||||
oldApp.Spec.Components[1].Properties = util.Object2RawExtension(map[string]interface{}{
|
||||
"image": "busybox",
|
||||
"cmd": []string{"sleep", "1"},
|
||||
})
|
||||
if err := k8sClient.Update(context.Background(), oldApp); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}, 3*time.Second, 300*time.Microsecond).Should(BeNil())
|
||||
|
||||
newApp := new(v1beta1.Application)
|
||||
Eventually(func() error {
|
||||
if err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(oldApp), newApp); err != nil {
|
||||
return err
|
||||
}
|
||||
appliedCronJob := false
|
||||
for _, resource := range newApp.Status.AppliedResources {
|
||||
if resource.ObjectReference.Kind == "CronJob" {
|
||||
appliedCronJob = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !appliedCronJob {
|
||||
return errors.New("fail to apply cronjob")
|
||||
}
|
||||
return nil
|
||||
}, 3*time.Second, 300*time.Microsecond).Should(BeNil())
|
||||
|
||||
newWorkload := new(batchv1beta1.CronJob)
|
||||
Eventually(func() error {
|
||||
return k8sClient.Get(context.Background(), client.ObjectKey{Name: component2Name, Namespace: namespace}, newWorkload)
|
||||
}, 10*time.Second, 300*time.Microsecond).Should(BeNil())
|
||||
|
||||
Eventually(func() error {
|
||||
queryRes, err := http.Get(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/api/v1/query?velaql=%s{appName=%s,appNs=%s,name=%s}.%s", "test-component-pod-view", appName, namespace, component2Name, "status"),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if queryRes.StatusCode != 200 {
|
||||
return errors.Errorf("status code is %d", queryRes.StatusCode)
|
||||
}
|
||||
defer queryRes.Body.Close()
|
||||
status := new(Status)
|
||||
err = json.NewDecoder(queryRes.Body).Decode(status)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(status.PodList) == 0 {
|
||||
return errors.New("pod list is 0")
|
||||
}
|
||||
return nil
|
||||
}, 2*time.Minute, 3*time.Microsecond).Should(BeNil())
|
||||
})
|
||||
|
||||
It("Test collect pod from helmRelease", func() {
|
||||
appWithHelm := new(v1beta1.Application)
|
||||
Expect(yaml.Unmarshal([]byte(podInfoApp), appWithHelm)).Should(BeNil())
|
||||
req := apiv1.ApplicationRequest{
|
||||
Components: appWithHelm.Spec.Components,
|
||||
}
|
||||
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, appWithHelm.Name),
|
||||
"application/json",
|
||||
bytes.NewBuffer(bodyByte),
|
||||
)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(res).ShouldNot(BeNil())
|
||||
Expect(res.StatusCode).Should(Equal(200))
|
||||
|
||||
newApp := new(v1beta1.Application)
|
||||
Eventually(func() error {
|
||||
if err := k8sClient.Get(context.Background(), client.ObjectKey{Name: appWithHelm.Name, Namespace: namespace}, newApp); err != nil {
|
||||
return err
|
||||
}
|
||||
if newApp.Status.Phase != common2.ApplicationRunning {
|
||||
return errors.New("application is not ready")
|
||||
}
|
||||
return nil
|
||||
}, 2*time.Minute, 1*time.Second).Should(BeNil())
|
||||
|
||||
Eventually(func() error {
|
||||
queryRes, err := http.Get(
|
||||
fmt.Sprintf("http://127.0.0.1:8000/api/v1/query?velaql=%s{appName=%s,appNs=%s,name=%s}.%s", "component-pod-view", appWithHelm.Name, namespace, "podinfo", "status"),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if queryRes.StatusCode != 200 {
|
||||
return errors.Errorf("status code is %d", queryRes.StatusCode)
|
||||
}
|
||||
defer queryRes.Body.Close()
|
||||
|
||||
type queryResult struct {
|
||||
PodList []interface{} `json:"podList,omitempty"`
|
||||
Error interface{} `json:"error,omitempty"`
|
||||
}
|
||||
status := new(queryResult)
|
||||
err = json.NewDecoder(queryRes.Body).Decode(status)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status.Error != nil {
|
||||
return errors.Errorf("error %v", status.Error)
|
||||
}
|
||||
if len(status.PodList) == 0 {
|
||||
return errors.New("pod list is 0")
|
||||
}
|
||||
return nil
|
||||
}, 2*time.Minute, 300*time.Microsecond).Should(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
var cronJobComponentDefinition = `
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: ComponentDefinition
|
||||
metadata:
|
||||
annotations: {}
|
||||
name: cronjob
|
||||
namespace: vela-system
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
output: {
|
||||
apiVersion: "batch/v1beta1"
|
||||
kind: "CronJob"
|
||||
metadata: name: context.name
|
||||
spec: {
|
||||
schedule: "*/1 * * * *"
|
||||
jobTemplate: spec: template: spec: {
|
||||
containers: [{
|
||||
name: context.name
|
||||
image: parameter.image
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
command: parameter.cmd
|
||||
}]
|
||||
restartPolicy: "OnFailure"
|
||||
}
|
||||
}
|
||||
}
|
||||
parameter: {
|
||||
image: string
|
||||
cmd: [...string]
|
||||
}
|
||||
workload:
|
||||
type: autodetects.core.oam.dev
|
||||
`
|
||||
|
||||
var podInfoApp = `
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
spec:
|
||||
components:
|
||||
- name: podinfo
|
||||
type: helm
|
||||
properties:
|
||||
chart: podinfo
|
||||
url: https://stefanprodan.github.io/podinfo
|
||||
repoType: helm
|
||||
version: 5.1.2
|
||||
`
|
||||
@@ -378,7 +378,7 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
if err := k8sClient.Get(ctx, client.ObjectKey{Name: cmName, Namespace: namespace}, cm); err != nil {
|
||||
return err
|
||||
}
|
||||
if cm.Data["openapi-v3-json-schema"] == "" {
|
||||
if cm.Data[types.OpenapiV3JSONSchema] == "" {
|
||||
return errors.New("json schema is not found in the ConfigMap")
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
@@ -347,7 +348,7 @@ spec:
|
||||
if err := k8sClient.Get(ctx, client.ObjectKey{Name: cmName, Namespace: namespace}, cm); err != nil {
|
||||
return err
|
||||
}
|
||||
if cm.Data["openapi-v3-json-schema"] == "" {
|
||||
if cm.Data[types.OpenapiV3JSONSchema] == "" {
|
||||
return errors.New("json schema is not found in the ConfigMap")
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -302,7 +302,7 @@ func RequestReconcileNow(ctx context.Context, o client.Object) {
|
||||
|
||||
// randomNamespaceName generates a random name based on the basic name.
|
||||
// Running each ginkgo case in a new namespace with a random name can avoid
|
||||
// waiting a long time to GC namesapce.
|
||||
// waiting a long time to GC namespace.
|
||||
func randomNamespaceName(basic string) string {
|
||||
return fmt.Sprintf("%s-%s", basic, strconv.FormatInt(rand.Int63(), 16))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user