From e05b6ed2811d4502dff14a0da4c75a316d4d4719 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Mon, 16 Sep 2024 14:17:04 +0530 Subject: [PATCH 1/8] update registration logic to support import command w/signoff Signed-off-by: Jougan-0 --- models/registration/dir.go | 179 +++++++++++++++++++++++++------ models/registration/interface.go | 4 +- models/registration/oci.go | 4 +- models/registration/register.go | 66 +++++++----- models/registration/tar.go | 4 +- utils/utils.go | 38 +++++++ 6 files changed, 232 insertions(+), 63 deletions(-) diff --git a/models/registration/dir.go b/models/registration/dir.go index fb7db466..f283f1e6 100644 --- a/models/registration/dir.go +++ b/models/registration/dir.go @@ -7,7 +7,10 @@ import ( "reflect" "github.com/layer5io/meshkit/models/meshmodel/entity" + "github.com/layer5io/meshkit/models/oci" + "github.com/layer5io/meshkit/utils" + "github.com/meshery/schemas/models/v1alpha3/relationship" "github.com/meshery/schemas/models/v1beta1/component" "github.com/meshery/schemas/models/v1beta1/model" @@ -26,69 +29,185 @@ func NewDir(path string) Dir { } /* -PkgUnit parses all the files inside the directory and finds out if they are any valid meshery definitions. Valid meshery definitions are added to the packagingUnit struct. +PkgUnit parses all the files inside the directory and finds out if they are any valid meshery definitions. Valid meshery definitions are added to the PackagingUnit struct. Invalid definitions are stored in the regErrStore with error data. */ -func (d Dir) PkgUnit(regErrStore RegistrationErrorStore) (_ packagingUnit, err error) { - pkg := packagingUnit{} - // check if the given is a directory - _, err = os.ReadDir(d.dirpath) +func (d Dir) PkgUnit(regErrStore RegistrationErrorStore) (_ PackagingUnit, err error) { + pkg := PackagingUnit{} + + // Extract the filename to use as entityName in case of errors + filename := filepath.Base(d.dirpath) + + // Check if the given path is accessible + _, err = os.Stat(d.dirpath) if err != nil { - return pkg, ErrDirPkgUnitParseFail(d.dirpath, fmt.Errorf("Could not read the directory: %e", err)) + regErrStore.InsertEntityRegError("", "", entity.EntityType("unknown"), filename, ErrDirPkgUnitParseFail(d.dirpath, fmt.Errorf("could not access the path: %w", err))) + return pkg, ErrDirPkgUnitParseFail(d.dirpath, fmt.Errorf("could not access the path: %w", err)) + } + + // Process the path (file or directory) + err = processDir(d.dirpath, &pkg, regErrStore) + if err != nil { + modelName := "" + if !reflect.ValueOf(pkg.Model).IsZero() { + modelName = pkg.Model.Name + } + regErrStore.InsertEntityRegError("", modelName, entity.EntityType("unknown"), filename, ErrDirPkgUnitParseFail(d.dirpath, fmt.Errorf("could not process the path: %w", err))) + return pkg, ErrDirPkgUnitParseFail(d.dirpath, fmt.Errorf("could not process the path: %w", err)) } - err = filepath.Walk(d.dirpath, func(path string, f os.FileInfo, err error) error { + + if reflect.ValueOf(pkg.Model).IsZero() { + errMsg := fmt.Errorf("model definition not found in imported package. Model definitions often use the filename `model.json`, but are not required to have this filename. One and exactly one entity containing schema: model.core must be present, otherwise the model package is considered malformed") + regErrStore.InsertEntityRegError("", "", entity.Model, filename, errMsg) + return pkg, errMsg + } + + return pkg, nil +} + +func processDir(dirPath string, pkg *PackagingUnit, regErrStore RegistrationErrorStore) error { + var tempDirs []string + defer func() { + for _, tempDir := range tempDirs { + os.RemoveAll(tempDir) + } + }() + + return filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { if err != nil { - return err + err = utils.ErrFileWalkDir(fmt.Errorf("error accessing path: %w", err), path) + regErrStore.InsertEntityRegError("", "", entity.EntityType("unknown"), filepath.Base(path), err) + regErrStore.AddInvalidDefinition(path, err) + return nil } - if f.IsDir() { + if info.IsDir() { return nil } - byt, _ := os.ReadFile(path) - if byt == nil { + + // Read the file content + data, err := os.ReadFile(path) + if err != nil { + err = oci.ErrReadingFile(err) + regErrStore.InsertEntityRegError("", "", entity.EntityType("unknown"), filepath.Base(path), err) + regErrStore.AddInvalidDefinition(path, err) return nil } - var e entity.Entity - e, err = getEntity(byt) + // Check if the file is an OCI artifact + if oci.IsOCIArtifact(data) { + // Extract the OCI artifact + tempDir, err := oci.CreateTempOCIContentDir() + if err != nil { + regErrStore.InsertEntityRegError("", "", entity.EntityType("unknown"), filepath.Base(path), err) + regErrStore.AddInvalidDefinition(path, err) + return nil + } + tempDirs = append(tempDirs, tempDir) + err = oci.UnCompressOCIArtifact(path, tempDir) + if err != nil { + regErrStore.InsertEntityRegError("", "", entity.EntityType("unknown"), filepath.Base(path), err) + regErrStore.AddInvalidDefinition(path, err) + return nil + } + // Recursively process the extracted directory + if err := processDir(tempDir, pkg, regErrStore); err != nil { + return err + } + return nil + } + + // Check if the file is a zip or tar file + if utils.IsZip(path) || utils.IsTarGz(path) { + tempDir, err := os.MkdirTemp("", "nested-extract-") + if err != nil { + err = utils.ErrCreateDir(fmt.Errorf("error creating temp directory for nested archive extraction: %w", err), tempDir) + regErrStore.InsertEntityRegError("", "", entity.EntityType("unknown"), filepath.Base(path), err) + regErrStore.AddInvalidDefinition(path, err) + return nil + } + tempDirs = append(tempDirs, tempDir) + if err := utils.ExtractFile(path, tempDir); err != nil { + regErrStore.InsertEntityRegError("", "", entity.EntityType("unknown"), filepath.Base(path), err) + regErrStore.AddInvalidDefinition(path, err) + return nil + } + // Recursively process the extracted directory + if err := processDir(tempDir, pkg, regErrStore); err != nil { + return err + } + return nil + } + + content := data + content, err = utils.YAMLToJSON(content) if err != nil { + regErrStore.InsertEntityRegError("", "", entity.EntityType("unknown"), filepath.Base(path), err) + return nil + } + // Determine the entity type + entityType, err := utils.FindEntityType(content) + if err != nil { + regErrStore.InsertEntityRegError("", "", entity.EntityType("unknown"), filepath.Base(path), err) regErrStore.AddInvalidDefinition(path, err) return nil } - // set it to pkgunit + if entityType == "" { + // Not an entity we care about + return nil + } + + // Get the entity + var e entity.Entity + e, err = getEntity(content) + if err != nil { + regErrStore.InsertEntityRegError("", "", entityType, filepath.Base(path), fmt.Errorf("could not get entity: %w", err)) + regErrStore.AddInvalidDefinition(path, fmt.Errorf("could not get entity: %w", err)) + return nil + } + + // Add the entity to the packaging unit switch e.Type() { case entity.Model: - if !reflect.ValueOf(pkg.model).IsZero() { - // currently models inside models are not handled - return nil - } model, err := utils.Cast[*model.ModelDefinition](e) if err != nil { + modelName := "" + if model != nil { + modelName = model.Name + } + regErrStore.InsertEntityRegError("", modelName, entityType, modelName, ErrGetEntity(err)) regErrStore.AddInvalidDefinition(path, ErrGetEntity(err)) + return nil } - pkg.model = *model + pkg.Model = *model case entity.ComponentDefinition: comp, err := utils.Cast[*component.ComponentDefinition](e) if err != nil { + componentName := "" + if comp != nil { + componentName = comp.Component.Kind + } + regErrStore.InsertEntityRegError("", "", entityType, componentName, ErrGetEntity(err)) regErrStore.AddInvalidDefinition(path, ErrGetEntity(err)) + return nil } - pkg.components = append(pkg.components, *comp) + pkg.Components = append(pkg.Components, *comp) case entity.RelationshipDefinition: rel, err := utils.Cast[*relationship.RelationshipDefinition](e) if err != nil { + relationshipName := "" + if rel != nil { + relationshipName = rel.Model.Name + } + regErrStore.InsertEntityRegError("", "", entityType, relationshipName, ErrGetEntity(err)) regErrStore.AddInvalidDefinition(path, ErrGetEntity(err)) + return nil } - pkg.relationships = append(pkg.relationships, *rel) + pkg.Relationships = append(pkg.Relationships, *rel) + default: + // Unhandled entity type + return nil } return nil }) - if err != nil { - return pkg, ErrDirPkgUnitParseFail(d.dirpath, fmt.Errorf("Could not completely walk the file tree: %e", err)) - } - if reflect.ValueOf(pkg.model).IsZero() { - err := fmt.Errorf("Model definition not found in imported package. Model definitions often use the filename `model.json`, but are not required to have this filename. One and exactly one entity containing schema: model.core....... ...... must be present, otherwise the model package is considered malformed..") - regErrStore.AddInvalidDefinition(d.dirpath, err) - return pkg, err - } - return pkg, err } diff --git a/models/registration/interface.go b/models/registration/interface.go index 3f9f580b..65872e20 100644 --- a/models/registration/interface.go +++ b/models/registration/interface.go @@ -12,11 +12,11 @@ type RegistrationErrorStore interface { InsertEntityRegError(hostname string, modelName string, entityType entity.EntityType, entityName string, err error) } -// Anything that can be parsed into a packagingUnit is a RegisterableEntity in Meshery server +// Anything that can be parsed into a PackagingUnit is a RegisterableEntity in Meshery server type RegisterableEntity interface { /* 1. `err` - this is a breaking error, which signifies that the given entity is invalid and cannot be registered 2. Errors encountered while parsing items into meshmodel entites are stored in the RegistrationErrorStore */ - PkgUnit(RegistrationErrorStore) (packagingUnit, error) + PkgUnit(RegistrationErrorStore) (PackagingUnit, error) } diff --git a/models/registration/oci.go b/models/registration/oci.go index 8c8af21b..02355cf8 100644 --- a/models/registration/oci.go +++ b/models/registration/oci.go @@ -8,7 +8,7 @@ type OCIImage struct { _ gcrv1.Image } -func (o OCIImage) PkgUnit(regErrStore RegistrationErrorStore) (packagingUnit, error) { - pkg := packagingUnit{} +func (o OCIImage) PkgUnit(regErrStore RegistrationErrorStore) (PackagingUnit, error) { + pkg := PackagingUnit{} return pkg, nil } diff --git a/models/registration/register.go b/models/registration/register.go index 50f86639..e01c969f 100644 --- a/models/registration/register.go +++ b/models/registration/register.go @@ -10,11 +10,11 @@ import ( "github.com/meshery/schemas/models/v1beta1/model" ) -// packaingUnit is the representation of the atomic unit that can be registered into the capabilities registry -type packagingUnit struct { - model model.ModelDefinition - components []component.ComponentDefinition - relationships []relationship.RelationshipDefinition +// PackagingUnit is the representation of the atomic unit that can be registered into the capabilities registry +type PackagingUnit struct { + Model model.ModelDefinition + Components []component.ComponentDefinition + Relationships []relationship.RelationshipDefinition _ []v1beta1.PolicyDefinition } @@ -22,10 +22,11 @@ type RegistrationHelper struct { regManager *meshmodel.RegistryManager regErrStore RegistrationErrorStore svgBaseDir string + PkgUnits []PackagingUnit // Store successfully registered packagingUnits } func NewRegistrationHelper(svgBaseDir string, regm *meshmodel.RegistryManager, regErrStore RegistrationErrorStore) RegistrationHelper { - return RegistrationHelper{svgBaseDir: svgBaseDir, regManager: regm, regErrStore: regErrStore} + return RegistrationHelper{svgBaseDir: svgBaseDir, regManager: regm, regErrStore: regErrStore, PkgUnits: []PackagingUnit{}} } /* @@ -45,11 +46,11 @@ func (rh *RegistrationHelper) Register(entity RegisterableEntity) { 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) { +func (rh *RegistrationHelper) register(pkg PackagingUnit) { // 1. Register the model - model := pkg.model + model := pkg.Model - // Dont register anything else if registrant is not there + // Don't register anything else if registrant is not there if model.Registrant.Kind == "" { err := ErrMissingRegistrant(model.Name) rh.regErrStore.InsertEntityRegError(model.Registrant.Kind, "", entity.Model, model.Name, err) @@ -64,24 +65,22 @@ func (rh *RegistrationHelper) register(pkg packagingUnit) { var svgCompletePath string - //Write SVG for models - model.Metadata.SvgColor, model.Metadata.SvgWhite, svgCompletePath = WriteAndReplaceSVGWithFileSystemPath(model.Metadata.SvgColor, + // Write SVG for models + model.Metadata.SvgColor, model.Metadata.SvgWhite, svgCompletePath = WriteAndReplaceSVGWithFileSystemPath( + model.Metadata.SvgColor, model.Metadata.SvgWhite, - svgComplete, rh.svgBaseDir, + svgComplete, + rh.svgBaseDir, model.Name, model.Name, ) if svgCompletePath != "" { model.Metadata.SvgComplete = &svgCompletePath } - } model.Registrant.Status = connection.Registered - _, _, err := rh.regManager.RegisterEntity( - model.Registrant, - &model, - ) + _, _, err := rh.regManager.RegisterEntity(model.Registrant, &model) // If model cannot be registered, don't register anything else if err != nil { @@ -91,13 +90,16 @@ func (rh *RegistrationHelper) register(pkg packagingUnit) { } hostname := model.Registrant.Kind - modelName := model.Name + + // Prepare slices to hold successfully registered components and relationships + var registeredComponents []component.ComponentDefinition + var registeredRelationships []relationship.RelationshipDefinition // 2. Register components - for _, comp := range pkg.components { + for _, comp := range pkg.Components { comp.Model = model if comp.Styles != nil { - //Write SVG for components + // Write SVG for components comp.Styles.SvgColor, comp.Styles.SvgWhite, comp.Styles.SvgComplete = WriteAndReplaceSVGWithFileSystemPath( comp.Styles.SvgColor, comp.Styles.SvgWhite, @@ -108,23 +110,33 @@ func (rh *RegistrationHelper) register(pkg packagingUnit) { ) } - _, _, err := rh.regManager.RegisterEntity( - model.Registrant, - &comp, - ) + _, _, err := rh.regManager.RegisterEntity(model.Registrant, &comp) if err != nil { err = ErrRegisterEntity(err, string(comp.Type()), comp.DisplayName) - rh.regErrStore.InsertEntityRegError(hostname, modelName, entity.ComponentDefinition, comp.DisplayName, err) + rh.regErrStore.InsertEntityRegError(hostname, model.DisplayName, entity.ComponentDefinition, comp.DisplayName, err) + } else { + // Successful registration, add to successfulComponents + registeredComponents = append(registeredComponents, comp) } } // 3. Register relationships - for _, rel := range pkg.relationships { + for _, rel := range pkg.Relationships { rel.Model = model _, _, err := rh.regManager.RegisterEntity(model.Registrant, &rel) if err != nil { err = ErrRegisterEntity(err, string(rel.Type()), string(rel.Kind)) - rh.regErrStore.InsertEntityRegError(hostname, modelName, entity.RelationshipDefinition, rel.Id.String(), err) + rh.regErrStore.InsertEntityRegError(hostname, model.DisplayName, entity.RelationshipDefinition, rel.Id.String(), err) + } else { + // Successful registration, add to successfulRelationships + registeredRelationships = append(registeredRelationships, rel) } } + + // Update pkg with only successfully registered components and relationships + pkg.Components = registeredComponents + pkg.Relationships = registeredRelationships + pkg.Model = model + // Store the successfully registered PackagingUnit + rh.PkgUnits = append(rh.PkgUnits, pkg) } diff --git a/models/registration/tar.go b/models/registration/tar.go index 139a28bb..3849039d 100644 --- a/models/registration/tar.go +++ b/models/registration/tar.go @@ -4,7 +4,7 @@ type Tar struct { _ string } -func (t Tar) PkgUnit(regErrStore RegistrationErrorStore) (packagingUnit, error) { - pkg := packagingUnit{} +func (t Tar) PkgUnit(regErrStore RegistrationErrorStore) (PackagingUnit, error) { + pkg := PackagingUnit{} return pkg, nil } diff --git a/utils/utils.go b/utils/utils.go index 96970d58..112c3cfe 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -495,3 +495,41 @@ func ConvertMapInterfaceMapString(v interface{}) interface{} { return v } +func ConvertToJSONCompatible(data interface{}) interface{} { + switch v := data.(type) { + case map[interface{}]interface{}: + m := make(map[string]interface{}) + for key, value := range v { + m[key.(string)] = ConvertToJSONCompatible(value) + } + return m + case []interface{}: + for i, item := range v { + v[i] = ConvertToJSONCompatible(item) + } + } + return data +} +func YAMLToJSON(content []byte) ([]byte, error) { + var jsonData interface{} + if err := yaml.Unmarshal(content, &jsonData); err == nil { + jsonData = ConvertToJSONCompatible(jsonData) + convertedContent, err := json.Marshal(jsonData) + if err == nil { + content = convertedContent + } else { + return nil, ErrUnmarshal(err) + } + } else { + return nil, ErrUnmarshal(err) + } + return content, nil +} +func ExtractFile(filePath string, destDir string) error { + if IsTarGz(filePath) { + return ExtractTarGz(destDir, filePath) + } else if IsZip(filePath) { + return ExtractZip(destDir, filePath) + } + return ErrExtractType +} From 8197443946c9e36526d69829d6a85ae5ac9751d8 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Mon, 16 Sep 2024 17:52:34 +0530 Subject: [PATCH 2/8] fix index issue w/signoff Signed-off-by: Jougan-0 --- models/meshmodel/registry/v1beta1/model_filter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/meshmodel/registry/v1beta1/model_filter.go b/models/meshmodel/registry/v1beta1/model_filter.go index 86971485..fe500864 100644 --- a/models/meshmodel/registry/v1beta1/model_filter.go +++ b/models/meshmodel/registry/v1beta1/model_filter.go @@ -102,7 +102,7 @@ func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, e if mf.Greedy { if mf.Id != "" { - finder = finder.First("model_dbs.id = ?", mf.Id) + finder = finder.Where("model_dbs.id = ?", mf.Id) } if mf.Name != "" && mf.DisplayName != "" { finder = finder.Where("model_dbs.name LIKE ? OR model_dbs.display_name LIKE ?", "%"+mf.Name+"%", "%"+mf.DisplayName+"%") From 1d0652511646c158fb37693d1dbbceeb1f7c1f65 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Mon, 16 Sep 2024 17:57:30 +0530 Subject: [PATCH 3/8] svgdata from path w/signoff Signed-off-by: Jougan-0 --- utils/utils.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/utils/utils.go b/utils/utils.go index 112c3cfe..a65d3438 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -533,3 +533,13 @@ func ExtractFile(filePath string, destDir string) error { } return ErrExtractType } + +// Convert path to svg Data +func ReadSVGData(baseDir, path string) (string, error) { + fullPath := baseDir + path + svgData, err := os.ReadFile(fullPath) + if err != nil { + return "", err + } + return string(svgData), nil +} From d6db6dda600570160f8e5dc2d13966be20605b16 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Wed, 18 Sep 2024 17:40:26 +0530 Subject: [PATCH 4/8] function to compress directory w/signoff Signed-off-by: Jougan-0 --- utils/error.go | 4 ++++ utils/utils.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/utils/error.go b/utils/error.go index 3981a282..b1e50625 100644 --- a/utils/error.go +++ b/utils/error.go @@ -46,6 +46,7 @@ var ( ErrCopyFileCode = "replace_me" ErrCloseFileCode = "replace_me" ErrCompressToTarGZCode = "meshkit-11248" + ErrOpenFileCode = "replace_me" ) var ( ErrExtractType = errors.New( @@ -230,3 +231,6 @@ func ErrCloseFile(err error) error { []string{"Check for issues with file permissions or disk space and try again."}, ) } +func ErrOpenFile(file string) error { + return errors.New(ErrOpenFileCode, errors.Alert, []string{"unable to open file: ", file}, []string{}, []string{"The file does not exist in the location"}, []string{"Make sure to upload the correct file"}) +} diff --git a/utils/utils.go b/utils/utils.go index a65d3438..77b2dd64 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,7 +1,9 @@ package utils import ( + "archive/tar" "bytes" + "compress/gzip" "encoding/json" "errors" "fmt" @@ -543,3 +545,44 @@ func ReadSVGData(baseDir, path string) (string, error) { } return string(svgData), nil } +func Compress(src string, buf io.Writer) error { + zr := gzip.NewWriter(buf) + defer zr.Close() + tw := tar.NewWriter(zr) + defer tw.Close() + + return filepath.Walk(src, func(file string, fi os.FileInfo, err error) error { + if err != nil { + return err + } + + header, err := tar.FileInfoHeader(fi, file) + if err != nil { + return err + } + + relPath, err := filepath.Rel(src, file) + if err != nil { + return err + } + header.Name = filepath.ToSlash(relPath) + + if err := tw.WriteHeader(header); err != nil { + return err + } + + if !fi.IsDir() { + data, err := os.Open(file) + if err != nil { + return err + } + defer data.Close() + + _, err = io.Copy(tw, data) + if err != nil { + return err + } + } + return nil + }) +} From fa51598986d21bcc85a010cf21b62615a1535246 Mon Sep 17 00:00:00 2001 From: Aabid Sofi Date: Thu, 19 Sep 2024 03:19:59 +0530 Subject: [PATCH 5/8] update impport modal schema Signed-off-by: Aabid Sofi --- schemas/configuration/modelImport.json | 81 +++++++++++++++++++++----- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/schemas/configuration/modelImport.json b/schemas/configuration/modelImport.json index e3693d40..27fa241f 100644 --- a/schemas/configuration/modelImport.json +++ b/schemas/configuration/modelImport.json @@ -3,10 +3,7 @@ "properties": { "uploadType": { "title": "Upload method", - "enum": [ - "File Upload", - "URL Import" - ], + "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." @@ -30,9 +27,7 @@ "x-rjsf-grid-area": "12" } }, - "required": [ - "file" - ] + "required": ["file"] } }, { @@ -51,15 +46,75 @@ "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" + }, + "model": { + "type": "object", + "description": "Provide the details of the model you are uploading incase you are trying to generate a new model", + "properties": { + "modelDisplayName": { + "type": "string" + }, + "registrant": { + "type": "string" + }, + "model": { + "type": "string" + }, + "category": { + "type": "string" + }, + "subCategory": { + "type": "string" + }, + "shape": { + "type": "string" + }, + "primaryColor": { + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" + }, + "secondaryColor": { + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$" + }, + "svgColor": { + "type": "string" + }, + "svgWhite": { + "type": "string" + }, + "svgComplete": { + "type": "string" + }, + "isAnnotation": { + "type": "string", + "enum": ["TRUE", "FALSE"] + }, + "publishToRegistry": { + "type": "string", + "enum": ["TRUE", "FALSE"] + } + }, + "required": [ + "modelDisplayName", + "registrant", + "model", + "category", + "subCategory", + "shape", + "primaryColor", + "secondaryColor", + "svgColor", + "svgWhite", + "svgComplete", + "isAnnotation", + "publishToRegistry" + ] } }, - "required": [ - "url" - ] + "required": ["url"] } } ], - "required": [ - "uploadType" - ] + "required": ["uploadType"] } From 09bfdc62d6593d709306e5d4c4700075fb9597b4 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Thu, 19 Sep 2024 20:52:47 +0530 Subject: [PATCH 6/8] update the schema w/signoff Signed-off-by: Jougan-0 --- schemas/configuration/modelImport.json | 125 +++++++++++++++++++++---- 1 file changed, 106 insertions(+), 19 deletions(-) diff --git a/schemas/configuration/modelImport.json b/schemas/configuration/modelImport.json index 27fa241f..fa6b82d6 100644 --- a/schemas/configuration/modelImport.json +++ b/schemas/configuration/modelImport.json @@ -55,19 +55,109 @@ "type": "string" }, "registrant": { - "type": "string" + "type": "string", + "enum": ["github", "artifacthub"] }, "model": { "type": "string" }, "category": { - "type": "string" + "type": "string", + "enum": [ + "Analytics", + "App Definition and Development", + "Cloud Native Network", + "Cloud Native Storage", + "Database", + "Machine Learning", + "Observability and Analysis", + "Orchestration & Management", + "Platform", + "Provisioning", + "Runtime", + "Security & Compliance", + "Serverless", + "Tools", + "Uncategorized" + ] }, "subCategory": { - "type": "string" + "type": "string", + "enum": [ + "Academic", + "API Gateway", + "Application Definition & Image Build", + "Automation & Configuration", + "Certified CNFs", + "Certified Kubernetes - Distribution", + "Certified Kubernetes - Hosted", + "Certified Kubernetes - Installer", + "Chaos Engineering", + "Cloud Native Network", + "Cloud Native Storage", + "Container Registry", + "Container Runtime", + "Continuous Integration & Delivery", + "Continuous Optimization", + "Coordination & Service Discovery", + "Database", + "Debugging and Observability", + "End User Supporter", + "Framework", + "Gold", + "Hosted Platform", + "Installable Platform", + "Key Management", + "Kubernetes Certified Service Provider", + "Kubernetes Training Partner", + "Logging", + "Metrics", + "Monitoring", + "Nonprofit", + "Packaging, Registries & Application Delivery", + "PaaS/Container Service", + "Platinum", + "Remote Procedure Call", + "Runtime", + "Scheduling & Orchestration", + "Security", + "Security & Compliance", + "Service Mesh", + "Service Proxy", + "Silver", + "Specifications", + "Streaming & Messaging", + "Toolchain", + "Tools", + "Tracing" + ] }, "shape": { - "type": "string" + "type": "string", + "enum":[ + "rectangle", + "round-rectangle", + "bottom-round-rectangle", + "cut-rectangle", + "shape", + "circle", + "diamond", + "round-rectang", + "hexagon", + "rhomboid", + "triangle", + "cilinder", + "round-triangle", + "round-pentagon", + "sheild", + "vee", + "cylinder", + "round-heptagon", + "concave-hexagon", + "right-rhomboid", + "barrel", + "round-diamond" + ] }, "primaryColor": { "type": "string", @@ -78,7 +168,8 @@ "pattern": "^#[0-9A-Fa-f]{6}$" }, "svgColor": { - "type": "string" + "type": "string", + "default": "" }, "svgWhite": { "type": "string" @@ -87,28 +178,24 @@ "type": "string" }, "isAnnotation": { - "type": "string", - "enum": ["TRUE", "FALSE"] + "type": "boolean", + "title": "Is Annotation", + "description": "Indicate whether this model is an annotation", + "x-rjsf-grid-area": "6" }, "publishToRegistry": { - "type": "string", - "enum": ["TRUE", "FALSE"] + "type": "boolean", + "title": "Publish to Registry", + "default": true, + "description": "Indicate whether to publish this model to the registry", + "x-rjsf-grid-area": "6" } }, "required": [ "modelDisplayName", "registrant", "model", - "category", - "subCategory", - "shape", - "primaryColor", - "secondaryColor", - "svgColor", - "svgWhite", - "svgComplete", - "isAnnotation", - "publishToRegistry" + "isAnnotation" ] } }, From 6b31b7d922f5405ecf8ef0f6898f7113ed68b1b8 Mon Sep 17 00:00:00 2001 From: Aabid Sofi Date: Fri, 20 Sep 2024 17:15:09 +0530 Subject: [PATCH 7/8] update ui schema Signed-off-by: Aabid Sofi --- .../configuration/uiSchemaModelImport.json | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/schemas/configuration/uiSchemaModelImport.json b/schemas/configuration/uiSchemaModelImport.json index 038796fd..ea24b633 100644 --- a/schemas/configuration/uiSchemaModelImport.json +++ b/schemas/configuration/uiSchemaModelImport.json @@ -1,6 +1,38 @@ { - "uploadType": { - "ui:widget": "radio" + "uploadType": { + "ui:widget": "radio" + }, + "model": { + "ui:options": { + "expand": true }, - "ui:order" : [ "uploadType", "file", "url"] - } + "styles": { + "padding": 0, + "margin": 0 + }, + + "primaryColor": { + "ui:widget": "color" + }, + "secondaryColor": { + "ui:widget": "color" + }, + + "ui:order": [ + "modelDisplayName", + "registrant", + "category", + "subCategory", + "model", + "primaryColor", + "secondaryColor", + "shape", + "svgColor", + "svgComplete", + "svgWhite", + "isAnnotation", + "publishToRegistry" + ] + }, + "ui:order": ["uploadType", "file", "url"] +} From 0072758a1323dcae31b05bed8bc7758ba9dabb43 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Sat, 21 Sep 2024 02:07:06 +0530 Subject: [PATCH 8/8] add missing capabilities w/signoff Signed-off-by: Jougan-0 --- .../registry/v1beta1/model_filter.go | 2 +- schemas/configuration/modelImport.json | 55 ++++++++++--------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/models/meshmodel/registry/v1beta1/model_filter.go b/models/meshmodel/registry/v1beta1/model_filter.go index fe500864..6a512f79 100644 --- a/models/meshmodel/registry/v1beta1/model_filter.go +++ b/models/meshmodel/registry/v1beta1/model_filter.go @@ -182,7 +182,7 @@ func (mf *ModelFilter) Get(db *database.Handler) ([]entity.Entity, int64, int, e if includeComponents { var components []component.ComponentDefinition finder := db.Model(&component.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,component_definition_dbs.styles"). + 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,component_definition_dbs.styles,component_definition_dbs.capabilities"). Where("component_definition_dbs.model_id = ?", _modelDB.Id) if err := finder.Scan(&components).Error; err != nil { return nil, 0, 0, err diff --git a/schemas/configuration/modelImport.json b/schemas/configuration/modelImport.json index fa6b82d6..aee0bbc0 100644 --- a/schemas/configuration/modelImport.json +++ b/schemas/configuration/modelImport.json @@ -44,7 +44,7 @@ "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", + "description": "Provide the URL of the design file you want to import.", "x-rjsf-grid-area": "12" }, "model": { @@ -52,6 +52,7 @@ "description": "Provide the details of the model you are uploading incase you are trying to generate a new model", "properties": { "modelDisplayName": { + "description":"The model name that would be showed on kanvas and everywhere else mostly of type 'Model Name'", "type": "string" }, "registrant": { @@ -59,27 +60,29 @@ "enum": ["github", "artifacthub"] }, "model": { + "description":"This name is of the type 'model-name'", "type": "string" }, "category": { - "type": "string", - "enum": [ - "Analytics", - "App Definition and Development", - "Cloud Native Network", - "Cloud Native Storage", - "Database", - "Machine Learning", - "Observability and Analysis", - "Orchestration & Management", - "Platform", - "Provisioning", - "Runtime", - "Security & Compliance", - "Serverless", - "Tools", - "Uncategorized" - ] + "description":"The category of the model. The model will be located under the specific category on kanvas.", + "type": "string", + "enum": [ + "Analytics", + "App Definition and Development", + "Cloud Native Network", + "Cloud Native Storage", + "Database", + "Machine Learning", + "Observability and Analysis", + "Orchestration & Management", + "Platform", + "Provisioning", + "Runtime", + "Security & Compliance", + "Serverless", + "Tools", + "Uncategorized" + ] }, "subCategory": { "type": "string", @@ -133,6 +136,7 @@ ] }, "shape": { + "description":"The shape of the model. The model will be displayed in the specific shape on kanvas.", "type": "string", "enum":[ "rectangle", @@ -160,6 +164,7 @@ ] }, "primaryColor": { + "description":"The primary color of the model. This will be the color of the background if the image has one.", "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" }, @@ -180,22 +185,22 @@ "isAnnotation": { "type": "boolean", "title": "Is Annotation", - "description": "Indicate whether this model is an annotation", + "default": false, + "description": "Indicate whether this model is an annotation. Annotation means that this model is not a real model but an svg image", "x-rjsf-grid-area": "6" }, "publishToRegistry": { "type": "boolean", "title": "Publish to Registry", "default": true, - "description": "Indicate whether to publish this model to the registry", + "description": "Indicate whether to publish this model to the registry. If marked as false then the model won't be registered in the registry", "x-rjsf-grid-area": "6" } }, - "required": [ - "modelDisplayName", + "required": [ "registrant", - "model", - "isAnnotation" + "modelDisplayName", + "model" ] } },