diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml
index 80a84b6a..c2d299b9 100755
--- a/.github/workflows/build-and-test.yaml
+++ b/.github/workflows/build-and-test.yaml
@@ -13,7 +13,7 @@ on:
- cron: '0 19 * * 1-5'
env:
- DEFAULT_GO_VERSION: ^1.22.0
+ DEFAULT_GO_VERSION: ^1.25.0
GITHUB_USERNAME: ${{ secrets.EC2_BOT_GITHUB_USERNAME }}
GITHUB_TOKEN: ${{ secrets.EC2_BOT_GITHUB_TOKEN }}
WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
@@ -71,7 +71,7 @@ jobs:
cache: false
- name: Set up golangci-lint
- uses: golangci/golangci-lint-action@v3
+ uses: golangci/golangci-lint-action@v7
with:
version: latest
args: --timeout=5m
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index b760aa12..7c44bd87 100755
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -10,7 +10,7 @@ permissions:
id-token: write
env:
- DEFAULT_GO_VERSION: ^1.22.0
+ DEFAULT_GO_VERSION: ^1.25.0
GITHUB_USERNAME: ${{ secrets.EC2_BOT_GITHUB_USERNAME }}
GITHUB_TOKEN: ${{ secrets.EC2_BOT_GITHUB_TOKEN }}
WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
diff --git a/Dockerfile b/Dockerfile
index 7d879865..bc9f09dc 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM --platform=$BUILDPLATFORM golang:1.22 as builder
+FROM --platform=$BUILDPLATFORM golang:1.25 as builder
## GOLANG env
ARG GOPROXY="https://proxy.golang.org|direct"
diff --git a/Dockerfile.windows b/Dockerfile.windows
index 092eb04e..ad86ea36 100644
--- a/Dockerfile.windows
+++ b/Dockerfile.windows
@@ -1,7 +1,7 @@
ARG WINDOWS_VERSION=1809
# Build the manager binary
-FROM --platform=windows/amd64 golang:1.22 as builder
+FROM --platform=windows/amd64 golang:1.25 as builder
## GOLANG env
ENV GO111MODULE="on" CGO_ENABLED="0" GOOS="windows" GOARCH="amd64"
diff --git a/README.md b/README.md
index 64b03109..fb4aee51 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
-
+
diff --git a/cmd/node-termination-handler.go b/cmd/node-termination-handler.go
index edbd1672..01626894 100644
--- a/cmd/node-termination-handler.go
+++ b/cmd/node-termination-handler.go
@@ -279,11 +279,12 @@ func main() {
asgLaunchHandler := launch.New(interruptionEventStore, *node, nthConfig, metrics, recorder, clientset)
drainCordonHander := draincordon.New(interruptionEventStore, *node, nthConfig, nodeMetadata, metrics, recorder)
+InterruptionLoop:
for range time.NewTicker(1 * time.Second).C {
select {
case <-signalChan:
// Exit interruption loop if a SIGTERM is received or the channel is closed
- break
+ break InterruptionLoop
default:
EventLoop:
for event, ok := interruptionEventStore.GetActiveEvent(); ok; event, ok = interruptionEventStore.GetActiveEvent() {
@@ -320,7 +321,7 @@ func handleRebootUncordon(nodeName string, interruptionEventStore *interruptione
}
err = node.UncordonIfRebooted(nodeName)
if err != nil {
- return fmt.Errorf("Unable to complete node label actions: %w", err)
+ return fmt.Errorf("unable to complete node label actions: %w", err)
}
interruptionEventStore.IgnoreEvent(eventID)
return nil
diff --git a/go.mod b/go.mod
index 2a01b7b8..41f569e8 100644
--- a/go.mod
+++ b/go.mod
@@ -1,8 +1,8 @@
module github.com/aws/aws-node-termination-handler
-go 1.22.0
+go 1.25
-toolchain go1.22.2
+toolchain go1.25.5
require (
github.com/Masterminds/sprig/v3 v3.2.3
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 9de5f69f..6498dc81 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -316,8 +316,12 @@ func ParseCliArgs() (config Config, err error) {
}
// client-go expects these to be set in env vars
- os.Setenv(kubernetesServiceHostConfigKey, config.KubernetesServiceHost)
- os.Setenv(kubernetesServicePortConfigKey, config.KubernetesServicePort)
+ if err := os.Setenv(kubernetesServiceHostConfigKey, config.KubernetesServiceHost); err != nil {
+ return config, fmt.Errorf("failed to set %s environment variable: %w", kubernetesServiceHostConfigKey, err)
+ }
+ if err := os.Setenv(kubernetesServicePortConfigKey, config.KubernetesServicePort); err != nil {
+ return config, fmt.Errorf("failed to set %s environment variable: %w", kubernetesServicePortConfigKey, err)
+ }
return config, err
}
diff --git a/pkg/ec2metadata/ec2metadata.go b/pkg/ec2metadata/ec2metadata.go
index 036a6347..c1e87557 100644
--- a/pkg/ec2metadata/ec2metadata.go
+++ b/pkg/ec2metadata/ec2metadata.go
@@ -139,16 +139,16 @@ func New(metadataURL string, tries int) *Service {
func (e *Service) GetScheduledMaintenanceEvents() ([]ScheduledEventDetail, error) {
resp, err := e.Request(ScheduledEventPath)
if resp != nil && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
- return nil, fmt.Errorf("Metadata request received http status code: %d", resp.StatusCode)
+ return nil, fmt.Errorf("metadata request received http status code: %d", resp.StatusCode)
}
if err != nil {
- return nil, fmt.Errorf("Unable to parse metadata response: %w", err)
+ return nil, fmt.Errorf("unable to parse metadata response: %w", err)
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
var scheduledEvents []ScheduledEventDetail
err = json.NewDecoder(resp.Body).Decode(&scheduledEvents)
if err != nil {
- return nil, fmt.Errorf("Could not decode json retrieved from imds: %w", err)
+ return nil, fmt.Errorf("could not decode json retrieved from imds: %w", err)
}
return scheduledEvents, nil
}
@@ -160,16 +160,16 @@ func (e *Service) GetSpotITNEvent() (instanceAction *InstanceAction, err error)
if resp != nil && resp.StatusCode == 404 {
return nil, nil
} else if resp != nil && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
- return nil, fmt.Errorf("Metadata request received http status code: %d", resp.StatusCode)
+ return nil, fmt.Errorf("metadata request received http status code: %d", resp.StatusCode)
}
if err != nil {
- return nil, fmt.Errorf("Unable to parse metadata response: %w", err)
+ return nil, fmt.Errorf("unable to parse metadata response: %w", err)
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
err = json.NewDecoder(resp.Body).Decode(&instanceAction)
if err != nil {
- return nil, fmt.Errorf("Could not decode instance action response: %w", err)
+ return nil, fmt.Errorf("could not decode instance action response: %w", err)
}
return instanceAction, nil
}
@@ -181,16 +181,16 @@ func (e *Service) GetRebalanceRecommendationEvent() (rebalanceRec *RebalanceReco
if resp != nil && resp.StatusCode == 404 {
return nil, nil
} else if resp != nil && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
- return nil, fmt.Errorf("Metadata request received http status code: %d", resp.StatusCode)
+ return nil, fmt.Errorf("metadata request received http status code: %d", resp.StatusCode)
}
if err != nil {
- return nil, fmt.Errorf("Unable to parse metadata response: %w", err)
+ return nil, fmt.Errorf("unable to parse metadata response: %w", err)
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
err = json.NewDecoder(resp.Body).Decode(&rebalanceRec)
if err != nil {
- return nil, fmt.Errorf("Could not decode rebalance recommendation response: %w", err)
+ return nil, fmt.Errorf("could not decode rebalance recommendation response: %w", err)
}
return rebalanceRec, nil
}
@@ -203,16 +203,16 @@ func (e *Service) GetASGTargetLifecycleState() (state string, err error) {
if resp != nil && resp.StatusCode == 404 {
return "", nil
} else if resp != nil && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
- return "", fmt.Errorf("Metadata request received http status code: %d", resp.StatusCode)
+ return "", fmt.Errorf("metadata request received http status code: %d", resp.StatusCode)
}
if err != nil {
- return "", fmt.Errorf("Unable to parse metadata response: %w", err)
+ return "", fmt.Errorf("unable to parse metadata response: %w", err)
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
body, err := io.ReadAll(resp.Body)
if err != nil {
- return "", fmt.Errorf("Unable to parse http response. Status code: %d. %w", resp.StatusCode, err)
+ return "", fmt.Errorf("unable to parse http response. Status code: %d. %w", resp.StatusCode, err)
}
return string(body), nil
}
@@ -222,19 +222,19 @@ func (e *Service) GetMetadataInfo(path string, allowMissing bool) (info string,
metadataInfo := ""
resp, err := e.Request(path)
if err != nil {
- return "", fmt.Errorf("Unable to parse metadata response: %w", err)
+ return "", fmt.Errorf("unable to parse metadata response: %w", err)
}
if resp != nil {
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
body, err := io.ReadAll(resp.Body)
if err != nil {
- return "", fmt.Errorf("Unable to parse http response. Status code: %d. %w", resp.StatusCode, err)
+ return "", fmt.Errorf("unable to parse http response. Status code: %d. %w", resp.StatusCode, err)
}
metadataInfo = string(body)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
if resp.StatusCode != 404 || !allowMissing {
log.Info().Msgf("Metadata response status code: %d. Body: %s", resp.StatusCode, metadataInfo)
- return "", fmt.Errorf("Metadata request received http status code: %d", resp.StatusCode)
+ return "", fmt.Errorf("metadata request received http status code: %d", resp.StatusCode)
} else {
return "", nil
}
@@ -249,7 +249,7 @@ func (e *Service) GetMetadataInfo(path string, allowMissing bool) (info string,
func (e *Service) Request(contextPath string) (*http.Response, error) {
req, err := http.NewRequest(http.MethodGet, e.metadataURL+contextPath, nil)
if err != nil {
- return nil, fmt.Errorf("Unable to construct an http get request to IDMS for %s: %w", e.metadataURL+contextPath, err)
+ return nil, fmt.Errorf("unable to construct an http get request to IDMS for %s: %w", e.metadataURL+contextPath, err)
}
var resp *http.Response
for i := 0; i < tokenRetryAttempts; i++ {
@@ -274,7 +274,7 @@ func (e *Service) Request(contextPath string) (*http.Response, error) {
}
resp, err = retry(e.tries, 2*time.Second, httpReq)
if err != nil {
- return nil, fmt.Errorf("Unable to get a response from IMDS: %w", err)
+ return nil, fmt.Errorf("unable to get a response from IMDS: %w", err)
}
if resp != nil && resp.StatusCode == 401 {
e.Lock()
@@ -297,7 +297,7 @@ func (e *Service) Request(contextPath string) (*http.Response, error) {
func (e *Service) getV2Token() (string, int, error) {
req, err := http.NewRequest(http.MethodPut, e.metadataURL+tokenRefreshPath, nil)
if err != nil {
- return "", -1, fmt.Errorf("Unable to construct http put request to retrieve imdsv2 token: %w", err)
+ return "", -1, fmt.Errorf("unable to construct http put request to retrieve imdsv2 token: %w", err)
}
req.Header.Add(tokenTTLHeader, strconv.Itoa(tokenTTL))
httpReq := func() (*http.Response, error) {
@@ -308,13 +308,13 @@ func (e *Service) getV2Token() (string, int, error) {
if err != nil {
return "", -1, err
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
- return "", -1, fmt.Errorf("Received an http status code %d", resp.StatusCode)
+ return "", -1, fmt.Errorf("received an http status code %d", resp.StatusCode)
}
token, err := io.ReadAll(resp.Body)
if err != nil {
- return "", -1, fmt.Errorf("Unable to read token response from IMDSv2: %w", err)
+ return "", -1, fmt.Errorf("unable to read token response from IMDSv2: %w", err)
}
ttl, err := ttlHeaderToInt(resp)
if err != nil {
@@ -327,7 +327,7 @@ func (e *Service) getV2Token() (string, int, error) {
func ttlHeaderToInt(resp *http.Response) (int, error) {
ttl := resp.Header.Get(tokenTTLHeader)
if ttl == "" {
- return -1, fmt.Errorf("No token TTL header found")
+ return -1, fmt.Errorf("no token TTL header found")
}
ttlInt, err := strconv.Atoi(ttl)
if err != nil {
diff --git a/pkg/ec2metadata/ec2metadata_internal_test.go b/pkg/ec2metadata/ec2metadata_internal_test.go
index 0e3999e4..89cbf26b 100644
--- a/pkg/ec2metadata/ec2metadata_internal_test.go
+++ b/pkg/ec2metadata/ec2metadata_internal_test.go
@@ -27,8 +27,8 @@ import (
)
func TestRetry(t *testing.T) {
- var numRetries int = 3
- var errorMsg string = "Request failed"
+ var numRetries = 3
+ var errorMsg = "Request failed"
var requestCount int
request := func() (*http.Response, error) {
diff --git a/pkg/ec2metadata/ec2metadata_test.go b/pkg/ec2metadata/ec2metadata_test.go
index 92660a23..87f89634 100644
--- a/pkg/ec2metadata/ec2metadata_test.go
+++ b/pkg/ec2metadata/ec2metadata_test.go
@@ -25,7 +25,7 @@ import (
)
func TestRequestV1(t *testing.T) {
- var requestPath string = "/some/path"
+ var requestPath = "/some/path"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/latest/api/token" {
@@ -55,7 +55,7 @@ func TestRequestV1(t *testing.T) {
}
func TestRequestV2(t *testing.T) {
- var requestPath string = "/some/path"
+ var requestPath = "/some/path"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -89,7 +89,7 @@ func TestRequestV2(t *testing.T) {
}
func TestRequestFailure(t *testing.T) {
- var requestPath string = "/some/path"
+ var requestPath = "/some/path"
imds := ec2metadata.New("notadomain", 1)
_, err := imds.Request(requestPath)
@@ -97,7 +97,7 @@ func TestRequestFailure(t *testing.T) {
}
func TestRequest500(t *testing.T) {
- var requestPath string = "/some/path"
+ var requestPath = "/some/path"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/latest/api/token" {
@@ -118,7 +118,7 @@ func TestRequest500(t *testing.T) {
}
func TestRequest401(t *testing.T) {
- var requestPath string = "/some/path"
+ var requestPath = "/some/path"
tokenGenerationCounter := 0
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
@@ -161,7 +161,7 @@ func TestGetSpotITNEventSuccess(t *testing.T) {
time = "2020-02-07T14:55:55Z"
instanceAction = "terminate"
)
- var requestPath string = "/latest/meta-data/spot/instance-action"
+ var requestPath = "/latest/meta-data/spot/instance-action"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -173,10 +173,10 @@ func TestGetSpotITNEventSuccess(t *testing.T) {
}
h.Equals(t, req.Header.Get("X-aws-ec2-metadata-token"), "token")
h.Equals(t, req.URL.String(), requestPath)
- _, err := rw.Write([]byte(fmt.Sprintf(`{
+ _, err := fmt.Fprintf(rw, `{
"action": "%s",
"time": "%s"
- }`, instanceAction, time)))
+ }`, instanceAction, time)
h.Ok(t, err)
}))
defer server.Close()
@@ -195,7 +195,7 @@ func TestGetSpotITNEventSuccess(t *testing.T) {
}
func TestGetSpotITNEvent404Success(t *testing.T) {
- var requestPath string = "/latest/meta-data/spot/instance-action"
+ var requestPath = "/latest/meta-data/spot/instance-action"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -220,7 +220,7 @@ func TestGetSpotITNEvent404Success(t *testing.T) {
}
func TestGetSpotITNEventBadJSON(t *testing.T) {
- var requestPath string = "/latest/meta-data/spot/instance-action"
+ var requestPath = "/latest/meta-data/spot/instance-action"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -245,7 +245,7 @@ func TestGetSpotITNEventBadJSON(t *testing.T) {
}
func TestGetSpotITNEvent500Failure(t *testing.T) {
- var requestPath string = "/latest/meta-data/spot/instance-action"
+ var requestPath = "/latest/meta-data/spot/instance-action"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -285,7 +285,7 @@ func TestGetScheduledMaintenanceEventsSuccess(t *testing.T) {
eventId = "instance-event-0d59937288b749b32"
state = "active"
)
- var requestPath string = "/latest/meta-data/events/maintenance/scheduled"
+ var requestPath = "/latest/meta-data/events/maintenance/scheduled"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -297,7 +297,7 @@ func TestGetScheduledMaintenanceEventsSuccess(t *testing.T) {
}
h.Equals(t, req.Header.Get("X-aws-ec2-metadata-token"), "token")
h.Equals(t, req.URL.String(), requestPath)
- _, err := rw.Write([]byte(fmt.Sprintf(`[
+ _, err := fmt.Fprintf(rw, `[
{
"NotBefore" : "%s",
"Code" : "%s",
@@ -306,7 +306,7 @@ func TestGetScheduledMaintenanceEventsSuccess(t *testing.T) {
"NotAfter" : "%s",
"State" : "%s"
}
- ]`, notBefore, code, description, eventId, notAfter, state)))
+ ]`, notBefore, code, description, eventId, notAfter, state)
h.Ok(t, err)
}))
defer server.Close()
@@ -331,7 +331,7 @@ func TestGetScheduledMaintenanceEventsSuccess(t *testing.T) {
}
func TestGetScheduledMaintenanceEvents500Failure(t *testing.T) {
- var requestPath string = "/latest/meta-data/events/maintenance/scheduled"
+ var requestPath = "/latest/meta-data/events/maintenance/scheduled"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -355,7 +355,7 @@ func TestGetScheduledMaintenanceEvents500Failure(t *testing.T) {
}
func TestGetScheduledMaintenanceEventsBadJSON(t *testing.T) {
- var requestPath string = "/latest/meta-data/events/maintenance/scheduled"
+ var requestPath = "/latest/meta-data/events/maintenance/scheduled"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -403,9 +403,9 @@ func TestGetRebalanceRecommendationEventSuccess(t *testing.T) {
}
h.Equals(t, req.Header.Get("X-aws-ec2-metadata-token"), "token")
h.Equals(t, req.URL.String(), requestPath)
- _, err := rw.Write([]byte(fmt.Sprintf(`{
+ _, err := fmt.Fprintf(rw, `{
"noticeTime": "%s"
- }`, noticeTime)))
+ }`, noticeTime)
h.Ok(t, err)
}))
defer server.Close()
@@ -590,7 +590,7 @@ func TestGetASGTargetLifecycleStateRequestFailure(t *testing.T) {
}
func TestGetMetadataServiceRequest404(t *testing.T) {
- var requestPath string = "/latest/meta-data/instance-type"
+ var requestPath = "/latest/meta-data/instance-type"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -615,7 +615,7 @@ func TestGetMetadataServiceRequest404(t *testing.T) {
}
func TestGetMetadataServiceRequest404AllowMissing(t *testing.T) {
- var requestPath string = "/latest/meta-data/instance-type"
+ var requestPath = "/latest/meta-data/instance-type"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -640,7 +640,7 @@ func TestGetMetadataServiceRequest404AllowMissing(t *testing.T) {
}
func TestGetMetadataServiceRequest500AllowMissing(t *testing.T) {
- var requestPath string = "/latest/meta-data/instance-type"
+ var requestPath = "/latest/meta-data/instance-type"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
@@ -673,7 +673,7 @@ func TestGetMetadataServiceRequestFailure(t *testing.T) {
}
func TestGetMetadataServiceSuccess(t *testing.T) {
- var requestPath string = "/latest/meta-data/instance-type"
+ var requestPath = "/latest/meta-data/instance-type"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Header().Add("X-aws-ec2-metadata-token-ttl-seconds", "100")
diff --git a/pkg/logging/versioned.go b/pkg/logging/versioned.go
index 95bcb72f..d6328819 100644
--- a/pkg/logging/versioned.go
+++ b/pkg/logging/versioned.go
@@ -102,6 +102,6 @@ func SetFormatVersion(version int) error {
return nil
default:
VersionedMsgs = versionedMsgsV1{}
- return fmt.Errorf("Unrecognized log format version: %d, using version 1", version)
+ return fmt.Errorf("unrecognized log format version: %d, using version 1", version)
}
}
diff --git a/pkg/monitor/asglifecycle/asg-lifecycle-monitor.go b/pkg/monitor/asglifecycle/asg-lifecycle-monitor.go
index a623ae96..36474bea 100644
--- a/pkg/monitor/asglifecycle/asg-lifecycle-monitor.go
+++ b/pkg/monitor/asglifecycle/asg-lifecycle-monitor.go
@@ -78,7 +78,7 @@ func (m ASGLifecycleMonitor) checkForASGTargetLifecycleStateNotice() (*monitor.I
// There's no EventID returned, so we'll create it using a hash to prevent duplicates.
hash := sha256.New()
- if _, err = hash.Write([]byte(fmt.Sprintf("%s:%s", state, interruptionTime))); err != nil {
+ if _, err = fmt.Fprintf(hash, "%s:%s", state, interruptionTime); err != nil {
return nil, fmt.Errorf("There was a problem creating an event ID from the event: %w", err)
}
diff --git a/pkg/monitor/rebalancerecommendation/rebalance-recommendation-monitor.go b/pkg/monitor/rebalancerecommendation/rebalance-recommendation-monitor.go
index d0095c78..c8a39c76 100644
--- a/pkg/monitor/rebalancerecommendation/rebalance-recommendation-monitor.go
+++ b/pkg/monitor/rebalancerecommendation/rebalance-recommendation-monitor.go
@@ -77,7 +77,7 @@ func (m RebalanceRecommendationMonitor) checkForRebalanceRecommendation() (*moni
// There's no EventID returned so we'll create it using a hash to prevent duplicates.
hash := sha256.New()
- _, err = hash.Write([]byte(fmt.Sprintf("%v", rebalanceRecommendation)))
+ _, err = fmt.Fprintf(hash, "%v", rebalanceRecommendation)
if err != nil {
return nil, fmt.Errorf("There was a problem creating an event ID from the event: %w", err)
}
diff --git a/pkg/monitor/scheduledevent/scheduled-event-monitor_test.go b/pkg/monitor/scheduledevent/scheduled-event-monitor_test.go
index fbe3a26f..f8e53ffc 100644
--- a/pkg/monitor/scheduledevent/scheduled-event-monitor_test.go
+++ b/pkg/monitor/scheduledevent/scheduled-event-monitor_test.go
@@ -54,7 +54,7 @@ func oneSecondAgo() time.Time {
}
func TestMonitor_Success(t *testing.T) {
- var requestPath string = ec2metadata.ScheduledEventPath
+ var requestPath = ec2metadata.ScheduledEventPath
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if imdsV2TokenPath == req.URL.String() {
@@ -103,7 +103,7 @@ func TestMonitor_Success(t *testing.T) {
}
func TestMonitor_CanceledEvent(t *testing.T) {
- var requestPath string = ec2metadata.ScheduledEventPath
+ var requestPath = ec2metadata.ScheduledEventPath
var state = "canceled"
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if imdsV2TokenPath == req.URL.String() {
@@ -158,7 +158,7 @@ func TestMonitor_CanceledEvent(t *testing.T) {
}
func TestMonitor_MetadataParseFailure(t *testing.T) {
- var requestPath string = ec2metadata.ScheduledEventPath
+ var requestPath = ec2metadata.ScheduledEventPath
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if imdsV2TokenPath == req.URL.String() {
@@ -179,7 +179,7 @@ func TestMonitor_MetadataParseFailure(t *testing.T) {
}
func TestMonitor_404Response(t *testing.T) {
- var requestPath string = ec2metadata.ScheduledEventPath
+ var requestPath = ec2metadata.ScheduledEventPath
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if imdsV2TokenPath == req.URL.String() {
@@ -202,7 +202,7 @@ func TestMonitor_404Response(t *testing.T) {
}
func TestMonitor_StartTimeParseFail(t *testing.T) {
- var requestPath string = ec2metadata.ScheduledEventPath
+ var requestPath = ec2metadata.ScheduledEventPath
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if imdsV2TokenPath == req.URL.String() {
rw.WriteHeader(403)
@@ -231,7 +231,7 @@ func TestMonitor_StartTimeParseFail(t *testing.T) {
}
func TestMonitor_EndTimeParseFail(t *testing.T) {
- var requestPath string = ec2metadata.ScheduledEventPath
+ var requestPath = ec2metadata.ScheduledEventPath
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if imdsV2TokenPath == req.URL.String() {
rw.WriteHeader(403)
diff --git a/pkg/monitor/spotitn/spot-itn-monitor.go b/pkg/monitor/spotitn/spot-itn-monitor.go
index 061577e7..c9f1954e 100644
--- a/pkg/monitor/spotitn/spot-itn-monitor.go
+++ b/pkg/monitor/spotitn/spot-itn-monitor.go
@@ -79,7 +79,7 @@ func (m SpotInterruptionMonitor) checkForSpotInterruptionNotice() (*monitor.Inte
// There's no EventID returned so we'll create it using a hash to prevent duplicates.
hash := sha256.New()
- _, err = hash.Write([]byte(fmt.Sprintf("%v", instanceAction)))
+ _, err = fmt.Fprintf(hash, "%v", instanceAction)
if err != nil {
return nil, fmt.Errorf("There was a problem creating an event ID from the event: %w", err)
}
diff --git a/pkg/monitor/sqsevent/sqs-monitor.go b/pkg/monitor/sqsevent/sqs-monitor.go
index 84440d4c..b0e7cdd2 100644
--- a/pkg/monitor/sqsevent/sqs-monitor.go
+++ b/pkg/monitor/sqsevent/sqs-monitor.go
@@ -211,21 +211,23 @@ func (m SQSMonitor) processEventBridgeEvent(eventBridgeEvent *EventBridgeEvent,
interruptionEvent, err = nil, fmt.Errorf("unmarshaling message, %s, from ASG lifecycle event: %w", *message.MessageId, err)
interruptionEventWrappers = append(interruptionEventWrappers, InterruptionEventWrapper{interruptionEvent, err})
}
- if lifecycleEvent.LifecycleTransition == ASGLaunchingLifecycleTransition {
+ switch lifecycleEvent.LifecycleTransition {
+ case ASGLaunchingLifecycleTransition:
interruptionEvent, err = m.createAsgInstanceLaunchEvent(eventBridgeEvent, message)
interruptionEventWrappers = append(interruptionEventWrappers, InterruptionEventWrapper{interruptionEvent, err})
- } else if lifecycleEvent.LifecycleTransition == ASGTerminatingLifecycleTransition {
+ case ASGTerminatingLifecycleTransition:
interruptionEvent, err = m.asgTerminationToInterruptionEvent(eventBridgeEvent, message)
interruptionEventWrappers = append(interruptionEventWrappers, InterruptionEventWrapper{interruptionEvent, err})
}
return interruptionEventWrappers
case "aws.ec2":
- if eventBridgeEvent.DetailType == "EC2 Instance State-change Notification" {
+ switch eventBridgeEvent.DetailType {
+ case "EC2 Instance State-change Notification":
interruptionEvent, err = m.ec2StateChangeToInterruptionEvent(eventBridgeEvent, message)
- } else if eventBridgeEvent.DetailType == "EC2 Spot Instance Interruption Warning" {
+ case "EC2 Spot Instance Interruption Warning":
interruptionEvent, err = m.spotITNTerminationToInterruptionEvent(eventBridgeEvent, message)
- } else if eventBridgeEvent.DetailType == "EC2 Instance Rebalance Recommendation" {
+ case "EC2 Instance Rebalance Recommendation":
interruptionEvent, err = m.rebalanceRecommendationToInterruptionEvent(eventBridgeEvent, message)
}
return append(interruptionEventWrappers, InterruptionEventWrapper{interruptionEvent, err})
diff --git a/pkg/monitor/sqsevent/sqs-monitor_internal_test.go b/pkg/monitor/sqsevent/sqs-monitor_internal_test.go
index c7caa10f..ff209746 100644
--- a/pkg/monitor/sqsevent/sqs-monitor_internal_test.go
+++ b/pkg/monitor/sqsevent/sqs-monitor_internal_test.go
@@ -29,7 +29,7 @@ func TestGetTime_Success(t *testing.T) {
testTime, err := time.Parse(time.RFC3339, testTimeStr)
h.Ok(t, err)
asgLifecycleTime := EventBridgeEvent{Time: testTimeStr}.getTime()
- h.Assert(t, testTime == asgLifecycleTime, "RFC3339 should be parsed correctly from event")
+ h.Assert(t, testTime.Equal(asgLifecycleTime), "RFC3339 should be parsed correctly from event")
}
func TestGetTime_Empty(t *testing.T) {
diff --git a/pkg/monitor/sqsevent/sqs-retryer_test.go b/pkg/monitor/sqsevent/sqs-retryer_test.go
index d097f930..785527e7 100644
--- a/pkg/monitor/sqsevent/sqs-retryer_test.go
+++ b/pkg/monitor/sqsevent/sqs-retryer_test.go
@@ -103,10 +103,10 @@ func getSqsRetryer(t *testing.T) sqsevent.SqsRetryer {
h.Ok(t, err)
sqsClient := sqsevent.GetSqsClient(sess)
- h.Assert(t, sqsClient.Client.Config.Region != nil, "Region should not be nil")
- h.Equals(t, "us-east-1", *sqsClient.Client.Config.Region)
+ h.Assert(t, sqsClient.Config.Region != nil, "Region should not be nil")
+ h.Equals(t, "us-east-1", *sqsClient.Config.Region)
- retryer, ok := sqsClient.Client.Config.Retryer.(sqsevent.SqsRetryer)
+ retryer, ok := sqsClient.Config.Retryer.(sqsevent.SqsRetryer)
h.Assert(t, ok, "Retryer should be of type SqsRetryer")
return retryer
}
diff --git a/pkg/node/node.go b/pkg/node/node.go
index b80d6ebf..48c5bd75 100644
--- a/pkg/node/node.go
+++ b/pkg/node/node.go
@@ -327,7 +327,7 @@ func (n Node) addLabel(nodeName string, key string, value string, skipExisting b
return err
}
if skipExisting {
- _, ok := node.ObjectMeta.Labels[key]
+ _, ok := node.Labels[key]
if ok {
return nil
}
@@ -394,7 +394,7 @@ func (n Node) removeLabelIfValueMatches(nodeName string, key string, matchValue
if err != nil {
return err
}
- val, ok := node.ObjectMeta.Labels[key]
+ val, ok := node.Labels[key]
if !ok || val == matchValue {
return nil
}
@@ -763,8 +763,8 @@ func getDrainHelper(nthConfig config.Config, clientset *kubernetes.Clientset) (*
}
func jsonPatchEscape(value string) string {
- value = strings.Replace(value, "~", "~0", -1)
- return strings.Replace(value, "/", "~1", -1)
+ value = strings.ReplaceAll(value, "~", "~0")
+ return strings.ReplaceAll(value, "/", "~1")
}
func getTaintEffect(effect string) corev1.TaintEffect {
diff --git a/pkg/node/node_internal_test.go b/pkg/node/node_internal_test.go
index 9f917cd2..e34fee6d 100644
--- a/pkg/node/node_internal_test.go
+++ b/pkg/node/node_internal_test.go
@@ -104,7 +104,7 @@ func TestUncordonIfRebootedSystemNotRestarted(t *testing.T) {
h.Ok(t, err)
tNode := getNode(t, getTestDrainHelper(client), getUptimeFromFile(testFile))
err = tNode.UncordonIfRebooted(nodeName)
- os.Remove(testFile)
+ _ = os.Remove(testFile)
h.Ok(t, err)
}
@@ -128,7 +128,7 @@ func TestUncordonIfRebootedFailureToRemoveLabel(t *testing.T) {
h.Ok(t, err)
tNode := getNode(t, getTestDrainHelper(client), getUptimeFromFile(testFile))
err = tNode.UncordonIfRebooted(nodeName)
- os.Remove(testFile)
+ _ = os.Remove(testFile)
h.Assert(t, err != nil, "Failed to return error on UncordonIfReboted failure remove NTH Label")
}
@@ -153,7 +153,7 @@ func TestUncordonIfRebootedFailureSuccess(t *testing.T) {
h.Ok(t, err)
tNode := getNode(t, getTestDrainHelper(client), getUptimeFromFile(testFile))
err = tNode.UncordonIfRebooted(nodeName)
- os.Remove(testFile)
+ _ = os.Remove(testFile)
h.Ok(t, err)
}
diff --git a/pkg/node/node_test.go b/pkg/node/node_test.go
index 052772a6..bb07f4b1 100644
--- a/pkg/node/node_test.go
+++ b/pkg/node/node_test.go
@@ -27,7 +27,6 @@ import (
"github.com/aws/aws-node-termination-handler/pkg/node"
h "github.com/aws/aws-node-termination-handler/pkg/test"
"github.com/aws/aws-node-termination-handler/pkg/uptime"
- corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
@@ -470,8 +469,8 @@ func TestFilterOutDaemonSetPods(t *testing.T) {
tNode, err := newNode(config.Config{IgnoreDaemonSets: true}, fake.NewSimpleClientset())
h.Ok(t, err)
- mockPodList := &corev1.PodList{
- Items: []corev1.Pod{
+ mockPodList := &v1.PodList{
+ Items: []v1.Pod{
{
ObjectMeta: metav1.ObjectMeta{
Name: "mock-daemon-pod",
@@ -530,7 +529,7 @@ func TestTaintOutOfService(t *testing.T) {
expectedTaint := v1.Taint{
Key: outOfServiceTaintKey,
Value: outOfServiceTaintValue,
- Effect: corev1.TaintEffectNoExecute,
+ Effect: v1.TaintEffectNoExecute,
}
for _, taint := range updatedNode.Spec.Taints {
if taint.Key == expectedTaint.Key &&
diff --git a/pkg/observability/opentelemetry_test.go b/pkg/observability/opentelemetry_test.go
index cf07f5e3..66db6e32 100644
--- a/pkg/observability/opentelemetry_test.go
+++ b/pkg/observability/opentelemetry_test.go
@@ -225,11 +225,11 @@ func TestServeMetrics(t *testing.T) {
if err != nil {
t.Errorf("server is not listening on port %d: %v", mockDefaultPort, err)
}
- conn.Close()
+ _ = conn.Close()
conn, err = net.DialTimeout("tcp", fmt.Sprintf("localhost:%d", mockClosedPort), time.Second)
if err == nil {
- conn.Close()
+ _ = conn.Close()
t.Errorf("server should not be listening on port %d: %v", mockClosedPort, err)
}
}
diff --git a/pkg/test/helpers.go b/pkg/test/helpers.go
index 74fcf26a..bb4a5bfe 100644
--- a/pkg/test/helpers.go
+++ b/pkg/test/helpers.go
@@ -61,7 +61,7 @@ func Equals(tb testing.TB, exp, act interface{}) {
// TimeWithinRange fails the test if act is not after lowerBound or not before upperBound
func TimeWithinRange(tb testing.TB, act time.Time, lowerBound time.Time, upperBound time.Time) {
- if !(act.After(lowerBound) && act.Before(upperBound)) {
+ if !act.After(lowerBound) || !act.Before(upperBound) {
_, file, line, _ := runtime.Caller(1)
fmt.Printf("\033[31m%s:%d:\n\n\tlower bound: %#v\n\n\tgot: %#v\n\n\tupper bound: %#v\033[39m\n\n", filepath.Base(file), line, lowerBound, act, upperBound)
tb.FailNow()
diff --git a/pkg/uptime/common_test.go b/pkg/uptime/common_test.go
index 23fad24d..2cc07d59 100644
--- a/pkg/uptime/common_test.go
+++ b/pkg/uptime/common_test.go
@@ -28,7 +28,7 @@ func TestUptimeFromFileSuccess(t *testing.T) {
h.Ok(t, err)
value, err := UptimeFromFile(testFile)
- os.Remove(testFile)
+ _ = os.Remove(testFile)
h.Ok(t, err)
h.Equals(t, int64(350735), value)
}
@@ -44,6 +44,6 @@ func TestUptimeFromFileBadData(t *testing.T) {
h.Ok(t, err)
_, err = UptimeFromFile(testFile)
- os.Remove(testFile)
+ _ = os.Remove(testFile)
h.Assert(t, err != nil, "Failed to return error for int64 parse")
}
diff --git a/pkg/webhook/webhook.go b/pkg/webhook/webhook.go
index 4c6ced4d..82771023 100644
--- a/pkg/webhook/webhook.go
+++ b/pkg/webhook/webhook.go
@@ -118,7 +118,7 @@ func Post(additionalInfo ec2metadata.NodeMetadata, event *monitor.InterruptionEv
return
}
- defer response.Body.Close()
+ defer func() { _ = response.Body.Close() }()
if response.StatusCode < 200 || response.StatusCode > 299 {
log.Warn().Int("status_code", response.StatusCode).Msg("Webhook Error: Received Non-Successful Status Code")
@@ -139,7 +139,7 @@ func ValidateWebhookConfig(nthConfig config.Config) error {
if nthConfig.WebhookTemplateFile != "" {
content, err := os.ReadFile(nthConfig.WebhookTemplateFile)
if err != nil {
- return fmt.Errorf("Webhook Error: Could not read template file %w", err)
+ return fmt.Errorf("webhook error: could not read template file %w", err)
}
webhookTemplateContent = string(content)
} else {
@@ -148,13 +148,13 @@ func ValidateWebhookConfig(nthConfig config.Config) error {
webhookTemplate, err := template.New("message").Funcs(sprig.TxtFuncMap()).Parse(webhookTemplateContent)
if err != nil {
- return fmt.Errorf("Unable to parse webhook template: %w", err)
+ return fmt.Errorf("unable to parse webhook template: %w", err)
}
var byteBuffer bytes.Buffer
err = webhookTemplate.Execute(&byteBuffer, &combinedDrainData{})
if err != nil {
- return fmt.Errorf("Unable to execute webhook template: %w", err)
+ return fmt.Errorf("unable to execute webhook template: %w", err)
}
return nil
}
diff --git a/pkg/webhook/webhook_test.go b/pkg/webhook/webhook_test.go
index ecd073dd..423d2593 100644
--- a/pkg/webhook/webhook_test.go
+++ b/pkg/webhook/webhook_test.go
@@ -181,7 +181,7 @@ func TestPostHeaderParseFail(t *testing.T) {
}
func TestPostTimeout(t *testing.T) {
- var requestCount int = 0
+ var requestCount = 0
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
requestCount++
time.Sleep(6 * time.Second)
@@ -201,7 +201,7 @@ func TestPostTimeout(t *testing.T) {
}
func TestPostBadResponseCode(t *testing.T) {
- var requestCount int = 0
+ var requestCount = 0
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
requestCount++
http.Error(rw, "404 page not found", http.StatusNotFound)
diff --git a/test/webhook-test-proxy/Dockerfile b/test/webhook-test-proxy/Dockerfile
index a0119541..9227505f 100644
--- a/test/webhook-test-proxy/Dockerfile
+++ b/test/webhook-test-proxy/Dockerfile
@@ -1,5 +1,5 @@
# Build the manager binary
-FROM golang:1.22-alpine as builder
+FROM golang:1.25-alpine as builder
## GOLANG env
ARG GOPROXY="https://proxy.golang.org|direct"
diff --git a/test/webhook-test-proxy/Dockerfile.windows b/test/webhook-test-proxy/Dockerfile.windows
index 5810b1cc..98eda76c 100644
--- a/test/webhook-test-proxy/Dockerfile.windows
+++ b/test/webhook-test-proxy/Dockerfile.windows
@@ -1,7 +1,7 @@
ARG WINDOWS_VERSION=1903
# Build the manager binary
-FROM --platform=windows/amd64 golang:1.22 AS builder
+FROM --platform=windows/amd64 golang:1.25 AS builder
## GOLANG env
ENV GO111MODULE="on" CGO_ENABLED="0" GOOS="windows" GOARCH="amd64"