Skip to content

Commit defefd9

Browse files
authored
Merge pull request #659 from aabidsofi19/add-identification-support
Add and Enhance support for file sanitization and identification
2 parents 65f7e2b + 6092233 commit defefd9

29 files changed

+3044
-116
lines changed

files/conversion.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package files
2+
3+
import (
4+
"fmt"
5+
"github.com/layer5io/meshkit/utils/helm"
6+
"helm.sh/helm/v3/pkg/chart"
7+
)
8+
9+
func ConvertHelmChartToKubernetesManifest(file IdentifiedFile) (string, error) {
10+
chart, ok := file.ParsedFile.(*chart.Chart)
11+
if chart != nil && !ok {
12+
return "", fmt.Errorf("Failed to get *chart.Chart from identified file")
13+
}
14+
// empty kubernetes version because helm should figure it out
15+
manifest, err := helm.DryRunHelmChart(chart, "")
16+
if err != nil {
17+
return "", err
18+
}
19+
return string(manifest), nil
20+
}
21+
22+
func ConvertDockerComposeToKubernetesManifest(file IdentifiedFile) (string, error) {
23+
parsedCompose, ok := file.ParsedFile.(ParsedCompose)
24+
if !ok {
25+
return "", fmt.Errorf("Failed to get *chart.Chart from identified file")
26+
}
27+
28+
return parsedCompose.manifest, nil
29+
}

