mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-12 13:35:00 +01:00
Merge pull request #3436 from ywk253100/171020_meta_api
Add project metadata API
This commit is contained in:
commit
5b2ececae8
@ -302,6 +302,149 @@ paths:
|
||||
description: User need to log in first.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
'/projects/{project_id}/metadatas':
|
||||
get:
|
||||
summary: Get project metadata.
|
||||
description: |
|
||||
This endpoint returns metadata of the project specified by project ID.
|
||||
parameters:
|
||||
- name: project_id
|
||||
in: path
|
||||
description: The ID of project.
|
||||
required: true
|
||||
type: integer
|
||||
format: int64
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
'200':
|
||||
description: Get metadata successfully.
|
||||
schema:
|
||||
$ref: '#/definitions/ProjectMetadata'
|
||||
'401':
|
||||
description: User need to login first.
|
||||
'500':
|
||||
description: Internal server errors.
|
||||
post:
|
||||
summary: Add metadata for the project.
|
||||
description: |
|
||||
This endpoint is aimed to add metadata of a project.
|
||||
parameters:
|
||||
- name: project_id
|
||||
in: path
|
||||
type: integer
|
||||
format: int64
|
||||
required: true
|
||||
description: Selected project ID.
|
||||
- name: metadata
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/ProjectMetadata'
|
||||
description: The metadata of project.
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
'200':
|
||||
description: Add metadata successfully.
|
||||
'400':
|
||||
description: Invalid request.
|
||||
'401':
|
||||
description: User need to log in first.
|
||||
'403':
|
||||
description: User does not have permission to the project.
|
||||
'404':
|
||||
description: Project ID does not exist.
|
||||
'500':
|
||||
description: Internal server errors.
|
||||
'/projects/{project_id}/metadatas/{meta_name}':
|
||||
get:
|
||||
summary: Get project metadata
|
||||
description: |
|
||||
This endpoint returns specified metadata of a project.
|
||||
parameters:
|
||||
- name: project_id
|
||||
in: path
|
||||
description: Project ID for filtering results.
|
||||
required: true
|
||||
type: integer
|
||||
format: int64
|
||||
- name: meta_name
|
||||
in: path
|
||||
description: The name of metadat.
|
||||
required: true
|
||||
type: string
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
'200':
|
||||
description: Get metadata successfully.
|
||||
schema:
|
||||
$ref: '#/definitions/ProjectMetadata'
|
||||
'401':
|
||||
description: User need to log in first.
|
||||
'500':
|
||||
description: Internal server errors.
|
||||
put:
|
||||
summary: Update metadata of a project.
|
||||
description: |
|
||||
This endpoint is aimed to update the metadata of a project.
|
||||
parameters:
|
||||
- name: project_id
|
||||
in: path
|
||||
type: integer
|
||||
format: int64
|
||||
required: true
|
||||
description: The ID of project.
|
||||
- name: meta_name
|
||||
in: path
|
||||
description: The name of metadat.
|
||||
required: true
|
||||
type: string
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
'200':
|
||||
description: Updated metadata successfully.
|
||||
'400':
|
||||
description: Invalid request.
|
||||
'401':
|
||||
description: User need to log in first.
|
||||
'403':
|
||||
description: User does not have permission to the project.
|
||||
'404':
|
||||
description: Project or metadata does not exist.
|
||||
'500':
|
||||
description: Internal server errors.
|
||||
delete:
|
||||
summary: Delete metadata of a project
|
||||
description: |
|
||||
This endpoint is aimed to delete metadata of a project.
|
||||
parameters:
|
||||
- name: project_id
|
||||
in: path
|
||||
description: The ID of project.
|
||||
required: true
|
||||
type: integer
|
||||
format: int64
|
||||
- name: meta_name
|
||||
in: path
|
||||
description: The name of metadat.
|
||||
required: true
|
||||
type: string
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
'200':
|
||||
description: Metadata is deleted successfully.
|
||||
'400':
|
||||
description: Invalid requst.
|
||||
'403':
|
||||
description: User need to log in first.
|
||||
'404':
|
||||
description: Project or metadata does not exist.
|
||||
'500':
|
||||
description: Internal server errors.
|
||||
'/projects/{project_id}/members/':
|
||||
get:
|
||||
summary: Return a project's relevant role members.
|
||||
|
@ -75,6 +75,17 @@ func (b *BaseAPI) HandleBadRequest(text string) {
|
||||
b.RenderError(http.StatusBadRequest, text)
|
||||
}
|
||||
|
||||
// HandleConflict ...
|
||||
func (b *BaseAPI) HandleConflict(text ...string) {
|
||||
msg := ""
|
||||
if len(text) > 0 {
|
||||
msg = text[0]
|
||||
}
|
||||
log.Infof("conflict: %s", msg)
|
||||
|
||||
b.RenderError(http.StatusConflict, msg)
|
||||
}
|
||||
|
||||
// HandleInternalServerError ...
|
||||
func (b *BaseAPI) HandleInternalServerError(text string) {
|
||||
log.Error(text)
|
||||
|
@ -101,6 +101,9 @@ func init() {
|
||||
beego.Router("/api/projects/:id([0-9]+)/logs", &ProjectAPI{}, "get:Logs")
|
||||
beego.Router("/api/projects/:id([0-9]+)/_deletable", &ProjectAPI{}, "get:Deletable")
|
||||
beego.Router("/api/projects/:pid([0-9]+)/members/?:mid", &ProjectMemberAPI{}, "get:Get;post:Post;delete:Delete;put:Put")
|
||||
beego.Router("/api/projects/:id([0-9]+)/metadatas/?:name", &MetadataAPI{}, "get:Get")
|
||||
beego.Router("/api/projects/:id([0-9]+)/metadatas/", &MetadataAPI{}, "post:Post")
|
||||
beego.Router("/api/projects/:id([0-9]+)/metadatas/:name", &MetadataAPI{}, "put:Put;delete:Delete")
|
||||
beego.Router("/api/repositories", &RepositoryAPI{})
|
||||
beego.Router("/api/statistics", &StatisticAPI{})
|
||||
beego.Router("/api/users/?:id", &UserAPI{})
|
||||
@ -1045,3 +1048,48 @@ func (a testapi) PingEmail(authInfo usrInfo, settings []byte) (int, string, erro
|
||||
|
||||
return code, string(body), err
|
||||
}
|
||||
|
||||
func (a testapi) PostMeta(authInfor usrInfo, projectID int64, metas map[string]string) (int, string, error) {
|
||||
_sling := sling.New().Base(a.basePath).
|
||||
Post(fmt.Sprintf("/api/projects/%d/metadatas/", projectID)).
|
||||
BodyJSON(metas)
|
||||
|
||||
code, body, err := request(_sling, jsonAcceptHeader, authInfor)
|
||||
return code, string(body), err
|
||||
}
|
||||
|
||||
func (a testapi) PutMeta(authInfor usrInfo, projectID int64, name string,
|
||||
metas map[string]string) (int, string, error) {
|
||||
_sling := sling.New().Base(a.basePath).
|
||||
Put(fmt.Sprintf("/api/projects/%d/metadatas/%s", projectID, name)).
|
||||
BodyJSON(metas)
|
||||
|
||||
code, body, err := request(_sling, jsonAcceptHeader, authInfor)
|
||||
return code, string(body), err
|
||||
}
|
||||
|
||||
func (a testapi) GetMeta(authInfor usrInfo, projectID int64, name ...string) (int, map[string]string, error) {
|
||||
_sling := sling.New().Base(a.basePath).
|
||||
Get(fmt.Sprintf("/api/projects/%d/metadatas/", projectID))
|
||||
if len(name) > 0 {
|
||||
_sling = _sling.Path(name[0])
|
||||
}
|
||||
|
||||
code, body, err := request(_sling, jsonAcceptHeader, authInfor)
|
||||
if err == nil && code == http.StatusOK {
|
||||
metas := map[string]string{}
|
||||
if err := json.Unmarshal(body, &metas); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
return code, metas, nil
|
||||
}
|
||||
return code, nil, err
|
||||
}
|
||||
|
||||
func (a testapi) DeleteMeta(authInfor usrInfo, projectID int64, name string) (int, string, error) {
|
||||
_sling := sling.New().Base(a.basePath).
|
||||
Delete(fmt.Sprintf("/api/projects/%d/metadatas/%s", projectID, name))
|
||||
|
||||
code, body, err := request(_sling, jsonAcceptHeader, authInfor)
|
||||
return code, string(body), err
|
||||
}
|
||||
|
231
src/ui/api/metadata.go
Normal file
231
src/ui/api/metadata.go
Normal file
@ -0,0 +1,231 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
"github.com/vmware/harbor/src/ui/promgr/metamgr"
|
||||
)
|
||||
|
||||
// MetadataAPI ...
|
||||
type MetadataAPI struct {
|
||||
BaseController
|
||||
metaMgr metamgr.ProjectMetadataManager
|
||||
project *models.Project
|
||||
name string
|
||||
}
|
||||
|
||||
// Prepare ...
|
||||
func (m *MetadataAPI) Prepare() {
|
||||
m.BaseController.Prepare()
|
||||
|
||||
m.metaMgr = m.ProjectMgr.GetMetadataManager()
|
||||
|
||||
// the project manager doesn't use a project metadata manager
|
||||
if m.metaMgr == nil {
|
||||
log.Debug("the project manager doesn't use a project metadata manager")
|
||||
m.RenderError(http.StatusMethodNotAllowed, "")
|
||||
return
|
||||
}
|
||||
|
||||
id, err := m.GetInt64FromPath(":id")
|
||||
if err != nil || id <= 0 {
|
||||
text := "invalid project ID: "
|
||||
if err != nil {
|
||||
text += err.Error()
|
||||
} else {
|
||||
text += fmt.Sprintf("%d", id)
|
||||
}
|
||||
m.HandleBadRequest(text)
|
||||
return
|
||||
}
|
||||
|
||||
project, err := m.ProjectMgr.Get(id)
|
||||
if err != nil {
|
||||
m.ParseAndHandleError(fmt.Sprintf("failed to get project %d", id), err)
|
||||
return
|
||||
}
|
||||
|
||||
if project == nil {
|
||||
m.HandleNotFound(fmt.Sprintf("project %d not found", id))
|
||||
return
|
||||
}
|
||||
|
||||
m.project = project
|
||||
|
||||
switch m.Ctx.Request.Method {
|
||||
case http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete:
|
||||
if !(m.Ctx.Request.Method == http.MethodGet && project.IsPublic()) {
|
||||
if !m.SecurityCtx.IsAuthenticated() {
|
||||
m.HandleUnauthorized()
|
||||
return
|
||||
}
|
||||
if !m.SecurityCtx.HasReadPerm(project.ProjectID) {
|
||||
m.HandleForbidden(m.SecurityCtx.GetUsername())
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
log.Debugf("%s method not allowed", m.Ctx.Request.Method)
|
||||
m.RenderError(http.StatusMethodNotAllowed, "")
|
||||
return
|
||||
}
|
||||
|
||||
name := m.GetStringFromPath(":name")
|
||||
if len(name) > 0 {
|
||||
m.name = name
|
||||
metas, err := m.metaMgr.Get(project.ProjectID, name)
|
||||
if err != nil {
|
||||
m.HandleInternalServerError(fmt.Sprintf("failed to get metadata of project %d: %v", project.ProjectID, err))
|
||||
return
|
||||
}
|
||||
if len(metas) == 0 {
|
||||
m.HandleNotFound(fmt.Sprintf("metadata %s of project %d not found", name, project.ProjectID))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get ...
|
||||
func (m *MetadataAPI) Get() {
|
||||
var metas map[string]string
|
||||
var err error
|
||||
if len(m.name) > 0 {
|
||||
metas, err = m.metaMgr.Get(m.project.ProjectID, m.name)
|
||||
} else {
|
||||
metas, err = m.metaMgr.Get(m.project.ProjectID)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
m.HandleInternalServerError(fmt.Sprintf("failed to get metadata %s of project %d: %v", m.name, m.project.ProjectID, err))
|
||||
return
|
||||
}
|
||||
m.Data["json"] = metas
|
||||
m.ServeJSON()
|
||||
}
|
||||
|
||||
// Post ...
|
||||
func (m *MetadataAPI) Post() {
|
||||
var metas map[string]string
|
||||
m.DecodeJSONReq(&metas)
|
||||
|
||||
ms, err := validateProjectMetadata(metas)
|
||||
if err != nil {
|
||||
m.HandleBadRequest(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(ms) != 1 {
|
||||
m.HandleBadRequest("invalid request: has no valid key/value pairs or has more than one valid key/value pairs")
|
||||
return
|
||||
}
|
||||
|
||||
keys := reflect.ValueOf(ms).MapKeys()
|
||||
mts, err := m.metaMgr.Get(m.project.ProjectID, keys[0].String())
|
||||
if err != nil {
|
||||
m.HandleInternalServerError(fmt.Sprintf("failed to get metadata for project %d: %v", m.project.ProjectID, err))
|
||||
return
|
||||
}
|
||||
|
||||
if len(mts) != 0 {
|
||||
m.HandleConflict()
|
||||
return
|
||||
}
|
||||
|
||||
if err := m.metaMgr.Add(m.project.ProjectID, ms); err != nil {
|
||||
m.HandleInternalServerError(fmt.Sprintf("failed to create metadata for project %d: %v", m.project.ProjectID, err))
|
||||
return
|
||||
}
|
||||
|
||||
m.Ctx.ResponseWriter.WriteHeader(http.StatusCreated)
|
||||
}
|
||||
|
||||
// Put ...
|
||||
func (m *MetadataAPI) Put() {
|
||||
var metas map[string]string
|
||||
m.DecodeJSONReq(&metas)
|
||||
|
||||
meta, exist := metas[m.name]
|
||||
if !exist {
|
||||
m.HandleBadRequest(fmt.Sprintf("must contains key %s", m.name))
|
||||
return
|
||||
}
|
||||
|
||||
ms, err := validateProjectMetadata(map[string]string{
|
||||
m.name: meta,
|
||||
})
|
||||
if err != nil {
|
||||
m.HandleBadRequest(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := m.metaMgr.Update(m.project.ProjectID, map[string]string{
|
||||
m.name: ms[m.name],
|
||||
}); err != nil {
|
||||
m.HandleInternalServerError(fmt.Sprintf("failed to update metadata %s of project %d: %v", m.name, m.project.ProjectID, err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Delete ...
|
||||
func (m *MetadataAPI) Delete() {
|
||||
if err := m.metaMgr.Delete(m.project.ProjectID, m.name); err != nil {
|
||||
m.HandleInternalServerError(fmt.Sprintf("failed to delete metadata %s of project %d: %v", m.name, m.project.ProjectID, err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// validate metas and return a new map which contains the valid key/value pairs only
|
||||
func validateProjectMetadata(metas map[string]string) (map[string]string, error) {
|
||||
if len(metas) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
boolMetas := []string{
|
||||
models.ProMetaPublic,
|
||||
models.ProMetaEnableContentTrust,
|
||||
models.ProMetaPreventVul,
|
||||
models.ProMetaAutoScan}
|
||||
|
||||
for _, boolMeta := range boolMetas {
|
||||
value, exist := metas[boolMeta]
|
||||
if exist {
|
||||
b, err := strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse %s to bool: %v", value, err)
|
||||
}
|
||||
metas[boolMeta] = strconv.FormatBool(b)
|
||||
}
|
||||
}
|
||||
|
||||
value, exist := metas[models.ProMetaSeverity]
|
||||
if exist {
|
||||
switch strings.ToLower(value) {
|
||||
case models.SeverityHigh, models.SeverityMedium, models.SeverityLow, models.SeverityNone:
|
||||
metas[models.ProMetaSeverity] = strings.ToLower(value)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid severity %s", value)
|
||||
}
|
||||
}
|
||||
|
||||
return metas, nil
|
||||
}
|
112
src/ui/api/metadata_test.go
Normal file
112
src/ui/api/metadata_test.go
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
)
|
||||
|
||||
func TestValidateProjectMetadata(t *testing.T) {
|
||||
var metas map[string]string
|
||||
|
||||
// nil metas
|
||||
ms, err := validateProjectMetadata(metas)
|
||||
require.Nil(t, err)
|
||||
require.Nil(t, ms)
|
||||
|
||||
// valid key, invalid value(bool)
|
||||
metas = map[string]string{
|
||||
models.ProMetaPublic: "invalid_value",
|
||||
}
|
||||
ms, err = validateProjectMetadata(metas)
|
||||
require.NotNil(t, err)
|
||||
|
||||
// valid key/value(bool)
|
||||
metas = map[string]string{
|
||||
models.ProMetaPublic: "1",
|
||||
}
|
||||
ms, err = validateProjectMetadata(metas)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, "true", ms[models.ProMetaPublic])
|
||||
|
||||
// valid key, invalid value(string)
|
||||
metas = map[string]string{
|
||||
models.ProMetaSeverity: "invalid_value",
|
||||
}
|
||||
ms, err = validateProjectMetadata(metas)
|
||||
require.NotNil(t, err)
|
||||
|
||||
// valid key, valid value(string)
|
||||
metas = map[string]string{
|
||||
models.ProMetaSeverity: "High",
|
||||
}
|
||||
ms, err = validateProjectMetadata(metas)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, "high", ms[models.ProMetaSeverity])
|
||||
}
|
||||
|
||||
func TestMetaAPI(t *testing.T) {
|
||||
client := newHarborAPI()
|
||||
|
||||
// non-exist project
|
||||
code, _, err := client.PostMeta(*unknownUsr, int64(1000), nil)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusNotFound, code)
|
||||
|
||||
// non-login
|
||||
code, _, err = client.PostMeta(*unknownUsr, int64(1), nil)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusUnauthorized, code)
|
||||
|
||||
// test post
|
||||
code, _, err = client.PostMeta(*admin, int64(1), map[string]string{
|
||||
models.ProMetaAutoScan: "true",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusCreated, code)
|
||||
|
||||
// test get
|
||||
code, metas, err := client.GetMeta(*admin, int64(1), models.ProMetaAutoScan)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
assert.Equal(t, "true", metas[models.ProMetaAutoScan])
|
||||
|
||||
// test put
|
||||
code, _, err = client.PutMeta(*admin, int64(1), models.ProMetaAutoScan,
|
||||
map[string]string{
|
||||
models.ProMetaAutoScan: "false",
|
||||
})
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
|
||||
code, metas, err = client.GetMeta(*admin, int64(1), models.ProMetaAutoScan)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
assert.Equal(t, "false", metas[models.ProMetaAutoScan])
|
||||
|
||||
// test delete
|
||||
code, _, err = client.DeleteMeta(*admin, int64(1), models.ProMetaAutoScan)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusOK, code)
|
||||
|
||||
code, metas, err = client.GetMeta(*admin, int64(1), models.ProMetaAutoScan)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusNotFound, code)
|
||||
}
|
@ -18,7 +18,6 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
@ -500,38 +499,11 @@ func validateProjectReq(req *models.ProjectRequest) error {
|
||||
return fmt.Errorf("project name is not in lower case or contains illegal characters")
|
||||
}
|
||||
|
||||
if req.Metadata != nil {
|
||||
metas := req.Metadata
|
||||
req.Metadata = map[string]string{}
|
||||
|
||||
boolMetas := []string{
|
||||
models.ProMetaPublic,
|
||||
models.ProMetaEnableContentTrust,
|
||||
models.ProMetaPreventVul,
|
||||
models.ProMetaAutoScan}
|
||||
|
||||
for _, boolMeta := range boolMetas {
|
||||
value, exist := metas[boolMeta]
|
||||
if exist {
|
||||
b, err := strconv.ParseBool(value)
|
||||
metas, err := validateProjectMetadata(req.Metadata)
|
||||
if err != nil {
|
||||
log.Errorf("failed to parse %s to bool: %v", value, err)
|
||||
b = false
|
||||
}
|
||||
req.Metadata[boolMeta] = strconv.FormatBool(b)
|
||||
}
|
||||
}
|
||||
|
||||
value, exist := metas[models.ProMetaSeverity]
|
||||
if exist {
|
||||
switch strings.ToLower(value) {
|
||||
case models.SeverityHigh, models.SeverityMedium, models.SeverityLow, models.SeverityNone:
|
||||
req.Metadata[models.ProMetaSeverity] = strings.ToLower(value)
|
||||
default:
|
||||
return fmt.Errorf("invalid severity %s", value)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
req.Metadata = metas
|
||||
return nil
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ type ProjectManager interface {
|
||||
Exists(projectIDOrName interface{}) (bool, error)
|
||||
// get all public project
|
||||
GetPublic() ([]*models.Project, error)
|
||||
// if the project manager uses a metadata manager, return it, otherwise return nil
|
||||
GetMetadataManager() metamgr.ProjectMetadataManager
|
||||
}
|
||||
|
||||
type defaultProjectManager struct {
|
||||
@ -235,3 +237,7 @@ func (d *defaultProjectManager) GetPublic() ([]*models.Project, error) {
|
||||
}
|
||||
return result.Projects, nil
|
||||
}
|
||||
|
||||
func (d *defaultProjectManager) GetMetadataManager() metamgr.ProjectMetadataManager {
|
||||
return d.metaMgr
|
||||
}
|
||||
|
@ -119,3 +119,8 @@ func TestGetPublic(t *testing.T) {
|
||||
assert.Equal(t, 1, len(projects))
|
||||
assert.True(t, projects[0].IsPublic())
|
||||
}
|
||||
|
||||
func TestGetMetadataManager(t *testing.T) {
|
||||
metaMgr := proMgr.GetMetadataManager()
|
||||
assert.Nil(t, metaMgr)
|
||||
}
|
||||
|
@ -87,6 +87,9 @@ func initRouters() {
|
||||
beego.Router("/api/projects/", &api.ProjectAPI{}, "get:List;post:Post")
|
||||
beego.Router("/api/projects/:id([0-9]+)/logs", &api.ProjectAPI{}, "get:Logs")
|
||||
beego.Router("/api/projects/:id([0-9]+)/_deletable", &api.ProjectAPI{}, "get:Deletable")
|
||||
beego.Router("/api/projects/:id([0-9]+)/metadatas/?:name", &api.MetadataAPI{}, "get:Get")
|
||||
beego.Router("/api/projects/:id([0-9]+)/metadatas/", &api.MetadataAPI{}, "post:Post")
|
||||
beego.Router("/api/projects/:id([0-9]+)/metadatas/:name", &api.MetadataAPI{}, "put:Put;delete:Delete")
|
||||
beego.Router("/api/internal/syncregistry", &api.InternalAPI{}, "post:SyncRegistry")
|
||||
beego.Router("/api/repositories", &api.RepositoryAPI{}, "get:Get")
|
||||
beego.Router("/api/repositories/scanAll", &api.RepositoryAPI{}, "post:ScanAll")
|
||||
|
Loading…
Reference in New Issue
Block a user