Feat: add RBAC support (#3493)

* Feat: add the rbac data model

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: add some api about the project

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: add CRUD about the project and the project user

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: add CRUD about the role and perm check filter function

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: update swagger config

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: add default roles and perm policies

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: add perm check filter for all webservice

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: change the method that find project name

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: query applications and envs by user perm

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: support get login user info

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Fix: change default permissions

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: change PermPolicy to Permission

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Feat: add some unit test and fix the e2e test error

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Fix: change some comment word

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Fix: e2e api path error

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
This commit is contained in:
barnettZQG
2022-03-28 16:03:11 +08:00
committed by GitHub
parent 795231ceb5
commit 044c4bf73c
69 changed files with 5026 additions and 932 deletions

View File

@@ -80,7 +80,8 @@ var _ = Describe("Test application rest api", func() {
var envName = "dev"
// create target
var createTarget = apisv1.CreateTargetRequest{
Name: targetName,
Name: targetName,
Project: appProject,
Cluster: &apisv1.ClusterTarget{
ClusterName: "local",
Namespace: targetName,

View File

@@ -40,16 +40,24 @@ var _ = Describe("Test env rest api", func() {
It("Test create, get, delete env with normal format", func() {
defer GinkgoRecover()
var re = apisv1.CreateProjectRequest{
Name: "my-pro",
Alias: "project alias",
}
var proBase apisv1.ProjectBase
resp := post("/projects", re)
Expect(decodeResponseBody(resp, &proBase)).Should(Succeed())
By("create a target for preparation")
var reqt = apisv1.CreateTargetRequest{
Name: testtarget1,
Alias: "my-target-for-env1",
Description: "KubeVela Target",
Project: "my-pro",
Cluster: &apisv1.ClusterTarget{ClusterName: multicluster.ClusterLocalName, Namespace: testtarget1},
}
var tgBase apisv1.TargetBase
resp := post("/targets", reqt)
resp = post("/targets", reqt)
Expect(decodeResponseBody(resp, &tgBase)).Should(Succeed())
By("create the first env")
@@ -100,6 +108,7 @@ var _ = Describe("Test env rest api", func() {
Name: testtarget1,
Alias: "my-target-for-env2",
Description: "KubeVela Target",
Project: "my-pro",
Cluster: &apisv1.ClusterTarget{ClusterName: multicluster.ClusterLocalName, Namespace: testtarget1},
}
var tgBase apisv1.TargetBase
@@ -109,6 +118,7 @@ var _ = Describe("Test env rest api", func() {
Name: testtarget2,
Alias: "my-target-for-env3",
Description: "KubeVela Target",
Project: "my-pro",
Cluster: &apisv1.ClusterTarget{ClusterName: multicluster.ClusterLocalName, Namespace: testtarget2},
}
resp = post("/targets", reqt)

View File

@@ -17,11 +17,9 @@
package e2e_apiserver_test
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/google/go-cmp/cmp"
@@ -49,14 +47,7 @@ var _ = Describe("Test oam application rest api", func() {
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())
res := post(fmt.Sprintf("/v1/namespaces/%s/applications/%s", namespace, appName), req)
Expect(res).ShouldNot(BeNil())
Expect(cmp.Diff(res.StatusCode, 200)).Should(BeEmpty())
Expect(res.Body).ShouldNot(BeNil())
@@ -73,15 +64,8 @@ var _ = Describe("Test oam application rest api", func() {
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())
res = post(fmt.Sprintf("/v1/namespaces/%s/applications/%s", namespace, appName), updateReq)
g.Expect(res).ShouldNot(BeNil())
g.Expect(cmp.Diff(res.StatusCode, 200)).Should(BeEmpty())
g.Expect(res.Body).ShouldNot(BeNil())
@@ -96,15 +80,12 @@ var _ = Describe("Test oam application rest api", func() {
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())
res := get(fmt.Sprintf("/v1/namespaces/%s/applications/%s", namespace, appName))
Expect(res).ShouldNot(BeNil())
defer res.Body.Close()
var appResp apiv1.ApplicationResponse
err = json.NewDecoder(res.Body).Decode(&appResp)
err := json.NewDecoder(res.Body).Decode(&appResp)
Expect(err).ShouldNot(HaveOccurred())
Expect(len(appResp.Spec.Components)).Should(Equal(1))
@@ -112,10 +93,7 @@ var _ = Describe("Test oam application rest api", func() {
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())
res := delete(fmt.Sprintf("/v1/namespaces/%s/applications/%s", namespace, appName))
Expect(res).ShouldNot(BeNil())
Expect(cmp.Diff(res.StatusCode, 200)).Should(BeEmpty())
})

View File

@@ -20,7 +20,6 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
@@ -38,12 +37,14 @@ import (
"github.com/oam-dev/kubevela/pkg/apiserver/datastore"
arest "github.com/oam-dev/kubevela/pkg/apiserver/rest"
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/rest/utils/bcode"
)
var k8sClient client.Client
var token string
const (
baseDomain = "http://127.0.0.1:8000"
baseURL = "http://127.0.0.1:8000/api/v1"
testNSprefix = "api-e2e-test-"
)
@@ -101,11 +102,11 @@ var _ = BeforeSuite(func() {
if err != nil {
return err
}
loginResp := &apisv1.LoginResponse{}
err = json.NewDecoder(resp.Body).Decode(loginResp)
Expect(err).Should(BeNil())
token = "Bearer " + loginResp.AccessToken
if resp.StatusCode == http.StatusOK {
if resp.StatusCode == 200 {
loginResp := &apisv1.LoginResponse{}
err = json.NewDecoder(resp.Body).Decode(loginResp)
Expect(err).Should(BeNil())
token = "Bearer " + loginResp.AccessToken
var req = apisv1.CreateProjectRequest{
Name: appProject,
Description: "test project",
@@ -113,8 +114,11 @@ var _ = BeforeSuite(func() {
_ = post("/projects", req)
return nil
}
return errors.New("rest service not ready")
}, time.Second*5, time.Millisecond*200).Should(BeNil())
code := &bcode.Bcode{}
err = json.NewDecoder(resp.Body).Decode(code)
Expect(err).Should(BeNil())
return fmt.Errorf("rest service not ready code:%d message:%s", resp.StatusCode, code.Message)
}, time.Second*10, time.Millisecond*200).Should(BeNil())
By("api server started")
})
@@ -134,7 +138,12 @@ func post(path string, body interface{}) *http.Response {
b, err := json.Marshal(body)
Expect(err).Should(BeNil())
client := &http.Client{}
req, err := http.NewRequest(http.MethodPost, baseURL+path, bytes.NewBuffer(b))
if !strings.HasPrefix(path, "/v1") {
path = baseURL + path
} else {
path = baseDomain + path
}
req, err := http.NewRequest(http.MethodPost, path, bytes.NewBuffer(b))
Expect(err).Should(BeNil())
req.Header.Add("Authorization", token)
req.Header.Add("Content-Type", "application/json")
@@ -148,7 +157,12 @@ func put(path string, body interface{}) *http.Response {
b, err := json.Marshal(body)
Expect(err).Should(BeNil())
client := &http.Client{}
req, err := http.NewRequest(http.MethodPut, baseURL+path, bytes.NewBuffer(b))
if !strings.HasPrefix(path, "/v1") {
path = baseURL + path
} else {
path = baseDomain + path
}
req, err := http.NewRequest(http.MethodPut, path, bytes.NewBuffer(b))
Expect(err).Should(BeNil())
req.Header.Add("Authorization", token)
req.Header.Set("Content-Type", "application/json")
@@ -160,7 +174,12 @@ func put(path string, body interface{}) *http.Response {
func get(path string) *http.Response {
client := &http.Client{}
req, err := http.NewRequest(http.MethodGet, baseURL+path, nil)
if !strings.HasPrefix(path, "/v1") {
path = baseURL + path
} else {
path = baseDomain + path
}
req, err := http.NewRequest(http.MethodGet, path, nil)
Expect(err).Should(BeNil())
req.Header.Add("Authorization", token)
@@ -171,10 +190,14 @@ func get(path string) *http.Response {
func delete(path string) *http.Response {
client := &http.Client{}
req, err := http.NewRequest(http.MethodDelete, baseURL+path, nil)
if !strings.HasPrefix(path, "/v1") {
path = baseURL + path
} else {
path = baseDomain + path
}
req, err := http.NewRequest(http.MethodDelete, path, nil)
Expect(err).Should(BeNil())
req.Header.Add("Authorization", token)
response, err := client.Do(req)
Expect(err).Should(BeNil())
defer response.Body.Close()

View File

@@ -24,10 +24,6 @@ import (
)
var _ = Describe("Test system info rest api", func() {
BeforeEach(func() {
res := delete("/system_info/")
Expect(decodeResponseBody(res, nil)).Should(Succeed())
})
It("Test get SystemInfo", func() {
res := get("/system_info/")

View File

@@ -17,11 +17,9 @@
package e2e_apiserver_test
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"time"
. "github.com/onsi/ginkgo"
@@ -70,14 +68,7 @@ var _ = Describe("Test velaQL rest api", func() {
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())
res := post(fmt.Sprintf("/v1/namespaces/%s/applications/%s", namespace, appName), req)
Expect(res).ShouldNot(BeNil())
Expect(res.StatusCode).Should(Equal(200))
@@ -218,14 +209,7 @@ var _ = Describe("Test velaQL rest api", func() {
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())
res := post(fmt.Sprintf("/v1/namespaces/%s/applications/%s", namespace, appWithHelm.Name), req)
Expect(res).ShouldNot(BeNil())
Expect(res.StatusCode).Should(Equal(200))
@@ -248,7 +232,7 @@ var _ = Describe("Test velaQL rest api", func() {
defer queryRes.Body.Close()
status := new(Status)
err = json.NewDecoder(queryRes.Body).Decode(status)
err := json.NewDecoder(queryRes.Body).Decode(status)
if err != nil {
return err
}
@@ -269,14 +253,7 @@ var _ = Describe("Test velaQL rest api", func() {
Components: appWithGC.Spec.Components,
Policies: appWithGC.Spec.Policies,
}
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, appWithGC.Name),
"application/json",
bytes.NewBuffer(bodyByte),
)
Expect(err).ShouldNot(HaveOccurred())
res := post(fmt.Sprintf("/v1/namespaces/%s/applications/%s", namespace, appWithGC.Name), req)
Expect(res).ShouldNot(BeNil())
Expect(res.StatusCode).Should(Equal(200))
@@ -299,7 +276,7 @@ var _ = Describe("Test velaQL rest api", func() {
defer queryRes.Body.Close()
status := new(Status)
err = json.NewDecoder(queryRes.Body).Decode(status)
err := json.NewDecoder(queryRes.Body).Decode(status)
if err != nil {
return err
}
@@ -317,14 +294,7 @@ var _ = Describe("Test velaQL rest api", func() {
Components: appWithGC.Spec.Components,
Policies: appWithGC.Spec.Policies,
}
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, appWithGC.Name),
"application/json",
bytes.NewBuffer(bodyByte),
)
Expect(err).ShouldNot(HaveOccurred())
res = post(fmt.Sprintf("/v1/namespaces/%s/applications/%s", namespace, appWithGC.Name), updateReq)
Expect(res).ShouldNot(BeNil())
Expect(res.StatusCode).Should(Equal(200))
@@ -346,7 +316,7 @@ var _ = Describe("Test velaQL rest api", func() {
defer queryRes.Body.Close()
status := new(Status)
err = json.NewDecoder(queryRes.Body).Decode(status)
err := json.NewDecoder(queryRes.Body).Decode(status)
if err != nil {
return err
}
@@ -367,7 +337,7 @@ var _ = Describe("Test velaQL rest api", func() {
defer queryRes.Body.Close()
status := new(Status)
err = json.NewDecoder(queryRes.Body).Decode(status)
err := json.NewDecoder(queryRes.Body).Decode(status)
if err != nil {
return err
}