Skip to content

Commit

Permalink
RHINENG-10240: check compatiblity of template and system rhel version…
Browse files Browse the repository at this point in the history
…,arch
  • Loading branch information
psegedy committed Jun 17, 2024
1 parent e0cac9d commit 355ce3a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 14 deletions.
2 changes: 2 additions & 0 deletions listener/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ func createTempateMsg(t *testing.T, eventName, orgID string, nTemplates int) mqu
OrgID: orgID,
Description: &description,
Date: time.Now(),
Arch: "x86_64",
Version: "8",
}
}

Expand Down
21 changes: 10 additions & 11 deletions manager/controllers/template_systems.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,42 +53,41 @@ type TemplateSystemsResponse struct {
Meta ListMeta `json:"meta"`
}

func getTemplateID(c *gin.Context, tx *gorm.DB, account int, uuid string) (int64, error) {
var id int64
func getTemplate(c *gin.Context, tx *gorm.DB, account int, uuid string) (*models.Template, error) {
var template models.Template
if !utils.IsValidUUID(uuid) {
err := errors.Errorf("Invalid template uuid: %s", uuid)
LogAndRespNotFound(c, err, err.Error())
return 0, err
return &template, err
}
err := tx.Model(&models.Template{}).
Select("id").
Where("rh_account_id = ? AND uuid = ?::uuid ", account, uuid).
// use Find() not First() otherwise it returns error "no rows found" if uuid is not present
Find(&id).Error
Find(&template).Error
if err != nil {
LogAndRespError(c, err, "database error")
return 0, err
return &template, err
}
if id == 0 {
if template.ID == 0 {
err := errors.New("Template not found")
LogAndRespNotFound(c, err, err.Error())
return 0, err
return &template, err
}
return id, nil
return &template, nil
}

func templateSystemsQuery(c *gin.Context, account int, groups map[string]string) (*gorm.DB, Filters, error) {
templateUUID := c.Param("template_id")
db := middlewares.DBFromContext(c)

templateID, err := getTemplateID(c, db, account, templateUUID)
template, err := getTemplate(c, db, account, templateUUID)
if err != nil {
// respose set in getTemplateID()
return nil, nil, err
}

query := database.Systems(db, account, groups).
Where("sp.template_id = ?", templateID).
Where("sp.template_id = ?", template.ID).
Select(templateSystemSelect)

filters, err := ParseAllFilters(c, TemplateSystemOpts)
Expand Down
46 changes: 43 additions & 3 deletions manager/controllers/template_systems_update.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package controllers

import (
"app/base/database"
"app/base/models"
"app/base/utils"
"app/manager/config"
"app/manager/middlewares"
"fmt"
"net/http"

errors2 "errors"

"github.com/pkg/errors"
"gorm.io/gorm"

Expand Down Expand Up @@ -44,13 +47,13 @@ func TemplateSystemsUpdateHandler(c *gin.Context) {
}

db := middlewares.DBFromContext(c)
templateID, err := getTemplateID(c, db, account, templateUUID)
template, err := getTemplate(c, db, account, templateUUID)
if err != nil {
// respose set in getTemplateID()
return
}

err = assignTemplateSystems(c, db, account, &templateID, req.Systems, groups)
err = assignTemplateSystems(c, db, account, template, req.Systems, groups)
if err != nil {
return
}
Expand All @@ -62,7 +65,7 @@ func TemplateSystemsUpdateHandler(c *gin.Context) {
c.Status(http.StatusOK)
}

func assignTemplateSystems(c *gin.Context, db *gorm.DB, accountID int, templateID *int64,
func assignTemplateSystems(c *gin.Context, db *gorm.DB, accountID int, template *models.Template,
inventoryIDs []string, groups map[string]string) error {
if len(inventoryIDs) == 0 {
err := errors.New(InvalidInventoryIDsErr)
Expand All @@ -88,6 +91,18 @@ func assignTemplateSystems(c *gin.Context, db *gorm.DB, accountID int, templateI
return err
}

if err := templateArchVersionMatch(db, inventoryIDs, template, accountID, groups); err != nil {
msg := fmt.Sprintf("Incompatible template and system version or architecture: %s", err.Error())
LogAndRespBadRequest(c, err, msg)
return err
}

// if we want to unassign system from template, we need to set template_id=null
var templateID *int64
if template != nil && template.ID != 0 {
templateID = &template.ID
}

tx = tx.Model(models.SystemPlatform{}).
Where("rh_account_id = ? AND inventory_id IN (?::uuid)",
accountID, inventoryIDs).
Expand All @@ -109,3 +124,28 @@ func assignTemplateSystems(c *gin.Context, db *gorm.DB, accountID int, templateI
}
return nil
}

func templateArchVersionMatch(
db *gorm.DB, inventoryIDs []string, template *models.Template, acc int, groups map[string]string,
) error {
var sysArchVersions = []struct {
InventoryID string
Arch string
Version string
}{}
var err error
database.Systems(db, acc, groups).
Select("ih.id as inventory_id, ih.system_profile->'operating_system'->>'major' as version, sp.arch as arch").
Where("id in (?)", inventoryIDs).Find(&sysArchVersions)

for _, sys := range sysArchVersions {
if sys.Version != template.Version && sys.Arch != template.Arch {
if err == nil {
err = fmt.Errorf("template arch: %s, version: %s", template.Arch, template.Version)
}
systemErr := fmt.Errorf("system uuid: %s, arch: %s, version: %s", sys.InventoryID, sys.Arch, sys.Version)
err = errors2.Join(err, systemErr)
}
}
return err
}

0 comments on commit 355ce3a

Please sign in to comment.