diff --git a/cmd/flux/bootstrap.go b/cmd/flux/bootstrap.go index b81e3576..c23ffee5 100644 --- a/cmd/flux/bootstrap.go +++ b/cmd/flux/bootstrap.go @@ -126,6 +126,14 @@ func bootstrapValidate() error { } func generateInstallManifests(targetPath, namespace, tmpDir string, localManifests string) (string, error) { + if bootstrapArgs.version == install.MakeDefaultOptions().Version { + version, err := install.GetLatestVersion() + if err != nil { + return "", err + } + bootstrapArgs.version = version + } + opts := install.Options{ BaseURL: localManifests, Version: bootstrapArgs.version, diff --git a/cmd/flux/bootstrap_github.go b/cmd/flux/bootstrap_github.go index aeca46be..fca6a8ad 100644 --- a/cmd/flux/bootstrap_github.go +++ b/cmd/flux/bootstrap_github.go @@ -125,13 +125,25 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { return err } - usedPath, bootstrapPathDiffers := checkIfBootstrapPathDiffers(ctx, kubeClient, rootArgs.namespace, filepath.ToSlash(githubArgs.path.String())) + usedPath, bootstrapPathDiffers := checkIfBootstrapPathDiffers( + ctx, + kubeClient, + rootArgs.namespace, + filepath.ToSlash(githubArgs.path.String()), + ) if bootstrapPathDiffers { return fmt.Errorf("cluster already bootstrapped to %v path", usedPath) } - repository, err := git.NewRepository(githubArgs.repository, githubArgs.owner, githubArgs.hostname, ghToken, "flux", githubArgs.owner+"@users.noreply.github.com") + repository, err := git.NewRepository( + githubArgs.repository, + githubArgs.owner, + githubArgs.hostname, + ghToken, + "flux", + githubArgs.owner+"@users.noreply.github.com", + ) if err != nil { return err } @@ -190,13 +202,22 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { // generate install manifests logger.Generatef("generating manifests") - installManifest, err := generateInstallManifests(githubArgs.path.String(), rootArgs.namespace, tmpDir, bootstrapArgs.manifestsPath) + installManifest, err := generateInstallManifests( + githubArgs.path.String(), + rootArgs.namespace, + tmpDir, + bootstrapArgs.manifestsPath, + ) if err != nil { return err } // stage install manifests - changed, err = repository.Commit(ctx, path.Join(githubArgs.path.String(), rootArgs.namespace), "Add manifests") + changed, err = repository.Commit( + ctx, + path.Join(githubArgs.path.String(), rootArgs.namespace), + fmt.Sprintf("Add flux %s components manifests", bootstrapArgs.version), + ) if err != nil { return err } @@ -270,13 +291,25 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { // configure repo synchronization logger.Actionf("generating sync manifests") - syncManifests, err := generateSyncManifests(repoURL, bootstrapArgs.branch, rootArgs.namespace, rootArgs.namespace, filepath.ToSlash(githubArgs.path.String()), tmpDir, githubArgs.interval) + syncManifests, err := generateSyncManifests( + repoURL, + bootstrapArgs.branch, + rootArgs.namespace, + rootArgs.namespace, + filepath.ToSlash(githubArgs.path.String()), + tmpDir, + githubArgs.interval, + ) if err != nil { return err } // commit and push manifests - if changed, err = repository.Commit(ctx, path.Join(githubArgs.path.String(), rootArgs.namespace), "Add manifests"); err != nil { + if changed, err = repository.Commit( + ctx, + path.Join(githubArgs.path.String(), rootArgs.namespace), + fmt.Sprintf("Add flux %s sync manifests", bootstrapArgs.version), + ); err != nil { return err } else if changed { if err := repository.Push(ctx); err != nil { diff --git a/cmd/flux/bootstrap_gitlab.go b/cmd/flux/bootstrap_gitlab.go index d5f99d91..c4b2b43c 100644 --- a/cmd/flux/bootstrap_gitlab.go +++ b/cmd/flux/bootstrap_gitlab.go @@ -131,7 +131,14 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("cluster already bootstrapped to %v path", usedPath) } - repository, err := git.NewRepository(gitlabArgs.repository, gitlabArgs.owner, gitlabArgs.hostname, glToken, "flux", gitlabArgs.owner+"@users.noreply.gitlab.com") + repository, err := git.NewRepository( + gitlabArgs.repository, + gitlabArgs.owner, + gitlabArgs.hostname, + glToken, + "flux", + gitlabArgs.owner+"@users.noreply.gitlab.com", + ) if err != nil { return err } @@ -169,13 +176,22 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { // generate install manifests logger.Generatef("generating manifests") - installManifest, err := generateInstallManifests(gitlabArgs.path.String(), rootArgs.namespace, tmpDir, bootstrapArgs.manifestsPath) + installManifest, err := generateInstallManifests( + gitlabArgs.path.String(), + rootArgs.namespace, + tmpDir, + bootstrapArgs.manifestsPath, + ) if err != nil { return err } // stage install manifests - changed, err = repository.Commit(ctx, path.Join(gitlabArgs.path.String(), rootArgs.namespace), "Add manifests") + changed, err = repository.Commit( + ctx, + path.Join(gitlabArgs.path.String(), rootArgs.namespace), + fmt.Sprintf("Add flux %s components manifests", bootstrapArgs.version), + ) if err != nil { return err } @@ -249,13 +265,25 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { // configure repo synchronization logger.Actionf("generating sync manifests") - syncManifests, err := generateSyncManifests(repoURL, bootstrapArgs.branch, rootArgs.namespace, rootArgs.namespace, filepath.ToSlash(gitlabArgs.path.String()), tmpDir, gitlabArgs.interval) + syncManifests, err := generateSyncManifests( + repoURL, + bootstrapArgs.branch, + rootArgs.namespace, + rootArgs.namespace, + filepath.ToSlash(gitlabArgs.path.String()), + tmpDir, + gitlabArgs.interval, + ) if err != nil { return err } // commit and push manifests - if changed, err = repository.Commit(ctx, path.Join(gitlabArgs.path.String(), rootArgs.namespace), "Add manifests"); err != nil { + if changed, err = repository.Commit( + ctx, + path.Join(gitlabArgs.path.String(), rootArgs.namespace), + fmt.Sprintf("Add flux %s sync manifests", bootstrapArgs.version), + ); err != nil { return err } else if changed { if err := repository.Push(ctx); err != nil { diff --git a/cmd/flux/install.go b/cmd/flux/install.go index 5218055f..8bd02327 100644 --- a/cmd/flux/install.go +++ b/cmd/flux/install.go @@ -122,6 +122,13 @@ func installCmdRun(cmd *cobra.Command, args []string) error { return err } + if installVersion == install.MakeDefaultOptions().Version { + installVersion, err = install.GetLatestVersion() + if err != nil { + return err + } + } + opts := install.Options{ BaseURL: installManifestsPath, Version: installVersion, @@ -156,7 +163,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error { fmt.Print(manifest.Content) } else if installExport { fmt.Println("---") - fmt.Println("# GitOps Toolkit revision", installVersion) + fmt.Println("# Flux version:", installVersion) fmt.Println("# Components:", strings.Join(components, ",")) fmt.Print(manifest.Content) fmt.Println("---") diff --git a/pkg/manifestgen/install/install.go b/pkg/manifestgen/install/install.go index 06a516bf..feb83046 100644 --- a/pkg/manifestgen/install/install.go +++ b/pkg/manifestgen/install/install.go @@ -18,11 +18,14 @@ package install import ( "context" + "encoding/json" "fmt" "io/ioutil" + "net/http" "os" "path" "strings" + "time" securejoin "github.com/cyphar/filepath-securejoin" @@ -75,3 +78,29 @@ func Generate(options Options) (*manifestgen.Manifest, error) { Content: string(content), }, nil } + +// GetLatestVersion calls the GitHub API and returns the latest released version. +func GetLatestVersion() (string, error) { + ghURL := "https://api.github.com/repos/fluxcd/flux2/releases/latest" + c := http.DefaultClient + c.Timeout = 15 * time.Second + + res, err := c.Get(ghURL) + if err != nil { + return "", fmt.Errorf("calling GitHub API failed: %w", err) + } + + if res.Body != nil { + defer res.Body.Close() + } + + type meta struct { + Tag string `json:"tag_name"` + } + var m meta + if err := json.NewDecoder(res.Body).Decode(&m); err != nil { + return "", fmt.Errorf("decoding GitHub API response failed: %w", err) + } + + return m.Tag, err +}