mirror of
https://github.com/kubescape/kubescape.git
synced 2026-02-14 18:09:55 +00:00
Added the update command for kubescape
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/kubescape/kubescape/v2/cmd/list"
|
||||
"github.com/kubescape/kubescape/v2/cmd/scan"
|
||||
"github.com/kubescape/kubescape/v2/cmd/submit"
|
||||
"github.com/kubescape/kubescape/v2/cmd/update"
|
||||
"github.com/kubescape/kubescape/v2/cmd/version"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils/getter"
|
||||
@@ -64,8 +65,8 @@ func getRootCmd(ks meta.IKubescape) *cobra.Command {
|
||||
rootCmd.PersistentFlags().StringVar(&rootInfo.CacheDir, "cache-dir", getter.DefaultLocalStore, "Cache directory [$KS_CACHE_DIR]")
|
||||
rootCmd.PersistentFlags().BoolVarP(&rootInfo.DisableColor, "disable-color", "", false, "Disable Color output for logging")
|
||||
rootCmd.PersistentFlags().BoolVarP(&rootInfo.EnableColor, "enable-color", "", false, "Force enable Color output for logging")
|
||||
rootCmd.PersistentFlags().StringVar(&rootInfo.KubeConfig, "kubeconfig", "", "newflag")//kubeconfig flag added
|
||||
//TODO flag functionality should be added further
|
||||
rootCmd.PersistentFlags().StringVar(&rootInfo.KubeConfig, "kubeconfig", "", "newflag") //kubeconfig flag added
|
||||
//TODO flag functionality should be added further
|
||||
|
||||
cobra.OnInitialize(initLogger, initLoggerLevel, initEnvironment, initCacheDir)
|
||||
|
||||
@@ -78,6 +79,7 @@ func getRootCmd(ks meta.IKubescape) *cobra.Command {
|
||||
rootCmd.AddCommand(completion.GetCompletionCmd())
|
||||
rootCmd.AddCommand(version.GetVersionCmd())
|
||||
rootCmd.AddCommand(config.GetConfigCmd(ks))
|
||||
rootCmd.AddCommand(update.GetUpdateCmd())
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
|
||||
64
cmd/update/update.go
Normal file
64
cmd/update/update.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package update
|
||||
|
||||
//This update command takes one argument for the type of OS installed(linux/windows/macos)
|
||||
//and updates to the latest kubescape release.
|
||||
//Examples:-
|
||||
// kubescape update linux
|
||||
// kubescape update windows
|
||||
// kubescape update macos
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/kubescape/kubescape/v2/core/cautils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func GetUpdateCmd() *cobra.Command {
|
||||
updateCmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Short: "Update your version",
|
||||
Long: ``,
|
||||
Args: cobra.ExactValidArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
vu := cautils.NewIVersionCheckHandlerU()
|
||||
vu.CheckLatestVersionU(cautils.NewVersionCheckRequestU(cautils.BuildNumber, "", "", "version"))
|
||||
//Checking the user's version of kubescape to the latest release
|
||||
if cautils.BuildNumber == cautils.LatestReleaseVersion {
|
||||
//your version == latest version
|
||||
fmt.Println("You are in the latest version")
|
||||
} else {
|
||||
//execute the install.sh if linux, install.ps1 for windows,.....depending on your OS
|
||||
switch strings.ToLower(args[0]) {
|
||||
case "linux":
|
||||
//run the installation command for linux
|
||||
cmd, err := exec.Command("./install.sh").Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(cmd))
|
||||
case "windows":
|
||||
//run the installation command for windows
|
||||
cmd, err := exec.Command("./install.ps1").Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(cmd))
|
||||
|
||||
case "macos":
|
||||
//run the installation command for macOS
|
||||
cmd, err := exec.Command("./macinstall/kubescape.rb").Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(cmd))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return updateCmd
|
||||
}
|
||||
139
core/cautils/updateutils.go
Normal file
139
core/cautils/updateutils.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package cautils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/armosec/utils-go/boolutils"
|
||||
logger "github.com/kubescape/go-logger"
|
||||
"github.com/kubescape/go-logger/helpers"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils/getter"
|
||||
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
type IVersionCheckHandlerU interface {
|
||||
CheckLatestVersionU(*VersionCheckRequestU) error
|
||||
}
|
||||
|
||||
func NewIVersionCheckHandlerU() IVersionCheckHandlerU {
|
||||
if BuildNumber == "" {
|
||||
logger.L().Warning("unknown build number, this might affect your scan results. Please make sure you are updated to latest version")
|
||||
}
|
||||
if v, ok := os.LookupEnv(SKIP_VERSION_CHECK); ok && boolutils.StringToBool(v) {
|
||||
return NewVersionCheckHandlerMockU()
|
||||
} else if v, ok := os.LookupEnv(SKIP_VERSION_CHECK_DEPRECATED); ok && boolutils.StringToBool(v) {
|
||||
return NewVersionCheckHandlerMockU()
|
||||
}
|
||||
return NewVersionCheckHandlerU()
|
||||
}
|
||||
|
||||
type VersionCheckHandlerMockU struct {
|
||||
}
|
||||
|
||||
func NewVersionCheckHandlerMockU() *VersionCheckHandlerMockU {
|
||||
return &VersionCheckHandlerMockU{}
|
||||
}
|
||||
|
||||
type VersionCheckHandlerU struct {
|
||||
versionURL string
|
||||
}
|
||||
type VersionCheckRequestU struct {
|
||||
Client string `json:"client"` // kubescape
|
||||
ClientBuild string `json:"clientBuild"` // client build environment
|
||||
ClientVersion string `json:"clientVersion"` // kubescape version
|
||||
Framework string `json:"framework"` // framework name
|
||||
FrameworkVersion string `json:"frameworkVersion"` // framework version
|
||||
ScanningTarget string `json:"target"` // Deprecated
|
||||
ScanningContext string `json:"context"` // scanning context- cluster/file/gitURL/localGit/dir
|
||||
}
|
||||
|
||||
type VersionCheckResponseU struct {
|
||||
Client string `json:"client"` // kubescape
|
||||
ClientUpdate string `json:"clientUpdate"` // kubescape latest version
|
||||
Framework string `json:"framework"` // framework name
|
||||
FrameworkUpdate string `json:"frameworkUpdate"` // framework latest version
|
||||
Message string `json:"message"` // alert message
|
||||
}
|
||||
|
||||
func NewVersionCheckHandlerU() *VersionCheckHandlerU {
|
||||
return &VersionCheckHandlerU{
|
||||
versionURL: "https://us-central1-elated-pottery-310110.cloudfunctions.net/ksgf1v1",
|
||||
}
|
||||
}
|
||||
func NewVersionCheckRequestU(buildNumber, frameworkName, frameworkVersion, scanningTarget string) *VersionCheckRequestU {
|
||||
if buildNumber == "" {
|
||||
buildNumber = UnknownBuildNumber
|
||||
}
|
||||
if scanningTarget == "" {
|
||||
scanningTarget = "unknown"
|
||||
}
|
||||
if Client == "" {
|
||||
Client = "local-build"
|
||||
}
|
||||
return &VersionCheckRequestU{
|
||||
Client: "kubescape",
|
||||
ClientBuild: Client,
|
||||
ClientVersion: buildNumber,
|
||||
Framework: frameworkName,
|
||||
FrameworkVersion: frameworkVersion,
|
||||
ScanningTarget: scanningTarget,
|
||||
}
|
||||
}
|
||||
|
||||
func (v *VersionCheckHandlerMockU) CheckLatestVersionU(versionData *VersionCheckRequestU) error {
|
||||
logger.L().Info("Skipping version check")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *VersionCheckHandlerU) CheckLatestVersionU(versionData *VersionCheckRequestU) error {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logger.L().Warning("failed to get latest version", helpers.Interface("error", err))
|
||||
}
|
||||
}()
|
||||
|
||||
latestVersion, err := v.getLatestVersionU(versionData)
|
||||
if err != nil || latestVersion == nil {
|
||||
return fmt.Errorf("failed to get latest version")
|
||||
}
|
||||
|
||||
LatestReleaseVersion := latestVersion.ClientUpdate
|
||||
|
||||
if latestVersion.ClientUpdate != "" {
|
||||
if BuildNumber != "" && semver.Compare(BuildNumber, LatestReleaseVersion) == -1 {
|
||||
logger.L().Warning(warningMessage(LatestReleaseVersion))
|
||||
}
|
||||
}
|
||||
|
||||
if latestVersion.Message != "" {
|
||||
logger.L().Info(latestVersion.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *VersionCheckHandlerU) getLatestVersionU(versionData *VersionCheckRequestU) (*VersionCheckResponseU, error) {
|
||||
|
||||
reqBody, err := json.Marshal(*versionData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in 'CheckLatestVersion' failed to json.Marshal, reason: %s", err.Error())
|
||||
}
|
||||
|
||||
resp, err := getter.HttpPost(http.DefaultClient, v.versionURL, map[string]string{"Content-Type": "application/json"}, reqBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vResp := &VersionCheckResponseU{}
|
||||
if err = getter.JSONDecoder(resp).Decode(vResp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return vResp, nil
|
||||
}
|
||||
|
||||
func warningMessageU(release string) string {
|
||||
return fmt.Sprintf("Updating your current version '%s' to the latest release: '%s' ...", BuildNumber, release)
|
||||
}
|
||||
@@ -19,6 +19,7 @@ const SKIP_VERSION_CHECK = "KS_SKIP_UPDATE_CHECK"
|
||||
|
||||
var BuildNumber string
|
||||
var Client string
|
||||
var LatestReleaseVersion string
|
||||
|
||||
const UnknownBuildNumber = "unknown"
|
||||
|
||||
@@ -108,9 +109,11 @@ func (v *VersionCheckHandler) CheckLatestVersion(versionData *VersionCheckReques
|
||||
return fmt.Errorf("failed to get latest version")
|
||||
}
|
||||
|
||||
LatestReleaseVersion := latestVersion.ClientUpdate
|
||||
|
||||
if latestVersion.ClientUpdate != "" {
|
||||
if BuildNumber != "" && semver.Compare(BuildNumber, latestVersion.ClientUpdate) == -1 {
|
||||
logger.L().Warning(warningMessage(latestVersion.ClientUpdate))
|
||||
if BuildNumber != "" && semver.Compare(BuildNumber, LatestReleaseVersion) == -1 {
|
||||
logger.L().Warning(warningMessage(LatestReleaseVersion))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user