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

[chore] Persist MeshModels Policies in DB on Server Boot #320

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
5 changes: 2 additions & 3 deletions models/meshmodel/core/policies/rego_policy_relationship.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import (
)

// RegoPolicyHandler takes the required inputs and run the query against all the policy files provided
func RegoPolicyHandler(ctx context.Context, policyDir []string, regoQueryString string, designFile []byte) (map[string]interface{}, error) {
regoPolicyLoader := rego.Load(policyDir, nil)
func RegoPolicyHandler(ctx context.Context, expression string, regoQueryString string, designFile []byte) (map[string]interface{}, error) {

regoEngine, err := rego.New(
rego.Query(regoQueryString),
regoPolicyLoader,
rego.Module("expression.rego", expression),
).PrepareForEval(ctx)
if err != nil {
logrus.Error("error preparing for evaluation", err)
Expand Down
66 changes: 51 additions & 15 deletions models/meshmodel/core/v1alpha1/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import (
"github.com/google/uuid"
"github.com/layer5io/meshkit/database"
"github.com/layer5io/meshkit/models/meshmodel/core/types"
"gorm.io/gorm/clause"
)

type PolicyDefinition struct {
ID uuid.UUID `json:"-"`
TypeMeta
Model Model `json:"model"`
SubType string `json:"subType" yaml:"subType"`
Expression map[string]interface{} `json:"expression" yaml:"expression"`
Expression string `json:"expression" yaml:"expression"`
Metadata map[string]interface{} `json:"metadata" yaml:"metadata"`
CreatedAt time.Time `json:"-"`
UpdatedAt time.Time `json:"-"`
}
Expand All @@ -25,15 +27,23 @@ type PolicyDefinitionDB struct {
ModelID uuid.UUID `json:"-" gorm:"modelID"`
TypeMeta
SubType string `json:"subType" yaml:"subType"`
Expression []byte `json:"expression" yaml:"expression"`
Expression string `json:"expression" yaml:"expression"`
Metadata []byte `json:"metadata" yaml:"metadata"`
CreatedAt time.Time `json:"-"`
UpdatedAt time.Time `json:"-"`
}

type PolicyFilter struct {
Kind string
SubType string
ModelName string
Kind string
SubType string
Name string
APIVersion string
ModelName string
Version string // future use for versioning
Sort string //asc or desc. Default behavior is asc
OrderOn string //Name of the field on which sorting is to be done
Limit int //If 0 or unspecified then all records are returned and limit is not used
Offset int
}

func (pf *PolicyFilter) Create(m map[string]interface{}) {
Expand All @@ -50,15 +60,18 @@ func (p PolicyDefinition) Type() types.CapabilityType {
return types.PolicyDefinition
}

func GetMeshModelPolicy(db *database.Handler, f PolicyFilter) (pl []PolicyDefinition) {
func GetMeshModelPolicy(db *database.Handler, f PolicyFilter) (pl []PolicyDefinition, count int64) {
type componentDefinitionWithModel struct {
PolicyDefinitionDB
Model
ModelDB
CategoryDB
}

var componentDefinitionsWithModel []componentDefinitionWithModel
finder := db.Model(&PolicyDefinitionDB{}).
Select("policy_definition_dbs.*, models.*").
Joins("JOIN model_dbs ON model_dbs.id = policy_definition_dbs.model_id")
Select("policy_definition_dbs.*, model_dbs.*").
Joins("JOIN model_dbs ON model_dbs.id = policy_definition_dbs.model_id").
Joins("JOIN category_dbs ON model_dbs.category_id = category_dbs.id")
if f.Kind != "" {
finder = finder.Where("policy_definition_dbs.kind = ?", f.Kind)
}
Expand All @@ -68,25 +81,47 @@ func GetMeshModelPolicy(db *database.Handler, f PolicyFilter) (pl []PolicyDefini
if f.ModelName != "" {
finder = finder.Where("model_dbs.name = ?", f.ModelName)
}
if f.APIVersion != "" {
finder = finder.Where("policy_definition_dbs.api_version = ?", f.APIVersion)
}
if f.Name != "" {
finder = finder.Where("policy_definition_dbs.metadata ->> 'name'", f.Name)
}
if f.OrderOn != "" {
if f.Sort == "desc" {
finder = finder.Order(clause.OrderByColumn{Column: clause.Column{Name: f.OrderOn}, Desc: true})
} else {
finder = finder.Order(f.OrderOn + " asc")
}
}

finder.Count(&count)

finder = finder.Offset(f.Offset)
if f.Limit != 0 {
finder = finder.Limit(f.Limit)
}

err := finder.Scan(&componentDefinitionsWithModel).Error
if err != nil {
fmt.Println(err.Error())
}
for _, cm := range componentDefinitionsWithModel {
pl = append(pl, cm.PolicyDefinitionDB.GetPolicyDefinition(cm.Model))
pl = append(pl, cm.PolicyDefinitionDB.GetPolicyDefinition(cm.ModelDB.GetModel(cm.CategoryDB.GetCategory(db))))
}
return pl
return pl, count
}

func (pdb *PolicyDefinitionDB) GetPolicyDefinition(m Model) (p PolicyDefinition) {
p.ID = pdb.ID
p.TypeMeta = pdb.TypeMeta
p.Model = m
p.SubType = pdb.SubType
if p.Expression == nil {
p.Expression = make(map[string]interface{})
p.Expression = pdb.Expression
if p.Metadata == nil {
p.Metadata = make(map[string]interface{})
}
_ = json.Unmarshal(pdb.Expression, &p.Expression)
_ = json.Unmarshal(pdb.Metadata, &p.Metadata)

return
}
Expand All @@ -111,6 +146,7 @@ func (p *PolicyDefinition) GetPolicyDefinitionDB() (pdb PolicyDefinitionDB) {
pdb.TypeMeta = p.TypeMeta
pdb.SubType = p.SubType
pdb.ModelID = p.Model.ID
pdb.Expression, _ = json.Marshal(p.Expression)
pdb.Expression = p.Expression
pdb.Metadata, _ = json.Marshal(p.Metadata)
return
}
6 changes: 3 additions & 3 deletions models/meshmodel/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func (rm *RegistryManager) Cleanup() {
&v1alpha1.ModelDB{},
&v1alpha1.CategoryDB{},
&v1alpha1.RelationshipDefinitionDB{},
&v1alpha1.PolicyDefinitionDB{},
)
}
func (rm *RegistryManager) RegisterEntity(h Host, en Entity) error {
Expand Down Expand Up @@ -132,7 +133,6 @@ func (rm *RegistryManager) RegisterEntity(h Host, en Entity) error {
UpdatedAt: time.Now(),
}
return rm.db.Create(&entry).Error
//Add logic for Policies and other entities below
case v1alpha1.PolicyDefinition:
policyID, err := v1alpha1.CreatePolicy(rm.db, entity)
if err != nil {
Expand Down Expand Up @@ -175,11 +175,11 @@ func (rm *RegistryManager) GetEntities(f types.Filter) ([]Entity, *int64, *int)
return en, &count, nil
case *v1alpha1.PolicyFilter:
en := make([]Entity, 0)
policies := v1alpha1.GetMeshModelPolicy(rm.db, *filter)
policies, count := v1alpha1.GetMeshModelPolicy(rm.db, *filter)
for _, pol := range policies {
en = append(en, pol)
}
return en, nil, nil
return en, &count
default:
return nil, nil, nil
}
Expand Down