Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

APIGOV-26853 - conditionally remove ta resource on shutdown #59

Merged
merged 4 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
29 changes: 29 additions & 0 deletions pkg/traceability/beater/beater.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"fmt"
"io"
"net/http"
"os"
"sync"

"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/common"
"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"
Expand Down Expand Up @@ -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.
Expand Down
95 changes: 95 additions & 0 deletions pkg/traceability/beater/beater_test.go
Original file line number Diff line number Diff line change
@@ -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)
})
}
}