diff --git a/go.mod b/go.mod index 6f7ef2d..6366126 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Axway/agents-kong go 1.18 require ( - github.com/Axway/agent-sdk v1.1.70 + github.com/Axway/agent-sdk v1.1.72-0.20240102220515-d0cc4b4fbc8e github.com/elastic/beats/v7 v7.17.15 github.com/google/uuid v1.3.1 github.com/kong/go-kong v0.47.0 diff --git a/go.sum b/go.sum index b18d359..7070369 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Axway/agent-sdk v1.1.70 h1:34QravPV19zkTp7tout7u7KX7XCXaO0OBOil17pRYSE= -github.com/Axway/agent-sdk v1.1.70/go.mod h1:Iuv9KlWksVTbTKdfs4bKVYMDc33ZTLYoHt572z2CbbI= +github.com/Axway/agent-sdk v1.1.72-0.20240102220515-d0cc4b4fbc8e h1:j2vkONYI4oS13kP0wRJp3hWi/Qqj8V0HYPkrGdwhaks= +github.com/Axway/agent-sdk v1.1.72-0.20240102220515-d0cc4b4fbc8e/go.mod h1:Iuv9KlWksVTbTKdfs4bKVYMDc33ZTLYoHt572z2CbbI= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= diff --git a/pkg/traceability/beater/beater.go b/pkg/traceability/beater/beater.go index 0584d44..750d257 100644 --- a/pkg/traceability/beater/beater.go +++ b/pkg/traceability/beater/beater.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net/http" + "os" "sync" "github.com/elastic/beats/v7/libbeat/beat" @@ -12,6 +13,7 @@ import ( "github.com/google/uuid" "github.com/Axway/agent-sdk/pkg/agent" + management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" "github.com/Axway/agent-sdk/pkg/transaction/metric" agentErrors "github.com/Axway/agent-sdk/pkg/util/errors" hc "github.com/Axway/agent-sdk/pkg/util/healthcheck" @@ -109,6 +111,33 @@ func (b *httpLogBeater) shutdownHandler() { // publish the metrics and usage b.logger.Info("publishing cached metrics and usage") metric.GetMetricCollector().ShutdownPublish() + + // clean the agent resource, if necessary + b.cleanResource() +} + +func (b *httpLogBeater) cleanResource() { + // if pod name is empty do nothing further + podName := os.Getenv("POD_NAME") + if podName == "" { + b.logger.Debug("not cleaning the agent resource, does not seem to be a kubernetes pod") + return + } + + // check if this agent resource reported an error + if agent.GetStatus() == agent.AgentFailed || agent.GetStatus() == agent.AgentUnhealthy { + b.logger.Debug("not cleaning the agent resource, agent not gracefully stopping") + return + } + + // check that this is not the last agent resource to be removed + agentRes := management.NewTraceabilityAgent(config.GetAgentConfig().CentralCfg.GetAgentName(), config.GetAgentConfig().CentralCfg.GetEnvironmentName()) + res, err := agent.GetCentralClient().GetResources(agentRes) + if len(res) > 1 && err == nil { + b.logger.Info("cleaning the agent resource") + // cleanup the agent resource + agent.GetCentralClient().DeleteResourceInstance(agentRes) + } } // Stop stops kong_traceability_agent. diff --git a/pkg/traceability/beater/beater_test.go b/pkg/traceability/beater/beater_test.go new file mode 100644 index 0000000..f9204f6 --- /dev/null +++ b/pkg/traceability/beater/beater_test.go @@ -0,0 +1,95 @@ +package beater + +import ( + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/Axway/agent-sdk/pkg/agent" + v1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1" + management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" + "github.com/Axway/agent-sdk/pkg/apic/mock" + corecfg "github.com/Axway/agent-sdk/pkg/config" + + "github.com/Axway/agents-kong/pkg/traceability/config" +) + +func Test_httpLogBeater_cleanResource(t *testing.T) { + testCases := map[string]struct { + podName string + agentStatus string + numTAs int + getResErr bool + expectGetCalled bool + expectDeleteCalled bool + }{ + "no pod name, nothing deleted": { + agentStatus: agent.AgentRunning, + }, + "agent in failed status, nothing deleted": { + podName: "pod", + agentStatus: agent.AgentFailed, + }, + "only one ta exists, nothing deleted": { + podName: "pod", + agentStatus: agent.AgentRunning, + numTAs: 1, + expectGetCalled: true, + }, + "error returned getting resources, nothing deleted": { + podName: "pod", + agentStatus: agent.AgentRunning, + numTAs: 2, + getResErr: true, + expectGetCalled: true, + }, + "all validations pass, delete agent res": { + podName: "pod", + agentStatus: agent.AgentRunning, + numTAs: 2, + expectGetCalled: true, + expectDeleteCalled: true, + }, + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + os.Setenv("POD_NAME", tc.podName) + config.SetAgentConfig(&config.AgentConfig{CentralCfg: &corecfg.CentralConfiguration{}}) + agent.UpdateStatus(tc.agentStatus, "") + + beater, err := New(nil, nil) + assert.Nil(t, err) + assert.NotNil(t, beater) + httpBeater := beater.(*httpLogBeater) + getResCalled := false + deleteResCalled := false + + mockAPICClient := &mock.Client{ + GetResourcesMock: func(ri v1.Interface) ([]v1.Interface, error) { + getResCalled = true + assert.NotNil(t, ri) + if tc.getResErr { + return nil, fmt.Errorf("error") + } + tas := []v1.Interface{} + for i := 0; i < tc.numTAs; i++ { + tas = append(tas, management.NewTraceabilityAgent("name", "env")) + } + return tas, nil + }, + DeleteResourceInstanceMock: func(ri v1.Interface) error { + deleteResCalled = true + assert.NotNil(t, ri) + return nil + }, + } + agent.InitializeForTest(mockAPICClient) + + httpBeater.cleanResource() + assert.Equal(t, tc.expectGetCalled, getResCalled) + assert.Equal(t, tc.expectDeleteCalled, deleteResCalled) + }) + } +}