mirror of https://github.com/linkerd/linkerd2.git
142 lines
3.8 KiB
Go
142 lines
3.8 KiB
Go
package version
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
healthcheckPb "github.com/runconduit/conduit/controller/gen/common/healthcheck"
|
|
pb "github.com/runconduit/conduit/controller/gen/public"
|
|
"github.com/runconduit/conduit/pkg/healthcheck"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// DO NOT EDIT
|
|
// This var is updated automatically as part of the build process
|
|
var Version = "undefined"
|
|
|
|
const (
|
|
VersionSubsystemName = "conduit-version"
|
|
CliCheckDescription = "cli is up-to-date"
|
|
ControlPlaneCheckDescription = "control plane is up-to-date"
|
|
)
|
|
|
|
func VersionFlag() *bool {
|
|
return flag.Bool("version", false, "print version and exit")
|
|
}
|
|
|
|
func MaybePrintVersionAndExit(printVersion bool) {
|
|
if printVersion {
|
|
fmt.Println(Version)
|
|
os.Exit(0)
|
|
}
|
|
log.Infof("running conduit version %s", Version)
|
|
}
|
|
|
|
var httpClientTimeout = 10 * time.Second
|
|
|
|
type versionStatusChecker struct {
|
|
version string
|
|
versionCheckURL string
|
|
versionOverride string
|
|
publicApiClient pb.ApiClient
|
|
httpClient http.Client
|
|
}
|
|
|
|
func (v versionStatusChecker) SelfCheck() []*healthcheckPb.CheckResult {
|
|
cliVersion := v.version
|
|
cliIsUpToDate := &healthcheckPb.CheckResult{
|
|
Status: healthcheckPb.CheckStatus_OK,
|
|
SubsystemName: VersionSubsystemName,
|
|
CheckDescription: CliCheckDescription,
|
|
}
|
|
|
|
latestVersion, err := v.getLatestVersion()
|
|
if err != nil {
|
|
cliIsUpToDate.Status = healthcheckPb.CheckStatus_ERROR
|
|
cliIsUpToDate.FriendlyMessageToUser = err.Error()
|
|
return []*healthcheckPb.CheckResult{cliIsUpToDate}
|
|
}
|
|
if cliVersion != latestVersion {
|
|
cliIsUpToDate.Status = healthcheckPb.CheckStatus_FAIL
|
|
cliIsUpToDate.FriendlyMessageToUser = fmt.Sprintf("is running version %s but the latest version is %s", cliVersion, latestVersion)
|
|
}
|
|
|
|
controlPlaneIsUpToDate := &healthcheckPb.CheckResult{
|
|
Status: healthcheckPb.CheckStatus_OK,
|
|
SubsystemName: VersionSubsystemName,
|
|
CheckDescription: ControlPlaneCheckDescription,
|
|
}
|
|
|
|
controlPlaneVersion, err := v.getServerVersion()
|
|
if err != nil {
|
|
controlPlaneIsUpToDate.Status = healthcheckPb.CheckStatus_ERROR
|
|
controlPlaneIsUpToDate.FriendlyMessageToUser = err.Error()
|
|
return []*healthcheckPb.CheckResult{controlPlaneIsUpToDate}
|
|
}
|
|
if controlPlaneVersion != latestVersion {
|
|
controlPlaneIsUpToDate.Status = healthcheckPb.CheckStatus_FAIL
|
|
controlPlaneIsUpToDate.FriendlyMessageToUser = fmt.Sprintf("is running version %s but the latest version is %s", controlPlaneVersion, latestVersion)
|
|
}
|
|
|
|
checks := []*healthcheckPb.CheckResult{cliIsUpToDate}
|
|
checks = append(checks, controlPlaneIsUpToDate)
|
|
return checks
|
|
}
|
|
|
|
func (v versionStatusChecker) getServerVersion() (string, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
resp, err := v.publicApiClient.Version(ctx, &pb.Empty{})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return resp.GetReleaseVersion(), nil
|
|
}
|
|
|
|
func (v versionStatusChecker) getLatestVersion() (string, error) {
|
|
if v.versionOverride != "" {
|
|
return v.versionOverride, nil
|
|
}
|
|
|
|
resp, err := v.httpClient.Get(v.versionCheckURL)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 {
|
|
return "", fmt.Errorf("got %d error from %s", resp.StatusCode, v.versionCheckURL)
|
|
}
|
|
|
|
bodyBytes, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var l map[string]string
|
|
err = json.Unmarshal(bodyBytes, &l)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return l["version"], nil
|
|
}
|
|
|
|
func NewVersionStatusChecker(versionCheckURL, versionOverride string, client pb.ApiClient) healthcheck.StatusChecker {
|
|
return versionStatusChecker{
|
|
version: Version,
|
|
versionCheckURL: versionCheckURL,
|
|
versionOverride: versionOverride,
|
|
publicApiClient: client,
|
|
httpClient: http.Client{Timeout: httpClientTimeout},
|
|
}
|
|
}
|