From 51b968089dd28bcb8faf886efb182533f8c1d4f3 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Wed, 17 Jul 2024 19:41:07 +0530 Subject: [PATCH 1/9] update error for ErrInvalidSchemaVersion w/singoff Signed-off-by: Jougan-0 --- utils/error.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/error.go b/utils/error.go index 8e9a42cf..bc0bc710 100644 --- a/utils/error.go +++ b/utils/error.go @@ -60,9 +60,9 @@ var ( ErrInvalidSchemaVersionCode, errors.Alert, []string{"Invalid schema version"}, - []string{"The `schemaVersion` key in the JSON file is either empty or has an incorrect value."}, - []string{"The JSON file schema is not of type 'relationship' or 'component'.", "The `schemaVersion` key in the JSON should be either `relationships.meshery.io` or `component.meshery.io`."}, - []string{"Verify that the `schemaVersion` key in the JSON has the correct value."}, + []string{"The `schemaVersion` key is either empty or has an incorrect value."}, + []string{"The JSON file schema is not of type 'relationship', 'component', 'model' , 'policy'."}, + []string{"Verify that `schemaVersion` key should be either `relationships.meshery.io`, `component.meshery.io`, `model.meshery.io` or `policy.meshery.io`."}, ) ) From f080ea4861e68484a96173f57a261dbcffb8bb2e Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Wed, 17 Jul 2024 19:42:45 +0530 Subject: [PATCH 2/9] update error for ErrInvalidSchemaVersion w/singoff Signed-off-by: Jougan-0 --- utils/error.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/error.go b/utils/error.go index bc0bc710..3981a282 100644 --- a/utils/error.go +++ b/utils/error.go @@ -61,7 +61,7 @@ var ( errors.Alert, []string{"Invalid schema version"}, []string{"The `schemaVersion` key is either empty or has an incorrect value."}, - []string{"The JSON file schema is not of type 'relationship', 'component', 'model' , 'policy'."}, + []string{"The schema is not of type 'relationship', 'component', 'model' , 'policy'."}, []string{"Verify that `schemaVersion` key should be either `relationships.meshery.io`, `component.meshery.io`, `model.meshery.io` or `policy.meshery.io`."}, ) ) From 7b20d127e3a38b2d048805de2c0b0b2c6b2371ec Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Mon, 29 Jul 2024 19:04:42 +0530 Subject: [PATCH 3/9] add oci support and refractor errorw/signoff Signed-off-by: Jougan-0 --- models/oci/utils.go | 80 +++++++++++++++++++ schemas/configuration/modelImport.json | 65 +++++++++++++++ .../configuration/uiSchemaModelImport.json | 6 ++ schemas/schemaProvider.go | 2 + 4 files changed, 153 insertions(+) create mode 100644 schemas/configuration/modelImport.json create mode 100644 schemas/configuration/uiSchemaModelImport.json diff --git a/models/oci/utils.go b/models/oci/utils.go index 7235f4ab..99cc1002 100644 --- a/models/oci/utils.go +++ b/models/oci/utils.go @@ -1,10 +1,16 @@ package oci import ( + "bytes" + "compress/gzip" + "encoding/json" "fmt" + "io" "os" "path/filepath" + archiveTar "archive/tar" + "github.com/fluxcd/pkg/tar" "github.com/google/go-containerregistry/pkg/crane" gcrv1 "github.com/google/go-containerregistry/pkg/v1" @@ -63,3 +69,77 @@ func UnCompressOCIArtifact(source, destination string) error { return nil } + +// ValidateOCIArtifact validates the OCI artifact tarball using go-containerregistry's validate function +func ValidateOCIArtifact(tarballPath string) error { + img, err := tarball.ImageFromPath(tarballPath, nil) + if err != nil { + return err + } + + return validate.Image(img) +} + +// IsOCIArtifact checks if the tarball is an OCI artifact by looking for manifest.json or index.json +func IsOCIArtifact(data []byte) bool { + reader := bytes.NewReader(data) + var tr *archiveTar.Reader + + if gzr, err := gzip.NewReader(reader); err == nil { + defer gzr.Close() + tr = archiveTar.NewReader(gzr) + } else { + reader.Seek(0, io.SeekStart) + tr = archiveTar.NewReader(reader) + } + + for { + header, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return false + } + + if header.Name == "manifest.json" || header.Name == "index.json" { + return true + } + } + + return false +} + +func ExtractAndValidateManifest(data []byte) error { + reader := bytes.NewReader(data) + var tr *archiveTar.Reader + + if gzr, err := gzip.NewReader(reader); err == nil { + defer gzr.Close() + tr = archiveTar.NewReader(gzr) + } else { + reader.Seek(0, io.SeekStart) + tr = archiveTar.NewReader(reader) + } + + for { + header, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return err + } + + if header.Name == "manifest.json" { + var manifest []map[string]interface{} + if err := json.NewDecoder(tr).Decode(&manifest); err != nil { + return fmt.Errorf("failed to decode manifest.json: %w", err) + } + fmt.Println("manifest.json is valid:", manifest) + return nil + } + } + + return fmt.Errorf("manifest.json not found in tarball") +} diff --git a/schemas/configuration/modelImport.json b/schemas/configuration/modelImport.json new file mode 100644 index 00000000..e3693d40 --- /dev/null +++ b/schemas/configuration/modelImport.json @@ -0,0 +1,65 @@ +{ + "type": "object", + "properties": { + "uploadType": { + "title": "Upload method", + "enum": [ + "File Upload", + "URL Import" + ], + "default": "Select the Upload Method", + "x-rjsf-grid-area": "12", + "description": "Choose the method you prefer to upload your model file. Select 'File Upload' if you have the file on your local system or 'URL Import' if you have the file hosted online." + } + }, + "allOf": [ + { + "if": { + "properties": { + "uploadType": { + "const": "File Upload" + } + } + }, + "then": { + "properties": { + "file": { + "type": "string", + "format": "file", + "description": "Browse the filter file from your file system", + "x-rjsf-grid-area": "12" + } + }, + "required": [ + "file" + ] + } + }, + { + "if": { + "properties": { + "uploadType": { + "const": "URL Import" + } + } + }, + "then": { + "properties": { + "url": { + "type": "string", + "format": "uri", + "title": "URL", + "description": "Provide the URL of the design file you want to import. This should be a direct URL to the file, for example: https://raw.github.com/your-design-file.yaml", + "x-rjsf-grid-area": "12" + } + }, + "required": [ + "url" + ] + } + } + ], + "required": [ + "uploadType" + ] +} diff --git a/schemas/configuration/uiSchemaModelImport.json b/schemas/configuration/uiSchemaModelImport.json new file mode 100644 index 00000000..038796fd --- /dev/null +++ b/schemas/configuration/uiSchemaModelImport.json @@ -0,0 +1,6 @@ +{ + "uploadType": { + "ui:widget": "radio" + }, + "ui:order" : [ "uploadType", "file", "url"] + } diff --git a/schemas/schemaProvider.go b/schemas/schemaProvider.go index 9cafddef..8e871e68 100644 --- a/schemas/schemaProvider.go +++ b/schemas/schemaProvider.go @@ -13,6 +13,7 @@ func getSchemaMap() map[string]string { "helmRepo": "connections/helmConnection/helmRepoConnection.json", "environment": "configuration/environment.json", "workspace": "configuration/workspace.json", + "model": "configuration/modelImport.json", } } @@ -25,6 +26,7 @@ func getUiSchemaMap() map[string]string { "helmRepo": "connections/helmConnection/uiHelmRepoConnection.json", "environment": "configuration/uiSchemaEnvironment.json", "workspace": "configuration/uiSchemaWorkspace.json", + "model": "configuration/uiSchemaModelImport.json", } } From 884059ba86eafd1b17a058ba4247ba69fcd4ba47 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Wed, 7 Aug 2024 11:12:34 +0530 Subject: [PATCH 4/9] fix linting w/signoff Signed-off-by: Jougan-0 --- models/oci/error.go | 4 ++++ models/oci/utils.go | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/models/oci/error.go b/models/oci/error.go index f3e51c77..307e43c9 100644 --- a/models/oci/error.go +++ b/models/oci/error.go @@ -22,6 +22,7 @@ var ( ErrAddLayerCode = "meshkit-11247" ErrTaggingPackageCode = "meshkit-11248" ErrPushingPackageCode = "meshkit-11249" + ErrSeekFailedCode = "replace_me" ) func ErrAppendingLayer(err error) error { @@ -83,3 +84,6 @@ func ErrTaggingPackage(err error) error { func ErrPushingPackage(err error) error { return errors.New(ErrPushingPackageCode, errors.Alert, []string{"pushing package failed"}, []string{err.Error()}, []string{"failed to push the package"}, []string{"Try using a different tag", "check if package is not malformed"}) } +func ErrSeekFailed(err error) error { + return errors.New(ErrSeekFailedCode, errors.Alert, []string{"Unable to reset the position within the OCI data."}, []string{err.Error()}, []string{"The function attempted to move to the start of the data but failed. This could happen if the data is corrupted or not in the expected format."}, []string{"Ensure the input data is a valid OCI archive and try again. Check if the data is compressed correctly and is not corrupted."}) +} diff --git a/models/oci/utils.go b/models/oci/utils.go index 99cc1002..69fd31c9 100644 --- a/models/oci/utils.go +++ b/models/oci/utils.go @@ -89,7 +89,10 @@ func IsOCIArtifact(data []byte) bool { defer gzr.Close() tr = archiveTar.NewReader(gzr) } else { - reader.Seek(0, io.SeekStart) + _, err := reader.Seek(0, io.SeekStart) + if err != nil { + return false + } tr = archiveTar.NewReader(reader) } @@ -118,7 +121,10 @@ func ExtractAndValidateManifest(data []byte) error { defer gzr.Close() tr = archiveTar.NewReader(gzr) } else { - reader.Seek(0, io.SeekStart) + _, err := reader.Seek(0, io.SeekStart) + if err != nil { + return ErrSeekFailed(err) + } tr = archiveTar.NewReader(reader) } From 091910c2c7e714d87005aa6f68d7f998dffc09ac Mon Sep 17 00:00:00 2001 From: MUzairS15 Date: Wed, 7 Aug 2024 19:01:30 +0530 Subject: [PATCH 5/9] run gofmt Signed-off-by: MUzairS15 --- models/registration/register.go | 49 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/models/registration/register.go b/models/registration/register.go index 6971952e..4960fd5f 100644 --- a/models/registration/register.go +++ b/models/registration/register.go @@ -9,28 +9,28 @@ import ( // packaingUnit is the representation of the atomic unit that can be registered into the capabilities registry type packagingUnit struct { - model v1beta1.Model - components []v1beta1.ComponentDefinition + model v1beta1.Model + components []v1beta1.ComponentDefinition relationships []v1alpha2.RelationshipDefinition - _ []v1beta1.PolicyDefinition + _ []v1beta1.PolicyDefinition } type RegistrationHelper struct { - regManager *meshmodel.RegistryManager - regErrStore RegistrationErrorStore + regManager *meshmodel.RegistryManager + regErrStore RegistrationErrorStore } func NewRegistrationHelper(regm *meshmodel.RegistryManager, regErrStore RegistrationErrorStore) RegistrationHelper { - return RegistrationHelper{ regManager: regm, regErrStore: regErrStore} + return RegistrationHelper{regManager: regm, regErrStore: regErrStore} } /* - Register will accept a RegisterableEntity (dir, tar or oci for now). +Register will accept a RegisterableEntity (dir, tar or oci for now). */ func (rh *RegistrationHelper) Register(entity RegisterableEntity) error { // get the packaging units pu, err := entity.PkgUnit(rh.regErrStore) - if(err != nil){ + if err != nil { // given input is not a valid model, or could not walk the directory return err } @@ -38,30 +38,29 @@ func (rh *RegistrationHelper) Register(entity RegisterableEntity) error { return rh.register(pu) } - /* - 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. +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) error { +func (rh *RegistrationHelper) register(pkg packagingUnit) error { // 1. Register the model model := pkg.model // Dont register anything else if registrant is not there - if(model.Registrant.Hostname == ""){ + if model.Registrant.Hostname == "" { err := ErrMissingRegistrant(model.Name) - rh.regErrStore.InsertEntityRegError(model.Registrant.Hostname, "",entity.Model, model.Name, err) + rh.regErrStore.InsertEntityRegError(model.Registrant.Hostname, "", entity.Model, model.Name, err) return err } _, _, err := rh.regManager.RegisterEntity( - v1beta1.Host{Hostname: model.Registrant.Hostname,}, + v1beta1.Host{Hostname: model.Registrant.Hostname}, &model, - ) + ) // If model cannot be registered, don't register anything else if err != nil { err = ErrRegisterEntity(err, string(model.Type()), model.DisplayName) - rh.regErrStore.InsertEntityRegError(model.Registrant.Hostname, "",entity.Model, model.Name, err) + rh.regErrStore.InsertEntityRegError(model.Registrant.Hostname, "", entity.Model, model.Name, err) return err } @@ -71,13 +70,13 @@ func (rh *RegistrationHelper)register(pkg packagingUnit) error { for _, comp := range pkg.components { comp.Model = model _, _, err := rh.regManager.RegisterEntity( - v1beta1.Host{Hostname: hostname,}, - &comp, + v1beta1.Host{Hostname: hostname}, + &comp, ) - if err != nil { - err = ErrRegisterEntity(err, string(comp.Type()), comp.DisplayName) - rh.regErrStore.InsertEntityRegError(hostname, modelName ,entity.ComponentDefinition, comp.DisplayName, err) - } + if err != nil { + err = ErrRegisterEntity(err, string(comp.Type()), comp.DisplayName) + rh.regErrStore.InsertEntityRegError(hostname, modelName, entity.ComponentDefinition, comp.DisplayName, err) + } } // 3. Register relationships @@ -88,8 +87,8 @@ func (rh *RegistrationHelper)register(pkg packagingUnit) error { }, &rel) if err != nil { err = ErrRegisterEntity(err, string(rel.Type()), rel.Kind) - rh.regErrStore.InsertEntityRegError(hostname, modelName ,entity.RelationshipDefinition, rel.ID.String(), err) + rh.regErrStore.InsertEntityRegError(hostname, modelName, entity.RelationshipDefinition, rel.ID.String(), err) } } - return nil + return nil } From 95ea8a013d15694daf85ce1b4600e41423451c83 Mon Sep 17 00:00:00 2001 From: MUzairS15 Date: Wed, 7 Aug 2024 19:24:53 +0530 Subject: [PATCH 6/9] write svg to file system Signed-off-by: MUzairS15 --- .../registry/v1beta1/model_filter.go | 4 - models/registration/register.go | 7 +- models/registration/svg_helper.go | 134 ++++++++++++++++++ 3 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 models/registration/svg_helper.go diff --git a/models/meshmodel/registry/v1beta1/model_filter.go b/models/meshmodel/registry/v1beta1/model_filter.go index d8969671..d4364c89 100644 --- a/models/meshmodel/registry/v1beta1/model_filter.go +++ b/models/meshmodel/registry/v1beta1/model_filter.go @@ -136,10 +136,6 @@ func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, e finder = finder.Where("model_dbs.status = ?", status) - if mf.Status != "" { - finder = finder.Where("model_dbs.status = ?", mf.Status) - } - includeComponents = mf.Components includeRelationships = mf.Relationships diff --git a/models/registration/register.go b/models/registration/register.go index 4960fd5f..3c8de734 100644 --- a/models/registration/register.go +++ b/models/registration/register.go @@ -18,10 +18,11 @@ type packagingUnit struct { type RegistrationHelper struct { regManager *meshmodel.RegistryManager regErrStore RegistrationErrorStore + svgBaseDir string } -func NewRegistrationHelper(regm *meshmodel.RegistryManager, regErrStore RegistrationErrorStore) RegistrationHelper { - return RegistrationHelper{regManager: regm, regErrStore: regErrStore} +func NewRegistrationHelper(svgBaseDir string, regm *meshmodel.RegistryManager, regErrStore RegistrationErrorStore) RegistrationHelper { + return RegistrationHelper{svgBaseDir: svgBaseDir, regManager: regm, regErrStore: regErrStore} } /* @@ -52,6 +53,7 @@ func (rh *RegistrationHelper) register(pkg packagingUnit) error { rh.regErrStore.InsertEntityRegError(model.Registrant.Hostname, "", entity.Model, model.Name, err) return err } + writeAndReplaceSVGWithFileSystemPath(model.Metadata, rh.svgBaseDir, model.Name, model.Name) //Write SVG for models _, _, err := rh.regManager.RegisterEntity( v1beta1.Host{Hostname: model.Registrant.Hostname}, &model, @@ -69,6 +71,7 @@ func (rh *RegistrationHelper) register(pkg packagingUnit) error { // 2. Register components for _, comp := range pkg.components { comp.Model = model + writeAndReplaceSVGWithFileSystemPath(comp.Metadata, rh.svgBaseDir, comp.Model.Name, comp.Component.Kind) //Write SVG on components _, _, err := rh.regManager.RegisterEntity( v1beta1.Host{Hostname: hostname}, &comp, diff --git a/models/registration/svg_helper.go b/models/registration/svg_helper.go new file mode 100644 index 00000000..8bcb75ad --- /dev/null +++ b/models/registration/svg_helper.go @@ -0,0 +1,134 @@ +package registration + +import ( + "crypto/md5" + "encoding/hex" + "fmt" + "os" + "path/filepath" + "strings" + "sync" +) + +var hashCheckSVG = make(map[string]string) +var mx sync.Mutex +var UISVGPaths = make([]string, 1) + +func writeHashCheckSVG(key string, val string) { + mx.Lock() + hashCheckSVG[key] = val + mx.Unlock() +} + +func writeAndReplaceSVGWithFileSystemPath(metadata map[string]interface{}, baseDir, dirname, filename string) { + filename = strings.ToLower(filename) + successCreatingDirectory := false + defer func() { + if successCreatingDirectory { + UISVGPaths = append(UISVGPaths, filepath.Join(baseDir, dirname)) + } + }() + if metadata["svgColor"] != "" { + path := filepath.Join(baseDir, dirname, "color") + err := os.MkdirAll(path, 0777) + if err != nil { + fmt.Println(err) + return + } + successCreatingDirectory = true + + x, ok := metadata["svgColor"].(string) + if ok { + hash := md5.Sum([]byte(x)) + hashString := hex.EncodeToString(hash[:]) + pathsvg := hashCheckSVG[hashString] + if pathsvg != "" { // the image has already been loaded, point the component to that path + metadata["svgColor"] = pathsvg + goto White + } + f, err := os.Create(filepath.Join(path, filename+"-color.svg")) + if err != nil { + fmt.Println(err) + return + } + _, err = f.WriteString(x) + if err != nil { + fmt.Println(err) + return + } + metadata["svgColor"] = getRelativePathForAPI(baseDir, filepath.Join(dirname, "color", filename+"-color.svg")) //Replace the actual SVG with path to SVG + writeHashCheckSVG(hashString, metadata["svgColor"].(string)) + } + } +White: + if metadata["svgWhite"] != "" { + path := filepath.Join(baseDir, dirname, "white") + err := os.MkdirAll(path, 0777) + if err != nil { + fmt.Println(err) + return + } + successCreatingDirectory = true + + x, ok := metadata["svgWhite"].(string) + if ok { + hash := md5.Sum([]byte(x)) + hashString := hex.EncodeToString(hash[:]) + pathsvg := hashCheckSVG[hashString] + if pathsvg != "" { // the image has already been loaded, point the component to that path + metadata["svgWhite"] = pathsvg + goto Complete + } + f, err := os.Create(filepath.Join(path, filename+"-white.svg")) + if err != nil { + fmt.Println(err) + return + } + _, err = f.WriteString(x) + if err != nil { + fmt.Println(err) + return + } + metadata["svgWhite"] = getRelativePathForAPI(baseDir, filepath.Join(dirname, "white", filename+"-white.svg")) //Replace the actual SVG with path to SVG + writeHashCheckSVG(hashString, metadata["svgWhite"].(string)) + } + } +Complete: + if metadata["svgComplete"] != "" { + path := filepath.Join(baseDir, dirname, "complete") + err := os.MkdirAll(path, 0777) + if err != nil { + fmt.Println(err) + return + } + successCreatingDirectory = true + + x, ok := metadata["svgComplete"].(string) + if ok { + hash := md5.Sum([]byte(x)) + hashString := hex.EncodeToString(hash[:]) + pathsvg := hashCheckSVG[hashString] + if pathsvg != "" { // the image has already been loaded, point the component to that path + metadata["svgComplete"] = pathsvg + return + } + f, err := os.Create(filepath.Join(path, filename+"-complete.svg")) + if err != nil { + fmt.Println(err) + return + } + _, err = f.WriteString(x) + if err != nil { + fmt.Println(err) + return + } + metadata["svgComplete"] = getRelativePathForAPI(baseDir, filepath.Join(dirname, "complete", filename+"-complete.svg")) //Replace the actual SVG with path to SVG + writeHashCheckSVG(hashString, metadata["svgComplete"].(string)) + } + } +} + +func getRelativePathForAPI(baseDir, path string) string { + ui := strings.TrimPrefix(baseDir, "../../") + return filepath.Join(ui, path) +} From e706e484155147af8fe433903ee1cb1fb7bc896d Mon Sep 17 00:00:00 2001 From: MUzairS15 Date: Wed, 7 Aug 2024 19:27:55 +0530 Subject: [PATCH 7/9] remove static status Signed-off-by: MUzairS15 --- models/meshmodel/core/v1beta1/models.go | 1 - 1 file changed, 1 deletion(-) diff --git a/models/meshmodel/core/v1beta1/models.go b/models/meshmodel/core/v1beta1/models.go index e3094f6c..0fc27a27 100644 --- a/models/meshmodel/core/v1beta1/models.go +++ b/models/meshmodel/core/v1beta1/models.go @@ -97,7 +97,6 @@ func (m *Model) Create(db *database.Handler, hostID uuid.UUID) (uuid.UUID, error m.ID = modelID m.CategoryID = id m.RegistrantID = hostID - m.Status = entity.Enabled err = db.Omit(clause.Associations).Create(&m).Error if err != nil { return uuid.UUID{}, err From 86b7fb93b7ba511103646e01c0551de85b72bba1 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Thu, 8 Aug 2024 23:31:33 +0530 Subject: [PATCH 8/9] fix versionmeta and missing schemaversion w/signoff Signed-off-by: Jougan-0 --- .../meshmodel/core/v1alpha2/relationship.go | 6 +-- models/meshmodel/core/v1beta1/component.go | 12 +++--- models/meshmodel/core/v1beta1/models.go | 5 ++- .../registry/v1beta1/model_filter.go | 42 +++++++++++++++---- 4 files changed, 45 insertions(+), 20 deletions(-) diff --git a/models/meshmodel/core/v1alpha2/relationship.go b/models/meshmodel/core/v1alpha2/relationship.go index 1b10bf86..931ef10f 100644 --- a/models/meshmodel/core/v1alpha2/relationship.go +++ b/models/meshmodel/core/v1alpha2/relationship.go @@ -16,9 +16,9 @@ import ( const RelationshipSchemaVersion = "relationships.meshery.io/v1alpha2" type RelationshipDefinition struct { - ID uuid.UUID `json:"id"` - v1beta1.VersionMeta - Kind string `json:"kind,omitempty" yaml:"kind"` + ID uuid.UUID `json:"id"` + v1beta1.VersionMeta `json:",inline" yaml:",inline"` + Kind string `json:"kind,omitempty" yaml:"kind"` // The property has been named RelationshipType instead of Type to avoid collision from Type() function, which enables support for dynamic type. // Though, the column name and the json representation is "type". RelationshipType string `json:"type" yaml:"type" gorm:"type"` diff --git a/models/meshmodel/core/v1beta1/component.go b/models/meshmodel/core/v1beta1/component.go index fbb56b7e..0722ec41 100644 --- a/models/meshmodel/core/v1beta1/component.go +++ b/models/meshmodel/core/v1beta1/component.go @@ -13,8 +13,8 @@ import ( ) type VersionMeta struct { - SchemaVersion string `json:"schemaVersion,omitempty" yaml:"schemaVersion"` - Version string `json:"version,omitempty" yaml:"version"` + SchemaVersion string `json:"schemaVersion,omitempty" yaml:"schemaVersion" gorm:"column:schema_version"` + Version string `json:"version,omitempty" yaml:"version" gorm:"column:version"` } type TypeMeta struct { @@ -40,10 +40,10 @@ type ComponentEntity struct { // swagger:response ComponentDefinition type ComponentDefinition struct { - ID uuid.UUID `json:"id"` - VersionMeta - DisplayName string `json:"displayName" gorm:"displayName"` - Description string `json:"description" gorm:"description"` + ID uuid.UUID `json:"id"` + VersionMeta `json:",inline" yaml:",inline"` + DisplayName string `json:"displayName" gorm:"column:display_name"` + Description string `json:"description" gorm:"column:description"` Format ComponentFormat `json:"format" yaml:"format"` ModelID uuid.UUID `json:"-" gorm:"index:idx_component_definition_dbs_model_id,column:model_id"` Model Model `json:"model" gorm:"foreignKey:ModelID;references:ID"` diff --git a/models/meshmodel/core/v1beta1/models.go b/models/meshmodel/core/v1beta1/models.go index 0fc27a27..b56ee887 100644 --- a/models/meshmodel/core/v1beta1/models.go +++ b/models/meshmodel/core/v1beta1/models.go @@ -24,8 +24,9 @@ type ModelEntity struct { // swagger:response Model type Model struct { - ID uuid.UUID `json:"id"` - VersionMeta + ID uuid.UUID `json:"id"` + VersionMeta `yaml:",inline"` + Name string `json:"name" gorm:"modelName"` DisplayName string `json:"displayName"` Description string `json:"description" gorm:"description"` diff --git a/models/meshmodel/registry/v1beta1/model_filter.go b/models/meshmodel/registry/v1beta1/model_filter.go index d4364c89..d5d3cce2 100644 --- a/models/meshmodel/registry/v1beta1/model_filter.go +++ b/models/meshmodel/registry/v1beta1/model_filter.go @@ -10,7 +10,7 @@ import ( ) type ModelFilter struct { - Id string + 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. @@ -49,18 +49,42 @@ func countUniqueModels(models []v1beta1.Model) int { } func (mf *ModelFilter) GetById(db *database.Handler) (entity.Entity, error) { - m := &v1beta1.Model{} - err := db.First(m, "id = ?", mf.Id).Error + m := &v1beta1.Model{} + // Retrieve the model by ID + err := db.First(m, "id = ?", mf.Id).Error if err != nil { return nil, registry.ErrGetById(err, mf.Id) } - return m, err -} + // Include components if requested + if mf.Components { + var components []v1beta1.ComponentDefinition + componentFinder := db.Model(&v1beta1.ComponentDefinition{}). + Select("component_definition_dbs.id, component_definition_dbs.component, component_definition_dbs.display_name, component_definition_dbs.metadata, component_definition_dbs.schema_version, component_definition_dbs.version"). + Where("component_definition_dbs.model_id = ?", m.ID) + if err := componentFinder.Scan(&components).Error; err != nil { + return nil, err + } + m.Components = components + } -func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, error) { + // Include relationships if requested + if mf.Relationships { + var relationships []v1alpha2.RelationshipDefinition + relationshipFinder := db.Model(&v1alpha2.RelationshipDefinition{}). + Select("relationship_definition_dbs.*"). + Where("relationship_definition_dbs.model_id = ?", m.ID) + if err := relationshipFinder.Scan(&relationships).Error; err != nil { + return nil, err + } + m.Relationships = relationships + } + + return m, nil +} +func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, error) { var modelWithCategories []v1beta1.Model finder := db.Model(&v1beta1.Model{}).Preload("Category").Preload("Registrant"). @@ -129,8 +153,8 @@ func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, e } status := "enabled" - - if mf.Status != "" { + + if mf.Status != "" { status = mf.Status } @@ -153,7 +177,7 @@ func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, e if includeComponents { var components []v1beta1.ComponentDefinition finder := db.Model(&v1beta1.ComponentDefinition{}). - Select("component_definition_dbs.id, component_definition_dbs.component, component_definition_dbs.display_name, component_definition_dbs.metadata"). + Select("component_definition_dbs.id, component_definition_dbs.component, component_definition_dbs.display_name, component_definition_dbs.metadata, component_definition_dbs.schema_version, component_definition_dbs.version"). Where("component_definition_dbs.model_id = ?", _modelDB.ID) if err := finder.Scan(&components).Error; err != nil { return nil, 0, 0, err From 81f1bd9fc3873ce35bb61ecb2c74b505108740df Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Thu, 8 Aug 2024 23:45:18 +0530 Subject: [PATCH 9/9] meshkit errors w/signoff Signed-off-by: Jougan-0 --- models/oci/error.go | 24 ++++++++++++++++++++++-- models/oci/oci.go | 2 +- models/oci/utils.go | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/models/oci/error.go b/models/oci/error.go index 307e43c9..641e49f0 100644 --- a/models/oci/error.go +++ b/models/oci/error.go @@ -23,12 +23,23 @@ var ( ErrTaggingPackageCode = "meshkit-11248" ErrPushingPackageCode = "meshkit-11249" ErrSeekFailedCode = "replace_me" + ErrCreateLayerCode = "replace_me" + ErrSavingImageCode = "replace_me" ) func ErrAppendingLayer(err error) error { return errors.New(ErrAppendingLayerCode, errors.Alert, []string{"appending content to artifact failed"}, []string{err.Error()}, []string{"layer is not compatible with the base image"}, []string{"Try using a different base image", "use a different media type for the layer"}) } - +func ErrSavingImage(err error) error { + return errors.New( + ErrSavingImageCode, + errors.Alert, + []string{"Failed to save image"}, + []string{"An error occurred while saving the image."}, + []string{"Possible issues with file system, insufficient disk space, , other IO errors."}, + []string{"Check the file system permissions and available disk space.", "Ensure the file path is correct and accessible.", "Check for any underlying IO errors."}, + ) +} func ErrReadingFile(err error) error { return errors.New(ErrReadingFileCode, errors.Alert, []string{"reading file failed"}, []string{err.Error()}, []string{"failed to read the file", "Insufficient permissions"}, []string{"Try using a different file", "check if appropriate read permissions are given to the file"}) } @@ -44,7 +55,16 @@ func ErrGettingLayer(err error) error { func ErrCompressingLayer(err error) error { return errors.New(ErrCompressingLayerCode, errors.Alert, []string{"compressing layer failed"}, []string{err.Error()}, []string{"failed to compress the layer"}, []string{"Try using a different layer", "check if layers are compatible with the base image"}) } - +func ErrCreateLayer(err error) error { + return errors.New( + ErrCreateLayerCode, + errors.Alert, + []string{"Failed to create layer"}, + []string{"An error occurred while creating the layer for the image."}, + []string{"Possible issues with file system, incorrect layer type, or other IO errors."}, + []string{"Check the file system permissions and paths.", "Ensure the layer type is correct.", "Check for any underlying IO errors."}, + ) +} func ErrUnTaringLayer(err error) error { return errors.New(ErrUnTaringLayerCode, errors.Alert, []string{"untaring layer failed"}, []string{err.Error()}, []string{"failed to untar the layer"}, []string{"Try using a different layer", "check if image is not malformed"}) } diff --git a/models/oci/oci.go b/models/oci/oci.go index 42e8f525..cde3fec4 100644 --- a/models/oci/oci.go +++ b/models/oci/oci.go @@ -64,7 +64,7 @@ func BuildImage(sourcePath string, opts ...BuildOption) (gcrv1.Image, error) { layer, err := createLayer(sourcePath, o.layerType, o.layerOpts) if err != nil { - return nil, err + return nil, ErrCreateLayer(err) } if o.meta.Created == "" { diff --git a/models/oci/utils.go b/models/oci/utils.go index 69fd31c9..796324bd 100644 --- a/models/oci/utils.go +++ b/models/oci/utils.go @@ -34,7 +34,7 @@ func SaveOCIArtifact(img gcrv1.Image, artifactPath, name string) error { repoWithTag := fmt.Sprintf("%s:%s", name, "latest") // TODO: Add support to make this dynamic from user input err := crane.Save(img, repoWithTag, artifactPath) if err != nil { - return err + return ErrSavingImage(err) } return nil