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
  • Loading branch information
psegedy committed Jun 12, 2024
1 parent 6442e28 commit a39ac20
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
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
41 changes: 37 additions & 4 deletions manager/controllers/template_systems_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"fmt"
"net/http"

errors2 "errors"

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

Expand Down Expand Up @@ -44,13 +46,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 +64,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,10 +90,16 @@ func assignTemplateSystems(c *gin.Context, db *gorm.DB, accountID int, templateI
return err
}

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

tx = tx.Model(models.SystemPlatform{}).
Where("rh_account_id = ? AND inventory_id IN (?::uuid)",
accountID, inventoryIDs).
Update("template_id", templateID)
Update("template_id", template.ID)
if e := tx.Error; e != nil {
LogAndRespError(c, err, "Database error")
return e
Expand All @@ -109,3 +117,28 @@ func assignTemplateSystems(c *gin.Context, db *gorm.DB, accountID int, templateI
}
return nil
}

func templateArchVersionMatch(db *gorm.DB, inventoryIDs []string, template *models.Template) error {
var archVersions = []struct {
InventoryID string
Arch string
Version string
}{}
var err error
db.Table("inventory.hosts").
// TODO: we need also ARCH but it is missing in system_profile
Select("id as inventory_id, system_profile->'operating_system'->>'major' as version").
Where("id in (?)", inventoryIDs).Find(&archVersions)

for _, av := range archVersions {
if av.Version != template.Version {
// TODO: check 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", av.InventoryID, av.Arch, av.Version)
err = errors2.Join(err, systemErr)
}
}
return err
}

0 comments on commit a39ac20

Please sign in to comment.