files/errors.go

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
package files
2+
3+
import (
4+
"fmt"
5+
"maps"
6+
"slices"
7+
"strings"
8+
9+
"github.com/layer5io/meshkit/errors"
10+
)
11+
12+
var (
13+
// Error code
14+
ErrUnsupportedExtensionCode = "replace_me"
15+
ErrUnsupportedExtensionForOperationCode = "replace_me"
16+
ErrFailedToIdentifyFileCode = "replace_me"
17+
ErrSanitizingFileCode = "replace_me"
18+
ErrInvalidYamlCode = "replace_me"
19+
ErrInvalidJsonCode = "replace_me"
20+
ErrFailedToExtractTarCode = "replace_me"
21+
ErrUnsupportedFileTypeCode = "replace_me"
22+
ErrInvalidKubernetesManifestCode = "replace_me"
23+
ErrInvalidMesheryDesignCode = "replace_me"
24+
ErrInvalidHelmChartCode = "replace_me"
25+
ErrInvalidDockerComposeCode = "replace_me"
26+
ErrInvalidKustomizationCode = "replace_me"
27+
ErrFileTypeNotSupportedForDesignConversion = "replace_me"
28+
)
29+
30+
func ErrUnsupportedExtensionForOperation(operation string, fileName string, fileExt string, supportedExtensions []string) error {
31+
sdescription := []string{
32+
fmt.Sprintf("The file '%s' has an unsupported extension '%s' for the operation '%s'.", fileName, fileExt, operation),
33+
fmt.Sprintf("Supported extensions for this operation are: %s.", strings.Join(supportedExtensions, ", ")),
34+
}
35+
36+
ldescription := []string{
37+
fmt.Sprintf("The file '%s' could not be used for the operation '%s' because the extension '%s' is not supported.", fileName, operation, fileExt),
38+
fmt.Sprintf("The system is designed to handle files with the following extensions for this operation: %s.", strings.Join(supportedExtensions, ", ")),
39+
}
40+
41+
probableCause := []string{
42+
"The file extension does not match any of the supported formats for this operation.",
43+
"The file may have been saved with an incorrect or unsupported extension.",
44+
"The operation may have specific requirements for file types that are not met by this file.",
45+
}
46+
47+
remedy := []string{
48+
"Ensure the file is saved with one of the supported extensions for this operation.",
49+
"Convert the file to a supported format before attempting the operation.",
50+
"Check the documentation or requirements for the operation to verify the supported file types.",
51+
}
52+
53+
return errors.New(ErrUnsupportedExtensionForOperationCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
54+
}
55+
56+
func ErrUnsupportedExtension(fileName string, fileExt string, supportedExtensionsMap map[string]bool) error {
57+
supportedExtensions := slices.Collect(maps.Keys(supportedExtensionsMap))
58+
59+
sdescription := []string{
60+
fmt.Sprintf("The file '%s' has an unsupported extension: '%s'.", fileName, fileExt),
61+
fmt.Sprintf("Supported file extensions are: %s.", strings.Join(supportedExtensions, ", ")),
62+
}
63+
64+
ldescription := []string{
65+
fmt.Sprintf("The file '%s' could not be processed because the extension '%s' is not supported by the system.", fileName, fileExt),
66+
fmt.Sprintf("The system is designed to handle files with the following extensions: %s.", strings.Join(supportedExtensions, ", ")),
67+
}
68+
69+
probableCause := []string{
70+
"The file extension does not match any of the supported formats.",
71+
"The file may have been saved with an incorrect or unsupported extension.",
72+
}
73+
74+
remedy := []string{
75+
"Ensure the file is saved with one of the supported extensions.",
76+
"Convert the file to a supported format before attempting to process it.",
77+
}
78+
79+
return errors.New(ErrSanitizingFileCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
80+
}
81+
82+
func ErrInvalidYaml(fileName string, err error) error {
83+
sdescription := []string{
84+
fmt.Sprintf("The file '%s' contains invalid YAML syntax.", fileName),
85+
}
86+
87+
ldescription := []string{
88+
fmt.Sprintf("The file '%s' could not be parsed due to invalid YAML syntax.", fileName),
89+
fmt.Sprintf("Error details: %s", err.Error()),
90+
}
91+
92+
probableCause := []string{
93+
"The YAML file may contain syntax errors, such as incorrect indentation, missing colons, or invalid characters.",
94+
"The file may have been corrupted or improperly edited.",
95+
}
96+
97+
remedy := []string{
98+
"Review the YAML syntax in the file and correct any errors.",
99+
"Use a YAML validator or linter to identify and fix issues.",
100+
"Ensure the file adheres to the YAML specification.",
101+
}
102+
103+
return errors.New(ErrInvalidYamlCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
104+
}
105+
106+
func ErrInvalidJson(fileName string, err error) error {
107+
sdescription := []string{
108+
fmt.Sprintf("The file '%s' contains invalid JSON syntax.", fileName),
109+
}
110+
111+
ldescription := []string{
112+
fmt.Sprintf("The file '%s' could not be parsed due to invalid JSON syntax.", fileName),
113+
fmt.Sprintf("Error details: %s", err.Error()),
114+
}
115+
116+
probableCause := []string{
117+
"The JSON file may contain syntax errors, such as missing commas, curly braces, or square brackets.",
118+
"The file may have been corrupted or improperly edited.",
119+
"Special characters or escape sequences may not have been properly formatted.",
120+
}
121+
122+
remedy := []string{
123+
"Review the JSON syntax in the file and correct any errors.",
124+
"Use a JSON validator or linter to identify and fix issues.",
125+
"Ensure the file adheres to the JSON specification (e.g., double quotes for keys and strings).",
126+
"Check for common issues like trailing commas or unescaped special characters.",
127+
}
128+
129+
return errors.New(ErrInvalidJsonCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
130+
}
131+
132+
func ErrFailedToExtractArchive(fileName string, err error) error {
133+
sdescription := []string{
134+
fmt.Sprintf("Failed to extract the archive '%s'.", fileName),
135+
}
136+
137+
ldescription := []string{
138+
fmt.Sprintf("An error occurred while attempting to extract the TAR archive '%s'.", fileName),
139+
fmt.Sprintf("Error details: %s", err.Error()),
140+
}
141+
142+
probableCause := []string{
143+
"The archive may be corrupted or incomplete.",
144+
"The archive may contain unsupported compression formats or features.",
145+
"Insufficient permissions to read or write files during extraction.",
146+
"The archive may have been created with a different tool or version that is incompatible.",
147+
}
148+
149+
remedy := []string{
150+
"Verify that the archive is not corrupted by checking its integrity or re-downloading it.",
151+
"Ensure the archive uses a supported compression format (e.g., .zip, .tar, .tar.gz, ).",
152+
"Check that you have sufficient permissions to read the archive and write to the destination directory.",
153+
"Try using a different extraction tool or library to rule out compatibility issues.",
154+
}
155+
156+
return errors.New(ErrFailedToExtractTarCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
157+
}
158+
159+
func ErrFailedToIdentifyFile(fileName string, fileExt string, identificationTrace map[string]error) error {
160+
161+
validTypes := slices.Collect(maps.Keys(identificationTrace))
162+
163+
sdescription := []string{
164+
"The file '%s' could not be identified as a supported type",
165+
}
166+
167+
// Build a detailed trace of identification attempts
168+
var traceDetails []string
169+
for fileType, err := range identificationTrace {
170+
traceDetails = append(traceDetails, fmt.Sprintf("- Attempted to identify as '%s': %v", fileType, err))
171+
}
172+
173+
ldescription := []string{
174+
fmt.Sprintf("The file '%s' was not recognized as any of the supported file types %v.", fileName, validTypes),
175+
"Identification attempts and errors:",
176+
}
177+
ldescription = append(ldescription, traceDetails...)
178+
179+
probableCause := []string{
180+
"The file extension does not match any of the supported types.",
181+
"The file may be corrupted or incomplete.",
182+
"The file may have been saved with an incorrect or unsupported format.",
183+
"The file may not conform to the expected structure for any supported type.",
184+
}
185+
186+
remedy := []string{
187+
"Ensure the file is saved with one of the supported extensions.",
188+
"Verify the integrity of the file and ensure it is not corrupted.",
189+
"Check the file's content and structure to ensure it matches one of the supported types.",
190+
"Convert the file to a supported format before attempting to process it.",
191+
}
192+
return errors.New(ErrUnsupportedFileTypeCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
193+
}
194+
195+
func ErrInvalidKubernetesManifest(fileName string, err error) error {
196+
sdescription := []string{
197+
fmt.Sprintf("The file '%s' is not a valid Kubernetes manifest.", fileName),
198+
}
199+
200+
ldescription := []string{
201+
fmt.Sprintf("The file '%s' could not be parsed as a Kubernetes manifest due to invalid syntax or structure.", fileName),
202+
fmt.Sprintf("Error details: %s", err.Error()),
203+
}
204+
205+
probableCause := []string{
206+
"The file may contain invalid YAML syntax or incorrect indentation.",
207+
"The file may not conform to the Kubernetes API schema.",
208+
"The file may be missing required fields or contain unsupported fields.",
209+
}
210+
211+
remedy := []string{
212+
"Review the YAML syntax in the file and correct any errors.",
213+
"Use a Kubernetes YAML validator or linter to identify and fix issues.",
214+
"Ensure the file adheres to the Kubernetes API specification.",
215+
}
216+
217+
return errors.New(ErrInvalidKubernetesManifestCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
218+
}
219+
220+
func ErrInvalidHelmChart(fileName string, err error) error {
221+
sdescription := []string{
222+
fmt.Sprintf("The file '%s' is not a valid Helm chart.", fileName),
223+
}
224+
225+
ldescription := []string{
226+
fmt.Sprintf("The file '%s' could not be parsed as a Helm chart due to invalid structure or missing files.", fileName),
227+
fmt.Sprintf("Error details: %s", err.Error()),
228+
}
229+
230+
probableCause := []string{
231+
"The file may be missing required files such as 'Chart.yaml' or 'values.yaml'.",
232+
"The file may be corrupted or incomplete.",
233+
"The file may not conform to the Helm chart specification.",
234+
}
235+
236+
remedy := []string{
237+
"Ensure the file contains all required Helm chart files (e.g., Chart.yaml, values.yaml).",
238+
"Verify the integrity of the Helm chart archive.",
239+
"Check the Helm documentation for the correct chart structure.",
240+
}
241+
242+
return errors.New(ErrInvalidHelmChartCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
243+
}
244+
245+
func ErrInvalidDockerCompose(fileName string, err error) error {
246+
sdescription := []string{
247+
fmt.Sprintf("The file '%s' is not a valid Docker Compose file.", fileName),
248+
}
249+
250+
ldescription := []string{
251+
fmt.Sprintf("The file '%s' could not be parsed as a Docker Compose file due to invalid syntax or structure.", fileName),
252+
fmt.Sprintf("Error details: %s", err.Error()),
253+
}
254+
255+
probableCause := []string{
256+
"The file may contain invalid YAML syntax or incorrect indentation.",
257+
"The file may not conform to the Docker Compose specification.",
258+
"The file may be missing required fields or contain unsupported fields.",
259+
}
260+
261+
remedy := []string{
262+
"Review the YAML syntax in the file and correct any errors.",
263+
"Use a Docker Compose validator or linter to identify and fix issues.",
264+
"Ensure the file adheres to the Docker Compose specification.",
265+
}
266+
267+
return errors.New(ErrInvalidDockerComposeCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
268+
}
269+
270+
func ErrInvalidKustomization(fileName string, err error) error {
271+
sdescription := []string{
272+
fmt.Sprintf("The file '%s' is not a valid Kustomization file.", fileName),
273+
}
274+
275+
ldescription := []string{
276+
fmt.Sprintf("The file '%s' could not be parsed as a Kustomization file due to invalid syntax or structure.", fileName),
277+
fmt.Sprintf("Error details: %s", err.Error()),
278+
}
279+
280+
probableCause := []string{
281+
"The file may be missing required fields such as 'resources' or 'bases'.",
282+
"The file may contain invalid YAML syntax or incorrect indentation.",
283+
"The file may not conform to the Kustomize specification.",
284+
}
285+
286+
remedy := []string{
287+
"Review the YAML syntax in the file and correct any errors.",
288+
"Ensure the file contains all required fields for Kustomization.",
289+
"Check the Kustomize documentation for the correct file structure.",
290+
}
291+
292+
return errors.New(ErrInvalidKustomizationCode, errors.Critical, sdescription, ldescription, probableCause, remedy)
293+
}
294+
295+
func ErrUnsupportedFileTypeForConversionToDesign(fileName string, fileType string) error {
296+
sdescription := []string{
297+
fmt.Sprintf("The file '%s' of type '%s' is not supported for conversion to a design", fileName, fileType),
298+
}
299+
300+
ldescription := []string{
301+
fmt.Sprintf("The file '%s' of type '%s' cannot be converted to design. Supported formats are: meshery-design, helm-chart, k8s-manifest, docker-compose.", fileName, fileType),
302+
}
303+
304+
probableCause := []string{
305+
"File doesn't match any supported IAC files",
306+
"Attempting to convert a file type not enabled for design conversion",
307+
}
308+
309+
remedy := []string{
310+
"Verify the file format matches one of the supported types",
311+
"Convert the file to a supported format before processing",
312+
}
313+
314+
return errors.New(ErrFileTypeNotSupportedForDesignConversion, errors.Critical, sdescription, ldescription, probableCause, remedy)
315+
}
316+
317+
var (
318+
ErrNoTarInsideOCICode = "replace_me"
319+
ErrEmptyOCIImageCode = "replace_me"
320+
ErrUnCompressOCIArtifactCode = "replace_me"
321+
ErrWaklingLocalDirectoryCode = "replace_me"
322+
ErrDecodePatternCode = "replace_me"
323+
)
324+
325+
// OCI Parsing errors
326+
327+
func ErrNoTarInsideOCi() error {
328+
return errors.New(ErrNoTarInsideOCICode, errors.Alert, []string{"No tar file found inside OCI image"}, []string{"Unable to locate the compressed file(.tar.gz) inside the OCI image."}, []string{"The OCI image does not contain a ziped file."}, []string{"Verify that the OCI image contains a ziped file."})
329+
}
330+
func ErrEmptyOCIImage(err error) error {
331+
return errors.New(ErrEmptyOCIImageCode, errors.Alert, []string{}, []string{}, []string{}, []string{})
332+
}
333+
334+
func ErrUnCompressOCIArtifact(err error) error {
335+
return errors.New(ErrUnCompressOCIArtifactCode, errors.Alert, []string{"Failed to uncompress OCI artifact"}, []string{err.Error()}, []string{"unable to uncompress OCI artifact", "OCI artifact may be corrupted"}, []string{"check if the OCI artifact is valid and not corrupted"})
336+
}
337+
338+
func ErrWaklingLocalDirectory(err error) error {
339+
return errors.New(ErrWaklingLocalDirectoryCode, errors.Alert, []string{"Failed to walk local directory"}, []string{err.Error()}, []string{"unable to walk local directory", "local directory may be corrupted"}, []string{"check if the local directory is valid and not corrupted"})
340+
}
341+
342+
func ErrDecodePattern(err error) error {
343+
return errors.New(ErrDecodePatternCode, errors.Alert, []string{"Error failed to decode design data into go slice"}, []string{err.Error()}, []string{}, []string{})
344+
}

0 commit comments

Comments
 (0)