From 9e70a16b5510a71968c8e2a9b4579a1c580e4dd8 Mon Sep 17 00:00:00 2001 From: dgghinea-axway Date: Tue, 8 Oct 2024 11:22:00 +0300 Subject: [PATCH 1/5] APIGOV-28932 - remove jfrog call and use agentstate --- pkg/cmd/agentversionjob.go | 221 ++++++++----------------------------- 1 file changed, 43 insertions(+), 178 deletions(-) diff --git a/pkg/cmd/agentversionjob.go b/pkg/cmd/agentversionjob.go index 71807421b..fbcf3c545 100644 --- a/pkg/cmd/agentversionjob.go +++ b/pkg/cmd/agentversionjob.go @@ -1,18 +1,17 @@ package cmd import ( - "encoding/json" + "fmt" + "github.com/Axway/agent-sdk/pkg/agent" + "github.com/Axway/agent-sdk/pkg/agent/resource" + management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" "github.com/Axway/agent-sdk/pkg/config" "github.com/Axway/agent-sdk/pkg/util" "regexp" - "strconv" "strings" - "net/http" - - coreapi "github.com/Axway/agent-sdk/pkg/api" "github.com/Axway/agent-sdk/pkg/jobs" "github.com/Axway/agent-sdk/pkg/util/errors" log "github.com/Axway/agent-sdk/pkg/util/log" @@ -20,56 +19,13 @@ import ( const ( avcCronSchedule = "@daily" - jfrogURL = "https://axway.jfrog.io/ui/api/v1/ui/treebrowser" ) -var agentNameToRepoPath = map[string]string{ - "AWSDiscoveryAgent": "aws-apigw-discovery-agent", - "AWSTraceabilityAgent": "aws-apigw-traceability-agent", - "AzureDiscoveryAgent": "azure-discovery-agent", - "AzureTraceabilityAgent": "azure-traceability-agent", - "EnterpriseEdgeGatewayDiscoveryAgent": "v7-discovery-agent", - "EnterpriseEdgeGatewayTraceabilityAgent": "v7-traceability-agent", -} - -type version struct { - major, minor, patch int - val string -} - -type jfrogRequest struct { - Type string `json:"type"` - RepoType string `json:"repoType"` - RepoKey string `json:"repoKey"` - Path string `json:"path"` - Text string `json:"text"` -} - -type jfrogData struct { - Items []jfrogItem `json:"data"` -} - -type jfrogItem struct { - RepoKey string `json:"repoKey,omitempty"` - Path string `json:"path,omitempty"` - Version string `json:"text"` - RepoType string `json:"repoType,omitempty"` - HasChild bool `json:"hasChild,omitempty"` - Local bool `json:"local,omitempty"` - Type string `json:"type,omitempty"` - Compacted bool `json:"compacted,omitempty"` - Cached bool `json:"cached,omitempty"` - Trash bool `json:"trash,omitempty"` - Distribution bool `json:"distribution,omitempty"` -} - // AgentVersionCheckJob - polls for agent versions type AgentVersionCheckJob struct { jobs.Job - apiClient coreapi.Client - requestBytes []byte buildVersion string - headers map[string]string + manager resource.Manager } // NewAgentVersionCheckJob - creates a new agent version check job structure @@ -77,42 +33,17 @@ func NewAgentVersionCheckJob(cfg config.CentralConfig) (*AgentVersionCheckJob, e // get current build version buildVersion, err := getBuildVersion() if err != nil { - log.Trace(err) - return nil, err - } - - if _, found := agentNameToRepoPath[BuildAgentName]; !found { - err := errors.ErrStartingVersionChecker.FormatError("empty or generic data plane type name") - log.Trace(err) return nil, err } - // create the request body for each check - requestBody := jfrogRequest{ - Type: "junction", - RepoType: "virtual", - RepoKey: "ampc-public-docker-release", - Path: "agent/" + agentNameToRepoPath[BuildAgentName], - Text: agentNameToRepoPath[BuildAgentName], - } - requestBytes, err := json.Marshal(requestBody) - if err != nil { - log.Trace(err) - return nil, err + manager := agent.GetAgentResourceManager() + if manager == nil { + return nil, errors.ErrStartingVersionChecker.FormatError("could not get the agent resource manager") } return &AgentVersionCheckJob{ - apiClient: coreapi.NewClient(cfg.GetTLSConfig(), cfg.GetProxyURL(), - coreapi.WithTimeout(cfg.GetClientTimeout()), - coreapi.WithSingleURL()), + manager: manager, buildVersion: buildVersion, - requestBytes: requestBytes, - headers: map[string]string{ - "X-Requested-With": "XMLHttpRequest", - "Host": "axway.jfrog.io", - "Content-Length": strconv.Itoa(len(requestBytes)), - "Content-Type": "application/json", - }, }, nil } @@ -128,44 +59,51 @@ func (avj *AgentVersionCheckJob) Status() error { // Execute - run agent version check job one time func (avj *AgentVersionCheckJob) Execute() error { - err := avj.getJFrogVersions() + state, err := avj.getAgentState() if err != nil { log.Trace(err) - // Could not get update from jfrog. Warn that we could not determine version and continue processing - log.Warn("Agent cannot determine the next available release. Be aware that your agent could be outdated.") - } else { - // Successfully got jfrog version. Now compare build to latest version - if isVersionStringOlder(avj.buildVersion, config.AgentLatestVersion) { - log.Warnf("New version available. Please consider upgrading from version %s to version %s", avj.buildVersion, config.AgentLatestVersion) - } + // Could not get update from agent state. Warn that we could not determine version and continue processing + log.Warn("Agent cannot determine the current available release. Be aware that your agent could be outdated.") + } + + switch state { + case "available": + log.Warn("Please be aware that there is a newer agent version available") + case "outdated": + log.Error("current agent version is no longer supported. We strongly advise to update the agent as soon as possible.") + case "retracted": + log.Error("current agent version has a known issue, please update the agent immediately.") } return nil } -// getJFrogVersions - obtaining the versions from JFrog website -// **Note** polling the jfrog website is the current solution to obtaining the list of versions -// In the future, adding a (Generic) resource for grouping versions together under the same scope is a possible solution -// ie: a new unscoped resource that represents the platform services, so that other products can plug in their releases. -func (avj *AgentVersionCheckJob) getJFrogVersions() error { - request := coreapi.Request{ - Method: http.MethodPost, - URL: jfrogURL, - Headers: avj.headers, - Body: avj.requestBytes, +func (avj *AgentVersionCheckJob) getAgentState() (string, error) { + agentRes := avj.manager.GetAgentResource() + if agentRes == nil { + return "", fmt.Errorf("could not get the agent resource") } - response, err := avj.apiClient.Send(request) - if err != nil { - return err + + // The kind should be only DA or TA + subResKey := management.DiscoveryAgentAgentstateSubResourceName + if agentRes.GetGroupVersionKind().Kind == "TraceabilityAgent" { + subResKey = management.DiscoveryAgentAgentstateSubResourceName } - jfrogResponse := jfrogData{} - err = json.Unmarshal(response.Body, &jfrogResponse) - if err != nil { - return err + err := fmt.Errorf("could not find the agentstate from agent subresource") + // This can happen at the first time the job executes, in which the resource has no agentState set beforehand + agentStateIface := agentRes.GetSubResource(subResKey) + if agentStateIface == nil { + return "", err } - config.AgentLatestVersion = avj.getLatestVersionFromJFrog(jfrogResponse.Items) - return nil + if agentState, ok := agentStateIface.(map[string]interface{}); ok { + if state, ok := agentState["update"]; ok { + if update, ok := state.(string); ok { + return update, nil + } + } + } + return "", err } func getBuildVersion() (string, error) { @@ -180,79 +118,6 @@ func getBuildVersion() (string, error) { return versionNoSHA, nil } -// isVersionStringOlder - return true if version of str1 is older than str2 -func isVersionStringOlder(build string, latest string) bool { - vB := getSemVer(build) - vL := getSemVer(latest) - - return isVersionSmaller(vB, vL) -} - -// isVersionSmaller - return true if version1 smaller than version2 -func isVersionSmaller(v1 version, v2 version) bool { - if v1.major < v2.major { - return true - } - if v1.major == v2.major { - if v1.minor < v2.minor { - return true - } - if v1.minor == v2.minor && v1.patch < v2.patch { - return true - } - } - return false -} - -func (avj *AgentVersionCheckJob) getLatestVersionFromJFrog(jfrogItems []jfrogItem) string { - tempMaxVersion := version{ - major: 0, - minor: 0, - patch: 0, - val: "", - } - re := regexp.MustCompile(`\d{8}`) - - for _, item := range jfrogItems { - //trimming version from jfrog webpage - if item.Version != "latest" && item.Version != "" { - v := getSemVer(item.Version) - // avoid a version with an 8 digit date as the patch number: 1.0.20210421 - if !re.MatchString(strconv.Itoa(v.patch)) && isVersionSmaller(tempMaxVersion, v) { - copyVersionStruct(&tempMaxVersion, v) - } - } - } - return tempMaxVersion.val -} - -// getSemVer - getting a semantic version struct from version string -// pre-req is that string is already in semantic versioning with major, minor, and patch -func getSemVer(str string) version { - s := strings.Split(str, ".") - maj, err := strconv.Atoi(s[0]) - min, err2 := strconv.Atoi(s[1]) - pat, err3 := strconv.Atoi(s[2]) - if err == nil && err2 == nil && err3 == nil { - v := version{ - major: maj, - minor: min, - patch: pat, - val: str, - } - return v - } - return version{} -} - -// copyVersionStruct - copying version2 into version1 struct by value -func copyVersionStruct(v1 *version, v2 version) { - v1.major = v2.major - v1.minor = v2.minor - v1.patch = v2.patch - v1.val = v2.val -} - // startVersionCheckJobs - starts both a single run and continuous checks func startVersionCheckJobs(cfg config.CentralConfig, agentFeaturesCfg config.AgentFeaturesConfig) { if !util.IsNotTest() || !agentFeaturesCfg.VersionCheckerEnabled() { From 5f8f6a8663af2961325909f7a1239bc2e136024f Mon Sep 17 00:00:00 2001 From: dgghinea-axway Date: Tue, 8 Oct 2024 16:01:27 +0300 Subject: [PATCH 2/5] MR issue --- pkg/cmd/agentversionjob.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cmd/agentversionjob.go b/pkg/cmd/agentversionjob.go index fbcf3c545..1edbe6cce 100644 --- a/pkg/cmd/agentversionjob.go +++ b/pkg/cmd/agentversionjob.go @@ -86,7 +86,7 @@ func (avj *AgentVersionCheckJob) getAgentState() (string, error) { // The kind should be only DA or TA subResKey := management.DiscoveryAgentAgentstateSubResourceName if agentRes.GetGroupVersionKind().Kind == "TraceabilityAgent" { - subResKey = management.DiscoveryAgentAgentstateSubResourceName + subResKey = management.TraceabilityAgentAgentstateSubResourceName } err := fmt.Errorf("could not find the agentstate from agent subresource") From a7813afd6b55d22c2a8e443977a7fcc555464c69 Mon Sep 17 00:00:00 2001 From: dgghinea-axway Date: Wed, 9 Oct 2024 13:56:31 +0300 Subject: [PATCH 3/5] MR issues --- pkg/cmd/agentversionjob.go | 71 +++++++++++++------------------------- 1 file changed, 24 insertions(+), 47 deletions(-) diff --git a/pkg/cmd/agentversionjob.go b/pkg/cmd/agentversionjob.go index 1edbe6cce..f48805c34 100644 --- a/pkg/cmd/agentversionjob.go +++ b/pkg/cmd/agentversionjob.go @@ -9,9 +9,6 @@ import ( "github.com/Axway/agent-sdk/pkg/config" "github.com/Axway/agent-sdk/pkg/util" - "regexp" - "strings" - "github.com/Axway/agent-sdk/pkg/jobs" "github.com/Axway/agent-sdk/pkg/util/errors" log "github.com/Axway/agent-sdk/pkg/util/log" @@ -24,26 +21,22 @@ const ( // AgentVersionCheckJob - polls for agent versions type AgentVersionCheckJob struct { jobs.Job - buildVersion string - manager resource.Manager + logger log.FieldLogger + manager resource.Manager } // NewAgentVersionCheckJob - creates a new agent version check job structure func NewAgentVersionCheckJob(cfg config.CentralConfig) (*AgentVersionCheckJob, error) { - // get current build version - buildVersion, err := getBuildVersion() - if err != nil { - return nil, err - } - manager := agent.GetAgentResourceManager() if manager == nil { return nil, errors.ErrStartingVersionChecker.FormatError("could not get the agent resource manager") } return &AgentVersionCheckJob{ - manager: manager, - buildVersion: buildVersion, + manager: manager, + logger: log.NewFieldLogger(). + WithPackage("sdk.cmd"). + WithComponent("agentVersionJob"), }, nil } @@ -61,14 +54,15 @@ func (avj *AgentVersionCheckJob) Status() error { func (avj *AgentVersionCheckJob) Execute() error { state, err := avj.getAgentState() if err != nil { - log.Trace(err) - // Could not get update from agent state. Warn that we could not determine version and continue processing - log.Warn("Agent cannot determine the current available release. Be aware that your agent could be outdated.") + avj.logger.WithError(err).Warn("agent cannot determine the current available release. Be aware that your agent could be outdated.") + return nil } switch state { + case "current": + log.Trace("agent is up to date.") case "available": - log.Warn("Please be aware that there is a newer agent version available") + log.Warn("please be aware that there is a newer agent version available.") case "outdated": log.Error("current agent version is no longer supported. We strongly advise to update the agent as soon as possible.") case "retracted": @@ -83,39 +77,22 @@ func (avj *AgentVersionCheckJob) getAgentState() (string, error) { return "", fmt.Errorf("could not get the agent resource") } - // The kind should be only DA or TA - subResKey := management.DiscoveryAgentAgentstateSubResourceName - if agentRes.GetGroupVersionKind().Kind == "TraceabilityAgent" { - subResKey = management.TraceabilityAgentAgentstateSubResourceName - } - - err := fmt.Errorf("could not find the agentstate from agent subresource") - // This can happen at the first time the job executes, in which the resource has no agentState set beforehand - agentStateIface := agentRes.GetSubResource(subResKey) - if agentStateIface == nil { - return "", err - } - - if agentState, ok := agentStateIface.(map[string]interface{}); ok { - if state, ok := agentState["update"]; ok { - if update, ok := state.(string); ok { - return update, nil - } + switch agentRes.GetGroupVersionKind().Kind { + case "TraceabilityAgent": + ta := management.NewTraceabilityAgent("", "") + if err := ta.FromInstance(agentRes); err != nil { + return "", fmt.Errorf("could not convert resource instance to TraceabilityAgent resource") + } + return ta.Agentstate.Update, nil + case "DiscoveryAgent": + da := management.NewDiscoveryAgent("", "") + if err := da.FromInstance(agentRes); err != nil { + return "", fmt.Errorf("could not convert resource instance to DiscoveryAgent resource") } + return da.Agentstate.Update, nil } - return "", err -} - -func getBuildVersion() (string, error) { - //remove -SHA from build version - versionNoSHA := strings.Split(BuildVersion, "-")[0] - //regex check for semantic versioning - semVerRegexp := regexp.MustCompile(`\d.\d.\d`) - if versionNoSHA == "" || !semVerRegexp.MatchString(versionNoSHA) { - return "", errors.ErrStartingVersionChecker.FormatError("build version is missing or of noncompliant semantic versioning") - } - return versionNoSHA, nil + return "", fmt.Errorf("agent resource is neither Discovery nor Traceability") } // startVersionCheckJobs - starts both a single run and continuous checks From c66052934ad0680a7c398dd450fe687db7733995 Mon Sep 17 00:00:00 2001 From: dgghinea-axway Date: Wed, 9 Oct 2024 13:58:15 +0300 Subject: [PATCH 4/5] use logger from agentVersionCheck struct --- pkg/cmd/agentversionjob.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/cmd/agentversionjob.go b/pkg/cmd/agentversionjob.go index f48805c34..8f8d376ab 100644 --- a/pkg/cmd/agentversionjob.go +++ b/pkg/cmd/agentversionjob.go @@ -60,13 +60,13 @@ func (avj *AgentVersionCheckJob) Execute() error { switch state { case "current": - log.Trace("agent is up to date.") + avj.logger.Trace("agent is up to date.") case "available": - log.Warn("please be aware that there is a newer agent version available.") + avj.logger.Warn("please be aware that there is a newer agent version available.") case "outdated": - log.Error("current agent version is no longer supported. We strongly advise to update the agent as soon as possible.") + avj.logger.Error("current agent version is no longer supported. We strongly advise to update the agent as soon as possible.") case "retracted": - log.Error("current agent version has a known issue, please update the agent immediately.") + avj.logger.Error("current agent version has a known issue, please update the agent immediately.") } return nil } From 16ebc2faf7c6c91d7b44151e5b1b44d1acf1aa81 Mon Sep 17 00:00:00 2001 From: dgghinea-axway Date: Wed, 23 Oct 2024 16:48:57 +0300 Subject: [PATCH 5/5] MR issue --- pkg/cmd/agentversionjob.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pkg/cmd/agentversionjob.go b/pkg/cmd/agentversionjob.go index 8f8d376ab..f0bf837a6 100644 --- a/pkg/cmd/agentversionjob.go +++ b/pkg/cmd/agentversionjob.go @@ -16,6 +16,11 @@ import ( const ( avcCronSchedule = "@daily" + + agentStateCurrent = "current" + agentStateAvailable = "available" + agentStateOutdated = "outdated" + agentStateRetracted = "retracted" ) // AgentVersionCheckJob - polls for agent versions @@ -59,13 +64,13 @@ func (avj *AgentVersionCheckJob) Execute() error { } switch state { - case "current": + case agentStateCurrent: avj.logger.Trace("agent is up to date.") - case "available": + case agentStateAvailable: avj.logger.Warn("please be aware that there is a newer agent version available.") - case "outdated": + case agentStateOutdated: avj.logger.Error("current agent version is no longer supported. We strongly advise to update the agent as soon as possible.") - case "retracted": + case agentStateRetracted: avj.logger.Error("current agent version has a known issue, please update the agent immediately.") } return nil