mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-05-18 14:47:13 +02:00
Add api for tag handling within cc-backend
This commit is contained in:
parent
13386175f5
commit
7abdd0545e
@ -143,7 +143,7 @@ func (r *mutationResolver) CreateTag(ctx context.Context, typeArg string, name s
|
|||||||
return &schema.Tag{ID: id, Type: typeArg, Name: name, Scope: scope}, nil
|
return &schema.Tag{ID: id, Type: typeArg, Name: name, Scope: scope}, nil
|
||||||
} else {
|
} else {
|
||||||
log.Warnf("Not authorized to create tag with scope: %s", scope)
|
log.Warnf("Not authorized to create tag with scope: %s", scope)
|
||||||
return nil, fmt.Errorf("Not authorized to create tag with scope: %s", scope)
|
return nil, fmt.Errorf("not authorized to create tag with scope: %s", scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ func (r *mutationResolver) AddTagsToJob(ctx context.Context, job string, tagIds
|
|||||||
_, _, tscope, exists := r.Repo.TagInfo(tid)
|
_, _, tscope, exists := r.Repo.TagInfo(tid)
|
||||||
if !exists {
|
if !exists {
|
||||||
log.Warnf("Tag does not exist (ID): %d", tid)
|
log.Warnf("Tag does not exist (ID): %d", tid)
|
||||||
return nil, fmt.Errorf("Tag does not exist (ID): %d", tid)
|
return nil, fmt.Errorf("tag does not exist (ID): %d", tid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test Access: Admins && Admin Tag OR Support/Admin and Global Tag OR Everyone && Private Tag
|
// Test Access: Admins && Admin Tag OR Support/Admin and Global Tag OR Everyone && Private Tag
|
||||||
@ -193,7 +193,7 @@ func (r *mutationResolver) AddTagsToJob(ctx context.Context, job string, tagIds
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Warnf("Not authorized to add tag: %d", tid)
|
log.Warnf("Not authorized to add tag: %d", tid)
|
||||||
return nil, fmt.Errorf("Not authorized to add tag: %d", tid)
|
return nil, fmt.Errorf("not authorized to add tag: %d", tid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ func (r *mutationResolver) RemoveTagsFromJob(ctx context.Context, job string, ta
|
|||||||
_, _, tscope, exists := r.Repo.TagInfo(tid)
|
_, _, tscope, exists := r.Repo.TagInfo(tid)
|
||||||
if !exists {
|
if !exists {
|
||||||
log.Warnf("Tag does not exist (ID): %d", tid)
|
log.Warnf("Tag does not exist (ID): %d", tid)
|
||||||
return nil, fmt.Errorf("Tag does not exist (ID): %d", tid)
|
return nil, fmt.Errorf("tag does not exist (ID): %d", tid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test Access: Admins && Admin Tag OR Support/Admin and Global Tag OR Everyone && Private Tag
|
// Test Access: Admins && Admin Tag OR Support/Admin and Global Tag OR Everyone && Private Tag
|
||||||
@ -240,7 +240,7 @@ func (r *mutationResolver) RemoveTagsFromJob(ctx context.Context, job string, ta
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Warnf("Not authorized to remove tag: %d", tid)
|
log.Warnf("Not authorized to remove tag: %d", tid)
|
||||||
return nil, fmt.Errorf("Not authorized to remove tag: %d", tid)
|
return nil, fmt.Errorf("not authorized to remove tag: %d", tid)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ func (r *mutationResolver) RemoveTagFromList(ctx context.Context, tagIds []strin
|
|||||||
_, _, tscope, exists := r.Repo.TagInfo(tid)
|
_, _, tscope, exists := r.Repo.TagInfo(tid)
|
||||||
if !exists {
|
if !exists {
|
||||||
log.Warnf("Tag does not exist (ID): %d", tid)
|
log.Warnf("Tag does not exist (ID): %d", tid)
|
||||||
return nil, fmt.Errorf("Tag does not exist (ID): %d", tid)
|
return nil, fmt.Errorf("tag does not exist (ID): %d", tid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test Access: Admins && Admin Tag OR Everyone && Private Tag
|
// Test Access: Admins && Admin Tag OR Everyone && Private Tag
|
||||||
@ -283,7 +283,7 @@ func (r *mutationResolver) RemoveTagFromList(ctx context.Context, tagIds []strin
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Warnf("Not authorized to remove tag: %d", tid)
|
log.Warnf("Not authorized to remove tag: %d", tid)
|
||||||
return nil, fmt.Errorf("Not authorized to remove tag: %d", tid)
|
return nil, fmt.Errorf("not authorized to remove tag: %d", tid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tags, nil
|
return tags, nil
|
||||||
@ -499,10 +499,7 @@ func (r *queryResolver) Jobs(ctx context.Context, filter []*model.JobFilter, pag
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
hasNextPage := false
|
hasNextPage := len(nextJobs) == 1
|
||||||
if len(nextJobs) == 1 {
|
|
||||||
hasNextPage = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return &model.JobResultList{Items: jobs, Count: &count, HasNextPage: &hasNextPage}, nil
|
return &model.JobResultList{Items: jobs, Count: &count, HasNextPage: &hasNextPage}, nil
|
||||||
}
|
}
|
||||||
@ -513,8 +510,8 @@ func (r *queryResolver) JobsStatistics(ctx context.Context, filter []*model.JobF
|
|||||||
var stats []*model.JobsStatistics
|
var stats []*model.JobsStatistics
|
||||||
|
|
||||||
// Top Level Defaults
|
// Top Level Defaults
|
||||||
var defaultDurationBins string = "1h"
|
defaultDurationBins := "1h"
|
||||||
var defaultMetricBins int = 10
|
defaultMetricBins := 10
|
||||||
|
|
||||||
if requireField(ctx, "totalJobs") || requireField(ctx, "totalWalltime") || requireField(ctx, "totalNodes") || requireField(ctx, "totalCores") ||
|
if requireField(ctx, "totalJobs") || requireField(ctx, "totalWalltime") || requireField(ctx, "totalNodes") || requireField(ctx, "totalCores") ||
|
||||||
requireField(ctx, "totalAccs") || requireField(ctx, "totalNodeHours") || requireField(ctx, "totalCoreHours") || requireField(ctx, "totalAccHours") {
|
requireField(ctx, "totalAccs") || requireField(ctx, "totalNodeHours") || requireField(ctx, "totalCoreHours") || requireField(ctx, "totalAccHours") {
|
||||||
@ -779,9 +776,11 @@ func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
|||||||
// SubCluster returns generated.SubClusterResolver implementation.
|
// SubCluster returns generated.SubClusterResolver implementation.
|
||||||
func (r *Resolver) SubCluster() generated.SubClusterResolver { return &subClusterResolver{r} }
|
func (r *Resolver) SubCluster() generated.SubClusterResolver { return &subClusterResolver{r} }
|
||||||
|
|
||||||
type clusterResolver struct{ *Resolver }
|
type (
|
||||||
type jobResolver struct{ *Resolver }
|
clusterResolver struct{ *Resolver }
|
||||||
type metricValueResolver struct{ *Resolver }
|
jobResolver struct{ *Resolver }
|
||||||
type mutationResolver struct{ *Resolver }
|
metricValueResolver struct{ *Resolver }
|
||||||
type queryResolver struct{ *Resolver }
|
mutationResolver struct{ *Resolver }
|
||||||
type subClusterResolver struct{ *Resolver }
|
queryResolver struct{ *Resolver }
|
||||||
|
subClusterResolver struct{ *Resolver }
|
||||||
|
)
|
||||||
|
@ -45,6 +45,36 @@ func (r *JobRepository) AddTag(user *schema.User, job int64, tag int64) ([]*sche
|
|||||||
return tags, archive.UpdateTags(j, archiveTags)
|
return tags, archive.UpdateTags(j, archiveTags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *JobRepository) AddTagDirect(job int64, tag int64) ([]*schema.Tag, error) {
|
||||||
|
j, err := r.FindByIdDirect(job)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Error while finding job by id")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
q := sq.Insert("jobtag").Columns("job_id", "tag_id").Values(job, tag)
|
||||||
|
|
||||||
|
if _, err := q.RunWith(r.stmtCache).Exec(); err != nil {
|
||||||
|
s, _, _ := q.ToSql()
|
||||||
|
log.Errorf("Error adding tag with %s: %v", s, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tags, err := r.GetTagsDirect(&job)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Error while getting tags for job")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
archiveTags, err := r.getArchiveTags(&job)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Error while getting tags for job")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags, archive.UpdateTags(j, archiveTags)
|
||||||
|
}
|
||||||
|
|
||||||
// Removes a tag from a job by tag id
|
// Removes a tag from a job by tag id
|
||||||
func (r *JobRepository) RemoveTag(user *schema.User, job, tag int64) ([]*schema.Tag, error) {
|
func (r *JobRepository) RemoveTag(user *schema.User, job, tag int64) ([]*schema.Tag, error) {
|
||||||
j, err := r.FindByIdWithUser(user, job)
|
j, err := r.FindByIdWithUser(user, job)
|
||||||
@ -82,7 +112,7 @@ func (r *JobRepository) RemoveJobTagByRequest(user *schema.User, job int64, tagT
|
|||||||
tagID, exists := r.TagId(tagType, tagName, tagScope)
|
tagID, exists := r.TagId(tagType, tagName, tagScope)
|
||||||
if !exists {
|
if !exists {
|
||||||
log.Warnf("Tag does not exist (name, type, scope): %s, %s, %s", tagName, tagType, tagScope)
|
log.Warnf("Tag does not exist (name, type, scope): %s, %s, %s", tagName, tagType, tagScope)
|
||||||
return nil, fmt.Errorf("Tag does not exist (name, type, scope): %s, %s, %s", tagName, tagType, tagScope)
|
return nil, fmt.Errorf("tag does not exist (name, type, scope): %s, %s, %s", tagName, tagType, tagScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Job
|
// Get Job
|
||||||
@ -122,7 +152,7 @@ func (r *JobRepository) RemoveTagByRequest(tagType string, tagName string, tagSc
|
|||||||
tagID, exists := r.TagId(tagType, tagName, tagScope)
|
tagID, exists := r.TagId(tagType, tagName, tagScope)
|
||||||
if !exists {
|
if !exists {
|
||||||
log.Warnf("Tag does not exist (name, type, scope): %s, %s, %s", tagName, tagType, tagScope)
|
log.Warnf("Tag does not exist (name, type, scope): %s, %s, %s", tagName, tagType, tagScope)
|
||||||
return fmt.Errorf("Tag does not exist (name, type, scope): %s, %s, %s", tagName, tagType, tagScope)
|
return fmt.Errorf("tag does not exist (name, type, scope): %s, %s, %s", tagName, tagType, tagScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Delete JobTagTable
|
// Handle Delete JobTagTable
|
||||||
@ -291,6 +321,24 @@ func (r *JobRepository) AddTagOrCreate(user *schema.User, jobId int64, tagType s
|
|||||||
return tagId, nil
|
return tagId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *JobRepository) AddTagOrCreateDirect(jobId int64, tagType string, tagName string) (tagId int64, err error) {
|
||||||
|
tagScope := "global"
|
||||||
|
|
||||||
|
tagId, exists := r.TagId(tagType, tagName, tagScope)
|
||||||
|
if !exists {
|
||||||
|
tagId, err = r.CreateTag(tagType, tagName, tagScope)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := r.AddTagDirect(jobId, tagId); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tagId, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *JobRepository) HasTag(jobId int64, tagType string, tagName string) bool {
|
func (r *JobRepository) HasTag(jobId int64, tagType string, tagName string) bool {
|
||||||
var id int64
|
var id int64
|
||||||
q := sq.Select("id").From("tag").Join("jobtag ON jobtag.tag_id = tag.id").
|
q := sq.Select("id").From("tag").Join("jobtag ON jobtag.tag_id = tag.id").
|
||||||
@ -359,6 +407,32 @@ func (r *JobRepository) GetTags(user *schema.User, job *int64) ([]*schema.Tag, e
|
|||||||
return tags, nil
|
return tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *JobRepository) GetTagsDirect(job *int64) ([]*schema.Tag, error) {
|
||||||
|
q := sq.Select("id", "tag_type", "tag_name", "tag_scope").From("tag")
|
||||||
|
if job != nil {
|
||||||
|
q = q.Join("jobtag ON jobtag.tag_id = tag.id").Where("jobtag.job_id = ?", *job)
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := q.RunWith(r.stmtCache).Query()
|
||||||
|
if err != nil {
|
||||||
|
s, _, _ := q.ToSql()
|
||||||
|
log.Errorf("Error get tags with %s: %v", s, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tags := make([]*schema.Tag, 0)
|
||||||
|
for rows.Next() {
|
||||||
|
tag := &schema.Tag{}
|
||||||
|
if err := rows.Scan(&tag.ID, &tag.Type, &tag.Name, &tag.Scope); err != nil {
|
||||||
|
log.Warn("Error while scanning rows")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tags = append(tags, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetArchiveTags returns a list of all tags *regardless of scope* for archiving if job is nil or of the tags that the job with that database ID has.
|
// GetArchiveTags returns a list of all tags *regardless of scope* for archiving if job is nil or of the tags that the job with that database ID has.
|
||||||
func (r *JobRepository) getArchiveTags(job *int64) ([]*schema.Tag, error) {
|
func (r *JobRepository) getArchiveTags(job *int64) ([]*schema.Tag, error) {
|
||||||
q := sq.Select("id", "tag_type", "tag_name", "tag_scope").From("tag")
|
q := sq.Select("id", "tag_type", "tag_name", "tag_scope").From("tag")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Copyright (C) 2023 NHR@FAU, University Erlangen-Nuremberg.
|
// Copyright (C) NHR@FAU, University Erlangen-Nuremberg.
|
||||||
// All rights reserved.
|
// All rights reserved. This file is part of cc-backend.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
package tagger
|
package tagger
|
||||||
@ -72,7 +72,7 @@ func (t *AppTagger) Match(job *schema.Job) {
|
|||||||
for _, s := range a.strings {
|
for _, s := range a.strings {
|
||||||
if strings.Contains(jobscript, s) {
|
if strings.Contains(jobscript, s) {
|
||||||
if !r.HasTag(id, tagType, tag) {
|
if !r.HasTag(id, tagType, tag) {
|
||||||
r.AddTagOrCreate(id, tagType, tag)
|
r.AddTagOrCreateDirect(id, tagType, tag)
|
||||||
break out
|
break out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ func TestRegister(t *testing.T) {
|
|||||||
func TestMatch(t *testing.T) {
|
func TestMatch(t *testing.T) {
|
||||||
r := setup(t)
|
r := setup(t)
|
||||||
|
|
||||||
job, err := r.FindById(5)
|
job, err := r.FindByIdDirect(5)
|
||||||
noErr(t, err)
|
noErr(t, err)
|
||||||
|
|
||||||
var tagger AppTagger
|
var tagger AppTagger
|
||||||
|
Loading…
x
Reference in New Issue
Block a user