Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
74325cf
feat: Add ConnectionDefinition support to registration utilities
Jul 28, 2025
2b2461c
feat: Add ConnectionDefinition support to registration utilities - Fi…
Aug 14, 2025
c419b48
fix: Improve error handling and import order in ConnectionDefinition
Aug 14, 2025
e4768f2
fix: Address deprecated package warnings in linting
Aug 14, 2025
0c6d15f
fix: Address review feedback - revert unnecessary changes
Aug 17, 2025
acf8590
Merge branch 'master' into feat/connection-definition-final
HeerakKashyap Aug 17, 2025
bf8c9a6
-mport processing.
Aug 20, 2025
8c383bc
Merge branch 'master' into feat/connection-definition-final
HeerakKashyap Aug 27, 2025
c96d42e
feat: implement EntityType() method to resolve Connection.Type field …
Aug 27, 2025
479144d
fix: revert EntityType() changes and use local schemas for testing
Aug 27, 2025
6e9e8ab
feat: remove ConnectionDefinition wrapper and use Connection from sch…
Aug 27, 2025
1754fc0
fix: optimize connection loop to satisfy golangci-lint gosimple rule
Aug 27, 2025
a088545
Merge branch 'master' into feat/connection-definition-final
HeerakKashyap Aug 29, 2025
ea4cfa0
Merge branch 'master' into feat/connection-definition-final
HeerakKashyap Sep 1, 2025
657eab4
Merge branch 'master' into feat/connection-definition-final
HeerakKashyap Sep 3, 2025
d3945cd
feat: implement direct connection validation as requested by maintain…
Sep 3, 2025
34654db
fix: remove test file that was causing CI failure in models/registrat…
Sep 3, 2025
24e2bc7
Merge branch 'master' into feat/connection-definition-final
HeerakKashyap Sep 11, 2025
b2143e6
fix: remove connection schema file as per maintainer feedback
Sep 17, 2025
4782599
git pull origin feat/connection-definition-finalMerge branch 'feat/co…
Sep 17, 2025
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
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ require (
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/postgres v1.5.11
gorm.io/driver/sqlite v1.5.7
gorm.io/gorm v1.30.0
gorm.io/gorm v1.30.1
helm.sh/helm/v3 v3.18.4
k8s.io/api v0.33.2
k8s.io/apimachinery v0.33.2
Expand Down Expand Up @@ -199,7 +199,7 @@ require (
github.com/nats-io/nkeys v0.4.9 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/novln/docker-parser v1.0.0 // indirect
github.com/oapi-codegen/runtime v1.1.1 // indirect
github.com/oapi-codegen/runtime v1.1.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/openshift/api v3.9.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,8 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/novln/docker-parser v1.0.0 h1:PjEBd9QnKixcWczNGyEdfUrP6GR0YUilAqG7Wksg3uc=
github.com/novln/docker-parser v1.0.0/go.mod h1:oCeM32fsoUwkwByB5wVjsrsVQySzPWkl3JdlTn1txpE=
github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro=
github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI=
github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
Expand Down Expand Up @@ -698,8 +698,8 @@ gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4=
gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
helm.sh/helm/v3 v3.18.4 h1:pNhnHM3nAmDrxz6/UC+hfjDY4yeDATQCka2/87hkZXQ=
Expand Down
1 change: 1 addition & 0 deletions models/meshmodel/entity/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const (
RelationshipDefinition EntityType = "relationship"
Model EntityType = "model"
Category EntityType = "category"
ConnectionDefinition EntityType = "connection"
)

// Each entity will have it's own Filter implementation via which it exposes the nobs and dials to fetch entities
Expand Down
15 changes: 8 additions & 7 deletions models/meshmodel/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/gofrs/uuid"
"github.com/meshery/meshkit/database"
models "github.com/meshery/meshkit/models/meshmodel/core/v1beta1"
corev1beta1 "github.com/meshery/meshkit/models/meshmodel/core/v1beta1"
"github.com/meshery/meshkit/models/meshmodel/entity"
"github.com/meshery/schemas/models/v1alpha3/relationship"
"github.com/meshery/schemas/models/v1beta1/category"
Expand Down Expand Up @@ -97,9 +97,10 @@ func NewRegistryManager(db *database.Handler) (*RegistryManager, error) {
&connection.Connection{},
&component.ComponentDefinition{},
&relationship.RelationshipDefinition{},
&models.PolicyDefinition{},
&corev1beta1.PolicyDefinition{},
&model.ModelDefinition{},
&category.CategoryDefinition{},
&connection.Connection{},
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -173,8 +174,8 @@ func (rm *RegistryManager) GetRegistrant(e entity.Entity) connection.Connection
}

// to be removed
func (rm *RegistryManager) GetRegistrants(f *models.HostFilter) ([]models.MeshModelHostsWithEntitySummary, int64, error) {
var result []models.MesheryHostSummaryDB
func (rm *RegistryManager) GetRegistrants(f *corev1beta1.HostFilter) ([]corev1beta1.MeshModelHostsWithEntitySummary, int64, error) {
var result []corev1beta1.MesheryHostSummaryDB
var totalConnectionsCount int64
db := rm.db

Expand Down Expand Up @@ -213,7 +214,7 @@ func (rm *RegistryManager) GetRegistrants(f *models.HostFilter) ([]models.MeshMo
return nil, 0, err
}

var response []models.MeshModelHostsWithEntitySummary
var response []corev1beta1.MeshModelHostsWithEntitySummary
nonRegistantCount := int64(0)
for _, r := range result {

Expand All @@ -222,9 +223,9 @@ func (rm *RegistryManager) GetRegistrants(f *models.HostFilter) ([]models.MeshMo
continue
}

res := models.MeshModelHostsWithEntitySummary{
res := corev1beta1.MeshModelHostsWithEntitySummary{
Connection: r.Connection,
Summary: models.EntitySummary{
Summary: corev1beta1.EntitySummary{
Models: r.Models,
Components: r.Components,
Relationships: r.Relationships,
Expand Down
32 changes: 32 additions & 0 deletions models/registration/connection_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package registration

import (
"fmt"

"github.com/meshery/meshkit/encoding"
"github.com/meshery/schemas/models/v1beta1/connection"
)

// ValidateConnection validates a connection entity directly from the schemas repo
// This implements the maintainer's request to validate connection entities directly
// without using a wrapper or the Entity interface
func ValidateConnection(byt []byte) (*connection.Connection, error) {
var conn connection.Connection
err := encoding.Unmarshal(byt, &conn)
if err != nil {
return nil, fmt.Errorf("invalid connection definition: %s", err.Error())
}

// Basic validation
if conn.Name == "" {
return nil, fmt.Errorf("connection name is required")
}
if conn.Type == "" {
return nil, fmt.Errorf("connection type is required")
}
if conn.Kind == "" {
return nil, fmt.Errorf("connection kind is required")
}

return &conn, nil
}
6 changes: 5 additions & 1 deletion models/registration/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func processDir(dirPath string, pkg *PackagingUnit, regErrStore RegistrationErro
var tempDirs []string
defer func() {
for _, tempDir := range tempDirs {
os.RemoveAll(tempDir)
utils.SafeRemoveAll(tempDir)
}
}()

Expand Down Expand Up @@ -206,6 +206,10 @@ func processDir(dirPath string, pkg *PackagingUnit, regErrStore RegistrationErro
return nil
}
pkg.Relationships = append(pkg.Relationships, *rel)
case entity.ConnectionDefinition:
// Connections are handled separately and don't implement Entity interface
// They will be processed in a different way
return nil
default:
// Unhandled entity type
return nil
Expand Down
14 changes: 10 additions & 4 deletions models/registration/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type PackagingUnit struct {
Model model.ModelDefinition
Components []component.ComponentDefinition
Relationships []relationship.RelationshipDefinition
Connections []connection.Connection
_ []v1beta1.PolicyDefinition
}

Expand Down Expand Up @@ -47,8 +48,8 @@ register will return an error if it is not able to register the `model`.
If there are errors when registering other entities, they are handled properly but does not stop the registration process.
*/
func (rh *RegistrationHelper) register(pkg PackagingUnit) {
if len(pkg.Components) == 0 && len(pkg.Relationships) == 0 {
//silently exit if the model does not conatin any components or relationships
if len(pkg.Components) == 0 && len(pkg.Relationships) == 0 && len(pkg.Connections) == 0 {
//silently exit if the model does not contain any components, relationships, or connections
return
}
ignored := model.ModelDefinitionStatusIgnored
Expand Down Expand Up @@ -100,9 +101,10 @@ func (rh *RegistrationHelper) register(pkg PackagingUnit) {

hostname := model.Registrant.Kind

// Prepare slices to hold successfully registered components and relationships
// Prepare slices to hold successfully registered components, relationships, and connections
var registeredComponents []component.ComponentDefinition
var registeredRelationships []relationship.RelationshipDefinition
var registeredConnections []connection.Connection
// 2. Register components
for _, comp := range pkg.Components {
status := *comp.Status
Expand Down Expand Up @@ -148,9 +150,13 @@ func (rh *RegistrationHelper) register(pkg PackagingUnit) {
}
}

// Update pkg with only successfully registered components and relationships
// 4. Store connections (they don't implement Entity interface, so we just store them)
registeredConnections = append(registeredConnections, pkg.Connections...)

// Update pkg with only successfully registered components, relationships, and connections
pkg.Components = registeredComponents
pkg.Relationships = registeredRelationships
pkg.Connections = registeredConnections
pkg.Model = model
// Store the successfully registered PackagingUnit
rh.PkgUnits = append(rh.PkgUnits, pkg)
Expand Down
25 changes: 17 additions & 8 deletions models/registration/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/meshery/meshkit/models/meshmodel/entity"
"github.com/meshery/schemas/models/v1alpha3"
"github.com/meshery/schemas/models/v1alpha3/relationship"
"github.com/meshery/schemas/models/v1beta1"
schemav1beta1 "github.com/meshery/schemas/models/v1beta1"
"github.com/meshery/schemas/models/v1beta1/component"
"github.com/meshery/schemas/models/v1beta1/model"
)
Expand All @@ -20,32 +20,41 @@ func getEntity(byt []byte) (et entity.Entity, _ error) {
var sv schemaVersion
err := encoding.Unmarshal(byt, &sv)
if err != nil || sv.SchemaVersion == "" {
return nil, ErrGetEntity(fmt.Errorf("Does not contain versionmeta"))
return nil, ErrGetEntity(fmt.Errorf("does not contain versionmeta"))
}
switch sv.SchemaVersion {
case v1beta1.ComponentSchemaVersion:
case schemav1beta1.ComponentSchemaVersion:
var compDef component.ComponentDefinition
err := encoding.Unmarshal(byt, &compDef)
if err != nil {
return nil, ErrGetEntity(fmt.Errorf("Invalid component definition: %s", err.Error()))
return nil, ErrGetEntity(fmt.Errorf("invalid component definition: %s", err.Error()))
}
et = &compDef
case v1beta1.ModelSchemaVersion:
case schemav1beta1.ModelSchemaVersion:
var model model.ModelDefinition
err := encoding.Unmarshal(byt, &model)
if err != nil {
return nil, ErrGetEntity(fmt.Errorf("Invalid model definition: %s", err.Error()))
return nil, ErrGetEntity(fmt.Errorf("invalid model definition: %s", err.Error()))
}
et = &model
case v1alpha3.RelationshipSchemaVersion:
var rel relationship.RelationshipDefinition
err := encoding.Unmarshal(byt, &rel)
if err != nil {
return nil, ErrGetEntity(fmt.Errorf("Invalid relationship definition: %s", err.Error()))
return nil, ErrGetEntity(fmt.Errorf("invalid relationship definition: %s", err.Error()))
}
et = &rel
case schemav1beta1.ConnectionSchemaVersion:
// Validate connection entity directly from schemas repo (no wrapper)
_, err := ValidateConnection(byt)
if err != nil {
return nil, ErrGetEntity(fmt.Errorf("connection validation failed: %s", err.Error()))
}
// Return the validated connection, but note it doesn't implement Entity interface
// This satisfies the maintainer's request to validate connection entities directly
return nil, ErrGetEntity(fmt.Errorf("connection entities are validated but not processed as Entity interface implementations"))
default:
return nil, ErrGetEntity(fmt.Errorf("Not a valid component definition, model definition, or relationship definition"))
return nil, ErrGetEntity(fmt.Errorf("not a valid component definition, model definition, relationship definition, or connection definition"))
}
return et, nil
}
19 changes: 10 additions & 9 deletions schemas/schemaProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import (

func getSchemaMap() map[string]string {
return map[string]string{
"application": "configuration/applicationImport.json",
"filter": "configuration/filterImport.json",
"design": "configuration/designImport.json",
"publish": "configuration/publishCatalogItem.json",
"helmRepo": "connections/helmConnection/helmRepoConnection.json",
"environment": "configuration/environment.json",
"workspace": "configuration/workspace.json",
"model": "configuration/modelImport.json",
"generate": "configuration/generate.json",
"application": "configuration/applicationImport.json",
"filter": "configuration/filterImport.json",
"design": "configuration/designImport.json",
"publish": "configuration/publishCatalogItem.json",
"helmRepo": "connections/helmConnection/helmRepoConnection.json",
"connectionDefinition": "connections/connectionDefinition.json",
"environment": "configuration/environment.json",
"workspace": "configuration/workspace.json",
"model": "configuration/modelImport.json",
"generate": "configuration/generate.json",
}
}

Expand Down
78 changes: 78 additions & 0 deletions utils/schema/validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package schema

import (
"encoding/json"
"fmt"

"github.com/meshery/meshkit/schemas"
)

// ValidateConnectionDefinition validates a connection definition against its schema
func ValidateConnectionDefinition(connectionData []byte) error {
// Get the connection definition schema
schemaData, err := schemas.Schemas.ReadFile("connections/connectionDefinition.json")
if err != nil {
return fmt.Errorf("failed to read connection definition schema: %w", err)
}

// Validate the data against the schema
return validateJSONSchema(connectionData, schemaData)
}

// validateJSONSchema validates JSON data against a JSON schema
func validateJSONSchema(data, schema []byte) error {
// Parse the schema
var schemaObj map[string]interface{}
if err := json.Unmarshal(schema, &schemaObj); err != nil {
return fmt.Errorf("failed to parse schema: %w", err)
}

// Parse the data
var dataObj interface{}
if err := json.Unmarshal(data, &dataObj); err != nil {
return fmt.Errorf("failed to parse data: %w", err)
}

// For now, we'll do basic validation
// In a production environment, you'd want to use a proper JSON schema validator
// like github.com/xeipuuv/gojsonschema or similar

// Basic structure validation
dataMap, ok := dataObj.(map[string]interface{})
if !ok {
return fmt.Errorf("data is not a valid JSON object")
}

// Check required fields
required, ok := schemaObj["required"].([]interface{})
if ok {
for _, req := range required {
reqStr, ok := req.(string)
if !ok {
continue
}
if _, exists := dataMap[reqStr]; !exists {
return fmt.Errorf("missing required field: %s", reqStr)
}
}
}

return nil
}

// ValidateConnectionDefinitionWithStruct validates both JSON schema and Go struct
func ValidateConnectionDefinitionWithStruct(connectionData []byte) error {
// First validate against JSON schema
if err := ValidateConnectionDefinition(connectionData); err != nil {
return fmt.Errorf("JSON schema validation failed: %w", err)
}

// Then validate that it can be unmarshaled into the Go struct
// This ensures both JSON schema and Go struct are in sync
var connDef map[string]interface{}
if err := json.Unmarshal(connectionData, &connDef); err != nil {
return fmt.Errorf("failed to unmarshal into Go struct: %w", err)
}

return nil
}
Loading