Repository: rancher/fleet
Pull request #592 (2021-11-04 19:46:46)

Allow for fleet.yml
Primary issue (contains child issues): https://github.com/rancher/fleet/issues/593


Patch:
diff --git a/go.sum b/go.sum
index 818faa94..44083f69 100644
--- a/go.sum
+++ b/go.sum
@@ -1208,8 +1208,6 @@ github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqW
 github.com/rancher/wrangler v0.6.1/go.mod h1:L4HtjPeX8iqLgsxfJgz+JjKMcX2q3qbRXSeTlC/CSd4=
 github.com/rancher/wrangler v0.6.2-0.20200829053106-7e1dd4260224/go.mod h1:I7qe4DZNMOLKVa9ax7DJdBZ0XtKOppLF/dalhPX3vaE=
 github.com/rancher/wrangler v0.7.3-0.20201002224307-4303c423125a/go.mod h1:goezjesEKwMxHLfltdjg9DW0xWV7txQee6vOuSDqXAI=
-github.com/rancher/wrangler v0.8.4-0.20210729214659-5e75fca61cb2 h1:ja7zS/MtLRAs4ZgCIlocJg3c74qWpvRneQWEkSF3g9Q=
-github.com/rancher/wrangler v0.8.4-0.20210729214659-5e75fca61cb2/go.mod h1:dKEaHNB4izxmPUtpq1Hvr3z3Oh+9k5pCZyFO9sUhlaY=
 github.com/rancher/wrangler v0.8.4 h1:aGMqLQHtn9yB8vw584TO8x/tvZMiaY7Yyi37Fp22UFU=
 github.com/rancher/wrangler v0.8.4/go.mod h1:dKEaHNB4izxmPUtpq1Hvr3z3Oh+9k5pCZyFO9sUhlaY=
 github.com/rancher/wrangler-cli v0.0.0-20200815040857-81c48cf8ab43 h1:+Bc9QnL9GuZiYxc3Mvm4n6EEjgI5TFQLDGjpRhQbkVk=
