diff --git a/models/meshmodel/entity/types.go b/models/meshmodel/entity/types.go index 8ab09c76..b7d0a96d 100644 --- a/models/meshmodel/entity/types.go +++ b/models/meshmodel/entity/types.go @@ -19,6 +19,7 @@ const ( type Filter interface { Create(map[string]interface{}) Get(db *database.Handler) (entities []Entity, count int64, unique int, err error) + GetById(db *database.Handler) (entity Entity, err error) } type Entity interface { diff --git a/models/meshmodel/registry/error.go b/models/meshmodel/registry/error.go index ed94ba80..2566ec58 100644 --- a/models/meshmodel/registry/error.go +++ b/models/meshmodel/registry/error.go @@ -14,8 +14,21 @@ var ( ErrRegisteringEntityCode = "replace_me" ErrUnknownHostInMapCode = "replace_me" ErrCreatingUserDataDirectoryCode = "replace_me" + ErrGetByIdCode = "replace_me" ) +func ErrGetById(err error, id string) error { + return errors.New( + ErrUnknownHostCode, + errors.Alert, + []string{"Failed to get the entity with the given ID: " + id}, + []string{err.Error()}, + []string{"Entity with the given ID may not be present in the registry", "Registry might be inaccessible at the moment"}, + []string{"Check if your ID is correct" , "If the registry is inaccesible, please try again after some time"}, + ) + +} + func ErrUnknownHost(err error) error { return errors.New(ErrUnknownHostCode, errors.Alert, []string{"host is not supported"}, []string{err.Error()}, []string{"The component's host is not supported by the version of server you are running"}, []string{"Try upgrading to latest available version"}) } diff --git a/models/meshmodel/registry/registry.go b/models/meshmodel/registry/registry.go index 6e193bad..fbd0558a 100644 --- a/models/meshmodel/registry/registry.go +++ b/models/meshmodel/registry/registry.go @@ -193,6 +193,10 @@ func (rm *RegistryManager) GetEntities(f entity.Filter) ([]entity.Entity, int64, return f.Get(rm.db) } +func (rm *RegistryManager) GetEntityById (f entity.Filter) (entity.Entity, error) { + return f.GetById(rm.db) +} + func HostnameToPascalCase(input string) string { parts := strings.Split(input, ".") caser := cases.Title(language.English) diff --git a/models/meshmodel/registry/v1alpha2/relationship_filter.go b/models/meshmodel/registry/v1alpha2/relationship_filter.go index e07b63b7..64f148fa 100644 --- a/models/meshmodel/registry/v1alpha2/relationship_filter.go +++ b/models/meshmodel/registry/v1alpha2/relationship_filter.go @@ -4,6 +4,7 @@ import ( "github.com/layer5io/meshkit/database" "github.com/layer5io/meshkit/models/meshmodel/core/v1alpha2" "github.com/layer5io/meshkit/models/meshmodel/entity" + "github.com/layer5io/meshkit/models/meshmodel/registry" "gorm.io/gorm/clause" ) @@ -11,6 +12,7 @@ import ( // In the future, we will add support to query using `selectors` (using CUE) // TODO: Add support for Model type RelationshipFilter struct { + Id string Kind string Greedy bool //when set to true - instead of an exact match, kind will be prefix matched SubType string @@ -30,6 +32,16 @@ func (rf *RelationshipFilter) Create(m map[string]interface{}) { } rf.Kind = m["kind"].(string) } + +func (rf *RelationshipFilter) GetById(db *database.Handler) (entity.Entity, error) { + r := &v1alpha2.RelationshipDefinition{} + err := db.First(r, "id = ?", rf.Id).Error + if err != nil { + return nil, registry.ErrGetById(err, rf.Id) + } + return r, err +} + func (relationshipFilter *RelationshipFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, error) { var relationshipDefinitionsWithModel []v1alpha2.RelationshipDefinition diff --git a/models/meshmodel/registry/v1beta1/category_filter.go b/models/meshmodel/registry/v1beta1/category_filter.go index 07ff177c..b992e8d1 100644 --- a/models/meshmodel/registry/v1beta1/category_filter.go +++ b/models/meshmodel/registry/v1beta1/category_filter.go @@ -4,10 +4,12 @@ import ( "github.com/layer5io/meshkit/database" "github.com/layer5io/meshkit/models/meshmodel/core/v1beta1" "github.com/layer5io/meshkit/models/meshmodel/entity" + "github.com/layer5io/meshkit/models/meshmodel/registry" "gorm.io/gorm/clause" ) type CategoryFilter struct { + Id string Name string OrderOn string Greedy bool @@ -24,6 +26,15 @@ func (cf *CategoryFilter) Create(m map[string]interface{}) { cf.Name = m["name"].(string) } +func (cf *CategoryFilter) GetById(db *database.Handler) (entity.Entity, error) { + c := &v1beta1.Category{} + err := db.First(c, "id = ?", cf.Id).Error + if err != nil { + return nil, registry.ErrGetById(err, cf.Id) + } + return c, err +} + func (cf *CategoryFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, error) { var catdb []v1beta1.Category var cat []entity.Entity diff --git a/models/meshmodel/registry/v1beta1/component_filter.go b/models/meshmodel/registry/v1beta1/component_filter.go index b9b401e8..72f0f9c5 100644 --- a/models/meshmodel/registry/v1beta1/component_filter.go +++ b/models/meshmodel/registry/v1beta1/component_filter.go @@ -4,10 +4,12 @@ import ( "github.com/layer5io/meshkit/database" "github.com/layer5io/meshkit/models/meshmodel/core/v1beta1" "github.com/layer5io/meshkit/models/meshmodel/entity" + "github.com/layer5io/meshkit/models/meshmodel/registry" "gorm.io/gorm/clause" ) type ComponentFilter struct { + Id string Name string APIVersion string Greedy bool //when set to true - instead of an exact match, name will be matched as a substring @@ -30,6 +32,15 @@ type componentDefinitionWithModel struct { HostsDB v1beta1.Host `gorm:"embedded"` } +func (cf *ComponentFilter) GetById(db *database.Handler) (entity.Entity, error) { + c := &v1beta1.ComponentDefinition{} + err := db.First(c, "id = ?", cf.Id).Error + if err != nil { + return nil, registry.ErrGetById(err, cf.Id) + } + return c, err +} + // Create the filter from map[string]interface{} func (cf *ComponentFilter) Create(m map[string]interface{}) { if m == nil { diff --git a/models/meshmodel/registry/v1beta1/model_filter.go b/models/meshmodel/registry/v1beta1/model_filter.go index e8bf85d2..440ecb3e 100644 --- a/models/meshmodel/registry/v1beta1/model_filter.go +++ b/models/meshmodel/registry/v1beta1/model_filter.go @@ -5,10 +5,12 @@ import ( "github.com/layer5io/meshkit/models/meshmodel/core/v1alpha2" "github.com/layer5io/meshkit/models/meshmodel/core/v1beta1" "github.com/layer5io/meshkit/models/meshmodel/entity" + "github.com/layer5io/meshkit/models/meshmodel/registry" "gorm.io/gorm/clause" ) type ModelFilter struct { + Id string Name string Registrant string //name of the registrant for a given model DisplayName string //If Name is already passed, avoid passing Display name unless greedy=true, else the filter will translate to an AND returning only the models where name and display name match exactly. Ignore, if this behavior is expected. @@ -46,6 +48,17 @@ func countUniqueModels(models []v1beta1.Model) int { return len(set) } +func (mf *ModelFilter) GetById(db *database.Handler) (entity.Entity, error) { + m := &v1beta1.Model{} + err := db.First(m, "id = ?", mf.Id).Error + + if err != nil { + return nil, registry.ErrGetById(err, mf.Id) + } + return m, err +} + + func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, error) { var modelWithCategories []v1beta1.Model diff --git a/models/meshmodel/registry/v1beta1/policy_filter.go b/models/meshmodel/registry/v1beta1/policy_filter.go index c481e84f..7de9ce07 100644 --- a/models/meshmodel/registry/v1beta1/policy_filter.go +++ b/models/meshmodel/registry/v1beta1/policy_filter.go @@ -4,9 +4,11 @@ import ( "github.com/layer5io/meshkit/database" "github.com/layer5io/meshkit/models/meshmodel/core/v1beta1" "github.com/layer5io/meshkit/models/meshmodel/entity" + "github.com/layer5io/meshkit/models/meshmodel/registry" ) type PolicyFilter struct { + Id string Kind string Greedy bool SubType string @@ -23,6 +25,15 @@ func (pf *PolicyFilter) Create(m map[string]interface{}) { } } +func (pf *PolicyFilter) GetById(db *database.Handler) (entity.Entity, error) { + p := &v1beta1.PolicyDefinition{} + err := db.First(p, "id = ?", pf.Id).Error + if err != nil { + return nil, registry.ErrGetById(err, pf.Id) + } + return p, err +} + func (pf *PolicyFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, error) { pl := []entity.Entity{} var policyDefinitionWithModel []v1beta1.PolicyDefinition