Support creating project with service account

This commit introduces a solution to workaround the restriction of project creation API: only normal users can create projects

Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
Wenkai Yin 2019-04-17 14:16:51 +08:00
parent 3f7884d9d2
commit 6e0d892963
3 changed files with 28 additions and 6 deletions

View File

@ -79,7 +79,8 @@ create table replication_execution (
id SERIAL NOT NULL, id SERIAL NOT NULL,
policy_id int NOT NULL, policy_id int NOT NULL,
status varchar(32), status varchar(32),
status_text varchar(256), /*the status text may contain error message whose length is very long*/
status_text text,
total int NOT NULL DEFAULT 0, total int NOT NULL DEFAULT 0,
failed int NOT NULL DEFAULT 0, failed int NOT NULL DEFAULT 0,
succeed int NOT NULL DEFAULT 0, succeed int NOT NULL DEFAULT 0,

View File

@ -115,7 +115,7 @@ func (p *ProjectAPI) Post() {
} }
} }
if onlyAdmin && !p.SecurityCtx.IsSysAdmin() { if onlyAdmin && !(p.SecurityCtx.IsSysAdmin() || p.SecurityCtx.IsSolutionUser()) {
log.Errorf("Only sys admin can create project") log.Errorf("Only sys admin can create project")
p.RenderError(http.StatusForbidden, "Only system admin can create project") p.RenderError(http.StatusForbidden, "Only system admin can create project")
return return
@ -153,9 +153,23 @@ func (p *ProjectAPI) Post() {
pro.Metadata[models.ProMetaPublic] = strconv.FormatBool(false) pro.Metadata[models.ProMetaPublic] = strconv.FormatBool(false)
} }
owner := p.SecurityCtx.GetUsername()
// set the owner as the system admin when the API being called by replication
// it's a solution to workaround the restriction of project creation API:
// only normal users can create projects
if p.SecurityCtx.IsSolutionUser() {
user, err := dao.GetUser(models.User{
UserID: 1,
})
if err != nil {
p.HandleInternalServerError(fmt.Sprintf("failed to get the user 1: %v", err))
return
}
owner = user.Username
}
projectID, err := p.ProjectMgr.Create(&models.Project{ projectID, err := p.ProjectMgr.Create(&models.Project{
Name: pro.Name, Name: pro.Name,
OwnerName: p.SecurityCtx.GetUsername(), OwnerName: owner,
Metadata: pro.Metadata, Metadata: pro.Metadata,
}) })
if err != nil { if err != nil {
@ -499,8 +513,8 @@ func (p *ProjectAPI) Logs() {
// TODO move this to pa ckage models // TODO move this to pa ckage models
func validateProjectReq(req *models.ProjectRequest) error { func validateProjectReq(req *models.ProjectRequest) error {
pn := req.Name pn := req.Name
if utils.IsIllegalLength(req.Name, projectNameMinLen, projectNameMaxLen) { if utils.IsIllegalLength(pn, projectNameMinLen, projectNameMaxLen) {
return fmt.Errorf("Project name is illegal in length. (greater than %d or less than %d)", projectNameMaxLen, projectNameMinLen) return fmt.Errorf("Project name %s is illegal in length. (greater than %d or less than %d)", pn, projectNameMaxLen, projectNameMinLen)
} }
validProjectName := regexp.MustCompile(`^` + restrictedNameChars + `$`) validProjectName := regexp.MustCompile(`^` + restrictedNameChars + `$`)
legal := validProjectName.MatchString(pn) legal := validProjectName.MatchString(pn)

View File

@ -156,7 +156,14 @@ func (a *adapter) PrepareForPush(resources []*model.Resource) error {
} }
} }
for _, project := range projects { for _, project := range projects {
err := a.client.Post(a.coreServiceURL+"/api/projects", project) pro := struct {
Name string `json:"project_name"`
Metadata map[string]interface{} `json:"metadata"`
}{
Name: project.Name,
Metadata: project.Metadata,
}
err := a.client.Post(a.coreServiceURL+"/api/projects", pro)
if httpErr, ok := err.(*common_http.Error); ok && httpErr.Code == http.StatusConflict { if httpErr, ok := err.(*common_http.Error); ok && httpErr.Code == http.StatusConflict {
log.Debugf("got 409 when trying to create project %s", project.Name) log.Debugf("got 409 when trying to create project %s", project.Name)
return nil return nil