diff --git a/modules/cli/apply/apply.go b/modules/cli/apply/apply.go
index 0920fcbb..9b1ff2a7 100644
--- a/modules/cli/apply/apply.go
+++ b/modules/cli/apply/apply.go
@@ -14,6 +14,7 @@ import (
 	"github.com/rancher/fleet/modules/cli/pkg/client"
 	fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
 	"github.com/rancher/fleet/pkg/bundle"
+	"github.com/rancher/fleet/pkg/bundleyaml"
 	name2 "github.com/rancher/wrangler/pkg/name"
 	"github.com/rancher/wrangler/pkg/yaml"
 	"github.com/sirupsen/logrus"
@@ -85,7 +86,7 @@ func Apply(ctx context.Context, client *client.Getter, name string, baseDirs []s
 					if !info.IsDir() {
 						return nil
 					}
-					if _, err := os.Stat(filepath.Join(path, "fleet.yaml")); err != nil {
+					if !bundleyaml.FoundFleetYamlInDirectory(path) {
 						return nil
 					}
 				}
diff --git a/pkg/bundle/read.go b/pkg/bundle/read.go
index 52227f59..068990da 100644
--- a/pkg/bundle/read.go
+++ b/pkg/bundle/read.go
@@ -13,6 +13,7 @@ import (
 	"strconv"
 
 	fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
+	"github.com/rancher/fleet/pkg/bundleyaml"
 	name1 "github.com/rancher/wrangler/pkg/name"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"sigs.k8s.io/yaml"
@@ -43,14 +44,14 @@ func Open(ctx context.Context, name, baseDir, file string, opts *Options) (*Bund
 	)
 
 	if file == "" {
-		file = filepath.Join(baseDir, "fleet.yaml")
-		if f, err := os.Open(file); os.IsNotExist(err) {
-			in = bytes.NewBufferString("{}")
-		} else if err != nil {
+		if file, err := setupIOReader(baseDir); err != nil {
 			return nil, err
+		} else if file != nil {
+			in = file
+			defer file.Close()
 		} else {
-			in = f
-			defer f.Close()
+			// Create a new buffer if opening both files resulted in "IsNotExist" errors.
+			in = bytes.NewBufferString("{}")
 		}
 	} else {
 		f, err := os.Open(filepath.Join(baseDir, file))
@@ -64,6 +65,27 @@ func Open(ctx context.Context, name, baseDir, file string, opts *Options) (*Bund
 	return Read(ctx, name, baseDir, in, opts)
 }
 
+// Try accessing the documented, primary fleet.yaml extension first. If that returns an "IsNotExist" error, then we
+// try the fallback extension. If we receive "IsNotExist" errors for both file extensions, then we return a "nil" file
+// and a "nil" error. If either return a non-"IsNotExist" error, then we return the error immediately.
+func setupIOReader(baseDir string) (*os.File, error) {
+	if file, err := os.Open(bundleyaml.GetFleetYamlPath(baseDir, false)); err != nil && !os.IsNotExist(err) {
+		return nil, err
+	} else if err == nil {
+		// File must be closed in the parent function.
+		return file, nil
+	}
+
+	if file, err := os.Open(bundleyaml.GetFleetYamlPath(baseDir, true)); err != nil && !os.IsNotExist(err) {
+		return nil, err
+	} else if err == nil {
+		// File must be closed in the parent function.
+		return file, nil
+	}
+
+	return nil, nil
+}
+
 func Read(ctx context.Context, name, baseDir string, bundleSpecReader io.Reader, opts *Options) (*Bundle, error) {
 	if opts == nil {
 		opts = &Options{}
diff --git a/pkg/bundleyaml/bundleyaml.go b/pkg/bundleyaml/bundleyaml.go
new file mode 100644
index 00000000..08dbdae7
--- /dev/null
+++ b/pkg/bundleyaml/bundleyaml.go
@@ -0,0 +1,39 @@
+package bundleyaml
+
+import (
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+const (
+	fleetYaml         = "fleet.yaml"
+	fallbackFleetYaml = "fleet.yml"
+)
+
+func FoundFleetYamlInDirectory(baseDir string) bool {
+	if _, err := os.Stat(GetFleetYamlPath(baseDir, false)); err != nil {
+		if _, err := os.Stat(GetFleetYamlPath(baseDir, true)); err != nil {
+			return false
+		}
+	}
+	return true
+}
+
+func GetFleetYamlPath(baseDir string, useFallbackFileExtension bool) string {
+	if useFallbackFileExtension {
+		return filepath.Join(baseDir, fallbackFleetYaml)
+	}
+	return filepath.Join(baseDir, fleetYaml)
+}
+
+func IsFleetYaml(fileName string) bool {
+	if fileName == fleetYaml || fileName == fallbackFleetYaml {
+		return true
+	}
+	return false
+}
+
+func IsFleetYamlSuffix(filePath string) bool {
+	return strings.HasSuffix(filePath, "/"+fleetYaml) || strings.HasSuffix(filePath, "/"+fallbackFleetYaml)
+}
diff --git a/pkg/helm/helm.go b/pkg/helm/helm.go
index daaf0d4f..1b4d2c66 100644
--- a/pkg/helm/helm.go
+++ b/pkg/helm/helm.go
@@ -6,6 +6,7 @@ import (
 
 	fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
 	"github.com/rancher/fleet/pkg/bundle"
+	"github.com/rancher/fleet/pkg/bundleyaml"
 	"github.com/rancher/fleet/pkg/manifest"
 	"github.com/rancher/fleet/pkg/rawyaml"
 	"github.com/rancher/wrangler/pkg/kv"
@@ -39,7 +40,7 @@ func move(m *manifest.Manifest, from, to string) (result []fleet.BundleResource)
 func manifests(m *manifest.Manifest) (result []fleet.BundleResource) {
 	var ignorePrefix []string
 	for _, resource := range m.Resources {
-		if strings.HasSuffix(resource.Name, "/fleet.yaml") ||
+		if bundleyaml.IsFleetYamlSuffix(resource.Name) ||
 			strings.HasSuffix(resource.Name, "/Chart.yaml") {
 			ignorePrefix = append(ignorePrefix, filepath.Dir(resource.Name)+"/")
 		}
@@ -47,7 +48,7 @@ func manifests(m *manifest.Manifest) (result []fleet.BundleResource) {
 
 outer:
 	for _, resource := range m.Resources {
-		if resource.Name == "fleet.yaml" {
+		if bundleyaml.IsFleetYaml(resource.Name) {
 			continue
 		}
 		if !strings.HasSuffix(resource.Name, ".yaml") &&


Test patch:
diff --git a/pkg/bundleyaml/bundleyaml_test.go b/pkg/bundleyaml/bundleyaml_test.go
new file mode 100644
index 00000000..44c7381c
--- /dev/null
+++ b/pkg/bundleyaml/bundleyaml_test.go
@@ -0,0 +1,28 @@
+// +build !windows
+
+package bundleyaml
+
+import (
+	"path/filepath"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestBundleYaml(t *testing.T) {
+	a := assert.New(t)
+	for _, path := range []string{"/foo", "foo", "/foo/", "foo/", "../foo/bar"} {
+
+		// Test both the primary extension and the fallback extension.
+		for _, fullPath := range []string{GetFleetYamlPath(path, false), GetFleetYamlPath(path, true)} {
+			a.True(IsFleetYaml(filepath.Base(fullPath)))
+			a.True(IsFleetYamlSuffix(fullPath))
+		}
+	}
+
+	// Test expected failure payloads.
+	for _, fullPath := range []string{"fleet.yaaaaaaaaaml", "", ".", "weakmonkey.yaml", "../fleet.yaaaaml"} {
+		a.False(IsFleetYaml(filepath.Base(fullPath)))
+		a.False(IsFleetYamlSuffix(fullPath))
+	}
+}