From b0c8fc663b06f451ba8257a86147019bce0041c5 Mon Sep 17 00:00:00 2001 From: Jougan-0 Date: Thu, 30 Jan 2025 02:21:57 +0530 Subject: [PATCH] feat: remove string checks and add robust checks for fileType w/signoff Signed-off-by: Jougan-0 --- go.mod | 2 + go.sum | 4 ++ utils/detect_pattern_file_type.go | 101 +++++++++--------------------- 3 files changed, 37 insertions(+), 70 deletions(-) diff --git a/go.mod b/go.mod index 53af3d4c..1a1c91ec 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ replace ( require ( cuelang.org/go v0.11.2 github.com/Masterminds/semver/v3 v3.3.1 + github.com/compose-spec/compose-go v1.20.2 github.com/fluxcd/pkg/oci v0.43.1 github.com/fluxcd/pkg/tar v0.10.0 github.com/go-git/go-git/v5 v5.13.2 @@ -150,6 +151,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect diff --git a/go.sum b/go.sum index f6561000..109df289 100644 --- a/go.sum +++ b/go.sum @@ -113,6 +113,8 @@ github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+py github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= +github.com/compose-spec/compose-go v1.20.2 h1:u/yfZHn4EaHGdidrZycWpxXgFffjYULlTbRfJ51ykjQ= +github.com/compose-spec/compose-go v1.20.2/go.mod h1:+MdqXV4RA7wdFsahh/Kb8U0pAJqkg7mr4PM9tFKU8RM= github.com/compose-spec/compose-go/v2 v2.4.7 h1:WNpz5bIbKG+G+w9pfu72B1ZXr+Og9jez8TMEo8ecXPk= github.com/compose-spec/compose-go/v2 v2.4.7/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= @@ -329,6 +331,8 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= diff --git a/utils/detect_pattern_file_type.go b/utils/detect_pattern_file_type.go index 4b36f8f1..aa30419a 100644 --- a/utils/detect_pattern_file_type.go +++ b/utils/detect_pattern_file_type.go @@ -1,19 +1,17 @@ package utils import ( - "archive/tar" "bytes" - "compress/gzip" - "encoding/json" - "io" - "regexp" + "errors" "strings" - "cuelang.org/go/cue/errors" + composeLoader "github.com/compose-spec/compose-go/loader" + "github.com/compose-spec/compose-go/schema" + "gopkg.in/yaml.v3" + "helm.sh/helm/v3/pkg/chart/loader" ) -// Function to identify the type of input func IdentifyInputType(data []byte) (string, error) { if isMesheryDesign(data) { return "Meshery Design", nil @@ -30,81 +28,44 @@ func IdentifyInputType(data []byte) (string, error) { return "", errors.New("unknown type") } -// Check if the input is a Meshery design func isMesheryDesign(data []byte) bool { - var tempMap map[string]interface{} - - // Try unmarshaling as JSON; if it fails, try YAML - if err := json.Unmarshal(data, &tempMap); err != nil { - var yamlMap map[string]interface{} - if yaml.Unmarshal(data, &yamlMap) != nil { - return false - } - - // Convert YAML to JSON format - yamlToJSON, err := json.Marshal(yamlMap) - if err != nil { - return false - } - - // Unmarshal JSON back into tempMap - if json.Unmarshal(yamlToJSON, &tempMap) != nil { - return false - } + var mesheryPattern struct { + SchemaVersion string `yaml:"schemaVersion"` + Name string `yaml:"name"` + Components []interface{} `yaml:"components"` } - // Check for schemaVersion key - schemaVersion, exists := tempMap["schemaVersion"].(string) - if !exists { + err := yaml.Unmarshal(data, &mesheryPattern) + return err == nil && + strings.HasPrefix(mesheryPattern.SchemaVersion, "designs.meshery.io") && + mesheryPattern.Name != "" && + len(mesheryPattern.Components) > 0 +} + +func isDockerCompose(yamlData []byte) bool { + dict, err := composeLoader.ParseYAML(yamlData) + if err != nil { return false } - - // Validate schemaVersion for Meshery Design - if strings.HasPrefix(schemaVersion, "designs.meshery.io") { - return true + if err := schema.Validate(dict); err != nil { + return false } - - return false -} - -// Check if the input is a Docker Compose file -func isDockerCompose(data []byte) bool { - dockerComposeKeys := []string{"version", "services"} - content := string(data) - for _, key := range dockerComposeKeys { - if !strings.Contains(content, key+":") { - return false - } + if _, ok := dict["services"]; !ok { + return false } return true } -// Check if the input is a Helm chart (.tgz file) func isHelmChart(data []byte) bool { - gzReader, err := gzip.NewReader(bytes.NewReader(data)) - if err != nil { - return false - } - defer gzReader.Close() - - tarReader := tar.NewReader(gzReader) - for { - header, err := tarReader.Next() - if err == io.EOF { - break - } - if err != nil { - return false - } - if strings.HasSuffix(header.Name, "Chart.yaml") { - return true - } - } - return false + chart, err := loader.LoadArchive(bytes.NewReader(data)) + return err == nil && chart.Metadata != nil && chart.Metadata.Name != "" } -// Check if the input is a Kubernetes manifest func isK8sManifest(data []byte) bool { - k8sRegex := regexp.MustCompile(`(?m)^kind:\s+\w+`) - return k8sRegex.Match(data) + var manifest struct { + APIVersion string `yaml:"apiVersion"` + Kind string `yaml:"kind"` + } + err := yaml.Unmarshal(data, &manifest) + return err == nil && manifest.Kind != "" && manifest.APIVersion != "" }