Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RHINENG-10240: check compatiblity of template and system rhel version #1436

Merged
merged 3 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions base/database/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ func DeleteSystem(t *testing.T, inventoryID string) {
func CreateTemplate(t *testing.T, account int, uuid string, inventoryIDs []string) {
template := &models.Template{
RhAccountID: account, UUID: uuid, Name: uuid, EnvironmentID: strings.ReplaceAll(uuid, "-", ""),
Arch: "x86_64", Version: "8",
}

tx := DB.Begin()
Expand Down
3 changes: 3 additions & 0 deletions base/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type Template struct {
UUID string
EnvironmentID string
Name string
Arch string
Version string
// Config pgtype.JSONB // currently unused
Description *string
Creator *string // pointer for compatibility with previous API versions
Expand Down Expand Up @@ -92,6 +94,7 @@ type SystemPlatform struct {
YumChecksum *string `gorm:"column:yum_checksum"`
SatelliteManaged bool `gorm:"column:satellite_managed"`
BuiltPkgcache bool `gorm:"column:built_pkgcache"`
Arch *string
}

func (SystemPlatform) TableName() string {
Expand Down
2 changes: 2 additions & 0 deletions database_admin/migrations/127_template_arch_version.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE template DROP COLUMN IF EXISTS version;
ALTER TABLE template DROP COLUMN IF EXISTS arch;
3 changes: 3 additions & 0 deletions database_admin/migrations/127_template_arch_version.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE template ADD COLUMN IF NOT EXISTS arch TEXT CHECK (NOT empty(arch));
ALTER TABLE template ADD COLUMN IF NOT EXISTS version TEXT CHECK (NOT empty(version));
ALTER TABLE system_platform ADD COLUMN IF NOT EXISTS arch TEXT CHECK (NOT empty(arch));
5 changes: 4 additions & 1 deletion database_admin/schema/create_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS schema_migrations


INSERT INTO schema_migrations
VALUES (126, false);
VALUES (127, false);

-- ---------------------------------------------------------------------------
-- Functions
Expand Down Expand Up @@ -693,6 +693,8 @@ CREATE TABLE IF NOT EXISTS template
published TIMESTAMP WITH TIME ZONE,
last_edited TIMESTAMP WITH TIME ZONE,
environment_id TEXT NOT NULL CHECK (not empty(environment_id)),
arch TEXT CHECK (not empty(arch)),
version TEXT CHECK (not empty(version)),
PRIMARY KEY (rh_account_id, id),
UNIQUE(rh_account_id, uuid)
) PARTITION BY HASH (rh_account_id);
Expand Down Expand Up @@ -742,6 +744,7 @@ CREATE TABLE IF NOT EXISTS system_platform
packages_applicable INT NOT NULL DEFAULT 0,
template_id BIGINT,
yum_checksum TEXT CHECK (NOT empty(yum_checksum)),
arch TEXT CHECK (NOT empty(arch)),
PRIMARY KEY (rh_account_id, id),
UNIQUE (rh_account_id, inventory_id),
CONSTRAINT reporter_id FOREIGN KEY (reporter_id) REFERENCES reporter (id),
Expand Down
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
2 changes: 2 additions & 0 deletions listener/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ func TemplateUpdate(template mqueue.TemplateResponse) error {
UUID: template.UUID,
EnvironmentID: template.EnvironmentID,
Name: template.Name,
Arch: template.Arch,
Version: template.Version,
//Config: nil,
Description: template.Description,
Creator: nil,
Expand Down
2 changes: 2 additions & 0 deletions listener/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ func updateSystemPlatform(tx *gorm.DB, inventoryID string, accountID int, host *
"culled_timestamp",
"satellite_managed",
"built_pkgcache",
"arch",
}

now := time.Now()
Expand All @@ -345,6 +346,7 @@ func updateSystemPlatform(tx *gorm.DB, inventoryID string, accountID int, host *
YumChecksum: utils.EmptyToNil(&yumChecksum),
SatelliteManaged: host.SystemProfile.SatelliteManaged,
BuiltPkgcache: yumUpdates.GetBuiltPkgcache(),
Arch: host.SystemProfile.Arch,
}

type OldChecksums struct {
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
}
8 changes: 4 additions & 4 deletions platform/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ var templates = []mqueue.TemplateResponse{
OrgID: "org_1",
Description: &desc1,
Arch: "x86_64",
Version: "1",
Version: "8",
Date: time.Now(),
RepositoryUUIDS: []string{"20000000-0000-0000-0000-000000000001"},
EnvironmentID: "10000000000000000000000000000001",
Expand All @@ -172,7 +172,7 @@ var templates = []mqueue.TemplateResponse{
OrgID: "org_1",
Description: &desc2,
Arch: "x86_64",
Version: "1",
Version: "8",
Date: time.Now(),
RepositoryUUIDS: []string{"20000000-0000-0000-0000-000000000001", "20000000-0000-0000-0000-000000000002"},
EnvironmentID: "10000000000000000000000000000002",
Expand Down Expand Up @@ -334,8 +334,8 @@ func mockCreatedTemplates(c *gin.Context) {

func mockUpdatedTemplates(c *gin.Context) {
updated := templates
updated[0].Version = "2"
updated[1].Version = "2"
updated[0].Version = "9"
updated[1].Version = "9"
err := sendTemplateMsg("template-updated", templates)
if err != nil {
c.JSON(http.StatusInternalServerError, err.Error())
Expand Down
Loading