From 9eb311000b869ef1f6cf3bdc68d2a78ed23904ef Mon Sep 17 00:00:00 2001 From: Sibasish Behera Date: Sat, 18 Feb 2023 15:20:35 +0530 Subject: [PATCH 1/2] updated karmor version to give info on any mandatory release Signed-off-by: Sibasish Behera --- selfupdate/selfupdate.go | 6 +-- version/version.go | 95 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 4 deletions(-) diff --git a/selfupdate/selfupdate.go b/selfupdate/selfupdate.go index 6c95671f..ee3d7a72 100644 --- a/selfupdate/selfupdate.go +++ b/selfupdate/selfupdate.go @@ -25,7 +25,7 @@ var BuildDate string const ghrepo = "kubearmor/kubearmor-client" -func isValidVersion(ver string) bool { +func IsValidVersion(ver string) bool { _, err := semver.Make(ver) return err == nil } @@ -59,7 +59,7 @@ func getLatest() (*selfupdate.Release, error) { // IsLatest - check if the current binary is the latest func IsLatest(curver string) (bool, string) { - if curver != "" && !isValidVersion(curver) { + if curver != "" && !IsValidVersion(curver) { return true, "" } latest, err := getLatest() @@ -110,7 +110,7 @@ func doSelfUpdate(curver string) error { func SelfUpdate(c *k8s.Client) error { var ver = GitSummary fmt.Printf("current karmor version %s\n", ver) - if !isValidVersion(ver) { + if !IsValidVersion(ver) { fmt.Println("version does not match the pattern. Maybe using a locally built karmor!") if !ConfirmUserAction("Do you want to update it?") { return nil diff --git a/version/version.go b/version/version.go index 72ab76ee..d1290541 100644 --- a/version/version.go +++ b/version/version.go @@ -8,8 +8,11 @@ import ( "context" "fmt" "runtime" + "strings" + "github.com/blang/semver" "github.com/fatih/color" + "github.com/google/go-github/github" "github.com/kubearmor/kubearmor-client/k8s" "github.com/kubearmor/kubearmor-client/selfupdate" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -18,11 +21,17 @@ import ( // PrintVersion handler for karmor version func PrintVersion(c *k8s.Client) error { fmt.Printf("karmor version %s %s/%s BuildDate=%s\n", selfupdate.GitSummary, runtime.GOOS, runtime.GOARCH, selfupdate.BuildDate) - latest, latestVer := selfupdate.IsLatest(selfupdate.GitSummary) + curver := selfupdate.GitSummary + latest, latestVer := selfupdate.IsLatest(curver) if !latest { color.HiMagenta("update available version " + latestVer) color.HiMagenta("use [karmor selfupdate] to update to latest") } + + mandatory, mandatoryVer := isLatestMandatory(curver) + if !mandatory { + color.HiMagenta("mandatory update available %s\n", mandatoryVer) + } kubearmorVersion, err := getKubeArmorVersion(c) if err != nil { return nil @@ -35,6 +44,90 @@ func PrintVersion(c *k8s.Client) error { return nil } +func isLatestMandatory(curver string) (bool, string) { + if curver != "" && !selfupdate.IsValidVersion(curver) { + return true, "" + } + + latestMandatoryRelease, err := GetLatestMandatoryRelease(curver) + if err != nil { + fmt.Println("Failed to get info on mandatory release") + return true, "" + } + + if latestMandatoryRelease == nil { + fmt.Println("No mandatory release found") + return true, "" + } + + latestMandatory, err := semver.ParseTolerant(*latestMandatoryRelease.TagName) + if err != nil { + return true, "" + } + return false, latestMandatory.String() +} + +// GetLatestMandatoryRelease finds the latest mandatory release in the given repository +// with a version greater than or equal to the given current version (in string format). +// If no such release is found, it returns an empty string and a nil error. +func GetLatestMandatoryRelease(curver string) (*github.RepositoryRelease, error) { + releases, err := FetchReleases() + if err != nil { + return nil, err + } + + var latestMandatoryRelease *github.RepositoryRelease + var latestMandatoryReleaseVer *semver.Version + + for _, release := range releases { + if strings.Contains(*release.Body, "mandatory") || strings.Contains(*release.Body, "MANDATORY") { + // parse the version string of the release + releaseVer, err := semver.ParseTolerant(*release.TagName) + + if err != nil { + // skip the release if the version string is invalid + continue + } + + // initialize the latest mandatory release version and release if they are nil + if latestMandatoryRelease == nil || latestMandatoryReleaseVer == nil { + latestMandatoryRelease = release + latestMandatoryReleaseVer = &releaseVer + continue + } + + // check if the release version is greater than or equal to the current version + if curver != "" && releaseVer.GTE(semver.MustParse(curver)) && releaseVer.GT(*latestMandatoryReleaseVer) { + latestMandatoryRelease = release + latestMandatoryReleaseVer = &releaseVer + } + } + } + + if latestMandatoryRelease == nil { + return nil, nil + } + + return latestMandatoryRelease, nil +} + +// FetchReleases fetches the list of all releases in the given repository. +func FetchReleases() ([]*github.RepositoryRelease, error) { + client := github.NewClient(nil) + releases, _, err := client.Repositories.ListReleases(context.Background(), + "kubearmor", + "kubearmor-client", + &github.ListOptions{ + Page: 1, + PerPage: 100, + }, + ) + if err != nil { + return nil, fmt.Errorf("error fetching releases from GitHub: %v", err) + } + return releases, nil +} + func getKubeArmorVersion(c *k8s.Client) (string, error) { pods, err := c.K8sClientset.CoreV1().Pods("kube-system").List(context.Background(), metav1.ListOptions{LabelSelector: "kubearmor-app=kubearmor"}) if err != nil { From 35de855bfc61af90872c6d331ebd055091ef2f35 Mon Sep 17 00:00:00 2001 From: Sibasish Behera Date: Sat, 18 Feb 2023 15:49:14 +0530 Subject: [PATCH 2/2] fix: add comment for linting issues in selfupdate package Signed-off-by: Sibasish Behera --- selfupdate/selfupdate.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selfupdate/selfupdate.go b/selfupdate/selfupdate.go index ee3d7a72..a8176436 100644 --- a/selfupdate/selfupdate.go +++ b/selfupdate/selfupdate.go @@ -25,6 +25,8 @@ var BuildDate string const ghrepo = "kubearmor/kubearmor-client" +// IsValidVersion checks if a given string is a valid semantic version. +// Returns true if the string is a valid semantic version, false otherwise. func IsValidVersion(ver string) bool { _, err := semver.Make(ver) return err == nil