Last active
January 29, 2025 00:50
-
-
Save leecalcote/51623fcf157d3113f3893af8c8f4ba7f to your computer and use it in GitHub Desktop.
YAML file type detectors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Ideally, the detectors here utilize the very same mechanism that each infrastructure has code tool uses to determine whether or not they have a valid manifest. | |
package main | |
import ( | |
"bytes" | |
"fmt" | |
"io/ioutil" | |
"os" | |
"path/filepath" | |
"helm.sh/helm/v3/pkg/chart/loader" | |
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | |
"k8s.io/apimachinery/pkg/util/yaml" | |
"sigs.k8s.io/kustomize/api/krusty" | |
"sigs.k8s.io/kustomize/kyaml/filesys" | |
) | |
func main() { | |
// Replace with the path to your YAML file | |
filePath := "weaveworks-gitops-enterprise-design.yaml" | |
fileContent, err := ioutil.ReadFile(filePath) | |
if err != nil { | |
fmt.Println("Error reading file:", err) | |
return | |
} | |
// Convert fileContent to string for debugging | |
// content := string(fileContent) | |
// fmt.Printf("File content: %s\n", content) | |
// Correct switch statement - no := here | |
switch identifyYAML(filePath, fileContent) { | |
case "DockerCompose": | |
fmt.Println("Docker Compose file detected.") | |
case "Kubernetes": | |
fmt.Println("Kubernetes manifest detected.") | |
case "Helm": | |
fmt.Println("Helm chart detected.") | |
case "Kustomize": | |
fmt.Println("Kustomize file detected.") | |
default: | |
fmt.Println("Unknown YAML format.") | |
} | |
} | |
func identifyYAML(filePath string, fileContent []byte) string { | |
// Check if it's a Kubernetes manifest | |
if isKubernetesManifest(fileContent) { | |
return "Kubernetes" | |
} | |
// Check if it's a Helm chart | |
if isHelmChart(filePath) { | |
return "Helm" | |
} | |
// Check if it's a Kustomize file | |
if isKustomizeFile(filePath) { | |
return "Kustomize" | |
} | |
// If none of the above, assume it's a Docker Compose file | |
// (especially if it has a.yml or.yaml extension and is in the project root) | |
return "DockerCompose" | |
} | |
func isKubernetesManifest(fileContent []byte) bool { | |
decoder := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(fileContent), 4096) | |
var typeMeta metav1.TypeMeta | |
if err := decoder.Decode(&typeMeta); err != nil { | |
return false | |
} | |
// Check for required Kubernetes fields | |
return typeMeta.APIVersion != "" && typeMeta.Kind != "" | |
} | |
func isHelmChart(filePath string) bool { | |
// Verification Criteria: | |
// 1. Check if there is a Chart.yaml file in the directory | |
// 2. Attempt to load the chart using loader.Load | |
chartPath := filepath.Dir(filePath) | |
if _, err := os.Stat(filepath.Join(chartPath, "Chart.yaml")); err == nil { | |
// Use loader.Load instead of chart.Load | |
_, err := loader.Load(chartPath) | |
if err == nil { | |
return true | |
} | |
} | |
return false | |
} | |
func isKustomizeFile(filePath string) bool { | |
// Verification Criteria: | |
// 1. Check if the filename is kustomization.yaml or kustomization.yml | |
// 2. Creates a krusty.Kustomizer instance with default options using krusty.MakeDefaultOptions(). | |
// 2.a. Calls the k.Run() method with the file system and file path to attempt to load and process the file as a Kustomize file. | |
// 2.b. If k.Run() returns an error, it indicates that the file is not a valid Kustomize file. Otherwise, it's considered a Kustomize file. | |
if filepath.Base(filePath) == "kustomization.yaml" || filepath.Base(filePath) == "kustomization.yml" { | |
// Attempt to decode the kustomization file | |
fSys := filesys.MakeFsOnDisk() | |
k := krusty.MakeKustomizer(krusty.MakeDefaultOptions()) | |
_, err := k.Run(fSys, filepath.Dir(filePath)) | |
if err == nil { | |
return true | |
} | |
} | |
return false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment