mirror of
https://github.com/semaphoreui/semaphore.git
synced 2025-01-20 07:19:20 +01:00
feat(be): allow filter entities by ownership
This commit is contained in:
parent
a047b7dd36
commit
dc347442c4
@ -56,7 +56,9 @@ func GetInventory(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
project := context.Get(r, "project").(db.Project)
|
||||
|
||||
inventories, err := helpers.Store(r).GetInventories(project.ID, helpers.QueryParams(r.URL))
|
||||
params := helpers.QueryParams(r.URL)
|
||||
params.Ownership.WithoutOwnerOnly = true
|
||||
inventories, err := helpers.Store(r).GetInventories(project.ID, params)
|
||||
|
||||
if err != nil {
|
||||
helpers.WriteError(w, err)
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"github.com/semaphoreui/semaphore/util"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/context"
|
||||
"github.com/semaphoreui/semaphore/api/helpers"
|
||||
"github.com/semaphoreui/semaphore/db"
|
||||
"github.com/gorilla/context"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -93,11 +93,11 @@ func AddTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if newTemplate.InventoryID == nil {
|
||||
inv, err = helpers.Store(r).CreateInventory(db.Inventory{
|
||||
Name: newTemplate.Name + " - default",
|
||||
ProjectID: project.ID,
|
||||
HolderID: &newTemplate.ID,
|
||||
Type: db.InventoryTerraformWorkspace,
|
||||
Inventory: "default",
|
||||
Name: newTemplate.Name + " - default",
|
||||
ProjectID: project.ID,
|
||||
TemplateID: &newTemplate.ID,
|
||||
Type: db.InventoryTerraformWorkspace,
|
||||
Inventory: "default",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@ -115,7 +115,7 @@ func AddTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
inv.HolderID = &newTemplate.ID
|
||||
inv.TemplateID = &newTemplate.ID
|
||||
err = helpers.Store(r).UpdateInventory(inv)
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,11 @@ type Inventory struct {
|
||||
// static/file
|
||||
Type InventoryType `db:"type" json:"type"`
|
||||
|
||||
// HolderID is an ID of template which holds the inventory
|
||||
// TemplateID is an ID of template which holds the inventory
|
||||
// It is not used now but can be used in feature for
|
||||
// inventories which can not be used more than one template
|
||||
// at once.
|
||||
HolderID *int `db:"holder_id" json:"holder_id" backup:"-"`
|
||||
TemplateID *int `db:"template_id" json:"template_id" backup:"-"`
|
||||
|
||||
// RepositoryID is an ID of repo where inventory stored.
|
||||
// If null than inventory will be got from template repository.
|
||||
|
37
db/Store.go
37
db/Store.go
@ -38,12 +38,19 @@ func ObjectToJSON(obj interface{}) *string {
|
||||
return &str
|
||||
}
|
||||
|
||||
type OwnershipFilter struct {
|
||||
WithoutOwnerOnly bool
|
||||
TemplateID *int
|
||||
EnvironmentID *int
|
||||
}
|
||||
|
||||
type RetrieveQueryParams struct {
|
||||
Offset int
|
||||
Count int
|
||||
SortBy string
|
||||
SortInverted bool
|
||||
Filter string
|
||||
Ownership OwnershipFilter
|
||||
}
|
||||
|
||||
type ObjectReferrer struct {
|
||||
@ -68,6 +75,17 @@ type IntegrationExtractorChildReferrers struct {
|
||||
Integrations []ObjectReferrer `json:"integrations"`
|
||||
}
|
||||
|
||||
func (f OwnershipFilter) GetOwnerID(ownership ObjectProps) *int {
|
||||
switch ownership.ReferringColumnSuffix {
|
||||
case "template_id":
|
||||
return f.TemplateID
|
||||
case "environment_id":
|
||||
return f.EnvironmentID
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ObjectProps describe database entities.
|
||||
// It mainly used for NoSQL implementations (currently BoltDB) to preserve same
|
||||
// data structure of different implementations and easy change it if required.
|
||||
@ -80,6 +98,7 @@ type ObjectProps struct {
|
||||
SortableColumns []string
|
||||
DefaultSortingColumn string
|
||||
SortInverted bool // sort from high to low object ID by default. It is useful for some NoSQL implementations.
|
||||
Ownerships []*ObjectProps
|
||||
}
|
||||
|
||||
var ErrNotFound = errors.New("no rows in result set")
|
||||
@ -350,6 +369,7 @@ var InventoryProps = ObjectProps{
|
||||
ReferringColumnSuffix: "inventory_id",
|
||||
SortableColumns: []string{"name"},
|
||||
DefaultSortingColumn: "name",
|
||||
Ownerships: []*ObjectProps{&TemplateProps},
|
||||
}
|
||||
|
||||
var RepositoryProps = ObjectProps{
|
||||
@ -369,12 +389,6 @@ var TemplateProps = ObjectProps{
|
||||
DefaultSortingColumn: "name",
|
||||
}
|
||||
|
||||
var ScheduleProps = ObjectProps{
|
||||
TableName: "project__schedule",
|
||||
Type: reflect.TypeOf(Schedule{}),
|
||||
PrimaryColumnName: "id",
|
||||
}
|
||||
|
||||
var ProjectUserProps = ObjectProps{
|
||||
TableName: "project__user",
|
||||
Type: reflect.TypeOf(ProjectUser{}),
|
||||
@ -390,6 +404,13 @@ var ProjectProps = ObjectProps{
|
||||
IsGlobal: true,
|
||||
}
|
||||
|
||||
var ScheduleProps = ObjectProps{
|
||||
TableName: "project__schedule",
|
||||
Type: reflect.TypeOf(Schedule{}),
|
||||
PrimaryColumnName: "id",
|
||||
Ownerships: []*ObjectProps{&ProjectProps},
|
||||
}
|
||||
|
||||
var UserProps = ObjectProps{
|
||||
TableName: "user",
|
||||
Type: reflect.TypeOf(User{}),
|
||||
@ -520,8 +541,8 @@ func ValidateInventory(store Store, inventory *Inventory) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if inventory.HolderID != nil {
|
||||
_, err = store.GetTemplate(inventory.ProjectID, *inventory.HolderID)
|
||||
if inventory.TemplateID != nil {
|
||||
_, err = store.GetTemplate(inventory.ProjectID, *inventory.TemplateID)
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -389,6 +389,30 @@ func apply(
|
||||
return
|
||||
}
|
||||
|
||||
if len(props.Ownerships) > 0 {
|
||||
|
||||
ownershipMatched := true
|
||||
|
||||
for _, ownership := range props.Ownerships {
|
||||
if params.Ownership.WithoutOwnerOnly {
|
||||
if f, ok := getReferredValue(*ownership, obj); ok && !f.IsZero() {
|
||||
ownershipMatched = false
|
||||
break
|
||||
}
|
||||
} else {
|
||||
ownerID := params.Ownership.GetOwnerID(*ownership)
|
||||
if ownerID != nil && !isObjectReferredBy(*ownership, intObjectID(*ownerID), obj) {
|
||||
ownershipMatched = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !ownershipMatched {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if filter != nil && !filter(obj) {
|
||||
continue
|
||||
}
|
||||
@ -780,18 +804,41 @@ func (d *BoltDb) getObjectRefsFrom(projectID int, objProps db.ObjectProps, objID
|
||||
return
|
||||
}
|
||||
|
||||
func isObjectReferredBy(props db.ObjectProps, objID objectID, referringObj interface{}) bool {
|
||||
func getReferredValue(props db.ObjectProps, referringObj interface{}) (f reflect.Value, ok bool) {
|
||||
if props.ReferringColumnSuffix == "" {
|
||||
return false
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
|
||||
fieldName, err := getFieldNameByTagSuffix(reflect.TypeOf(referringObj), "db", props.ReferringColumnSuffix)
|
||||
|
||||
if err != nil {
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
|
||||
f = reflect.ValueOf(referringObj).FieldByName(fieldName)
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
func isObjectReferredBy(props db.ObjectProps, objID objectID, referringObj interface{}) bool {
|
||||
f, ok := getReferredValue(props, referringObj)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
f := reflect.ValueOf(referringObj).FieldByName(fieldName)
|
||||
//if props.ReferringColumnSuffix == "" {
|
||||
// return false
|
||||
//}
|
||||
//
|
||||
//fieldName, err := getFieldNameByTagSuffix(reflect.TypeOf(referringObj), "db", props.ReferringColumnSuffix)
|
||||
//
|
||||
//if err != nil {
|
||||
// return false
|
||||
//}
|
||||
//
|
||||
//f := reflect.ValueOf(referringObj).FieldByName(fieldName)
|
||||
|
||||
if f.IsZero() {
|
||||
return false
|
||||
|
@ -210,6 +210,23 @@ func (d *SqlDb) makeObjectsQuery(projectID int, props db.ObjectProps, params db.
|
||||
q = q.Where("pe.project_id=?", projectID)
|
||||
}
|
||||
|
||||
if len(props.Ownerships) > 0 {
|
||||
for _, ownership := range props.Ownerships {
|
||||
if params.Ownership.WithoutOwnerOnly {
|
||||
q = q.Where(squirrel.Eq{
|
||||
"pe." + string(ownership.ReferringColumnSuffix): nil,
|
||||
})
|
||||
} else {
|
||||
ownerID := params.Ownership.GetOwnerID(*ownership)
|
||||
if ownerID != nil {
|
||||
q = q.Where(squirrel.Eq{
|
||||
"pe." + string(ownership.ReferringColumnSuffix): *ownerID,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
orderDirection := "ASC"
|
||||
if params.SortInverted {
|
||||
orderDirection = "DESC"
|
||||
|
@ -35,7 +35,7 @@ func (d *SqlDb) UpdateInventory(inventory db.Inventory) error {
|
||||
inventory.SSHKeyID,
|
||||
inventory.Inventory,
|
||||
inventory.BecomeKeyID,
|
||||
inventory.HolderID,
|
||||
inventory.TemplateID,
|
||||
inventory.RepositoryID,
|
||||
inventory.ID)
|
||||
|
||||
@ -53,7 +53,7 @@ func (d *SqlDb) CreateInventory(inventory db.Inventory) (newInventory db.Invento
|
||||
inventory.SSHKeyID,
|
||||
inventory.Inventory,
|
||||
inventory.BecomeKeyID,
|
||||
inventory.HolderID,
|
||||
inventory.TemplateID,
|
||||
inventory.RepositoryID)
|
||||
|
||||
if err != nil {
|
||||
|
@ -18,4 +18,6 @@ create table project__terraform_inventory_state(
|
||||
foreign key (`task_id`) references task(`id`) on delete set null,
|
||||
foreign key (`project_id`) references project(`id`) on delete cascade,
|
||||
foreign key (`inventory_id`) references project__inventory(`id`) on delete cascade
|
||||
);
|
||||
);
|
||||
|
||||
alter table `project__inventory` add `template_id` int null references project__template(`id`);
|
Loading…
Reference in New Issue
Block a user