Skip to content

Commit 560074b

Browse files
committed
Fix http response nil access to StatusCode
1 parent 93615e7 commit 560074b

21 files changed

+104
-51
lines changed

internal/controller/atlasproject/network_peering.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/mongodb/mongodb-atlas-kubernetes/v2/api/v1/status"
3131
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/compare"
3232
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/controller/workflow"
33+
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/httputil"
3334
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/pointer"
3435
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/translation/paging"
3536
)
@@ -185,7 +186,8 @@ func deleteUnusedContainers(context context.Context, containerService admin.Netw
185186
}
186187
if !compare.Contains(doNotDelete, container.GetId()) {
187188
response, errDelete := containerService.DeleteGroupContainer(context, groupID, container.GetId()).Execute()
188-
if errDelete != nil && response.StatusCode != http.StatusConflict { // AWS peer does not contain container id
189+
statusCode := httputil.StatusCode(response)
190+
if errDelete != nil && statusCode != http.StatusConflict { // AWS peer does not contain container id
189191
return errDelete
190192
}
191193
}
@@ -462,7 +464,7 @@ func comparePeersPair(ctx context.Context, existedPeer, expectedPeer akov2.Netwo
462464
func deletePeerByID(ctx context.Context, peerService admin.NetworkPeeringApi, groupID string, containerID string, logger *zap.SugaredLogger) error {
463465
_, response, err := peerService.DeleteGroupPeer(ctx, groupID, containerID).Execute()
464466
if err != nil {
465-
if response != nil && response.StatusCode == http.StatusNotFound {
467+
if httputil.StatusCode(response) == http.StatusNotFound {
466468
return errors.Join(err, errNortFound)
467469
}
468470
logger.Errorf("failed to delete peering container %s: %v", containerID, err)
@@ -510,7 +512,7 @@ func createContainer(ctx context.Context, containerService admin.NetworkPeeringA
510512

511513
create, response, err := containerService.CreateGroupContainer(ctx, groupID, container).Execute()
512514
if err != nil {
513-
if response.StatusCode == http.StatusConflict {
515+
if httputil.StatusCode(response) == http.StatusConflict {
514516
list, _, errList := containerService.ListGroupContainers(ctx, groupID).ProviderName(string(peer.ProviderName)).Execute()
515517
if errList != nil {
516518
logger.Errorf("failed to list containers: %v", errList)

internal/controller/atlasproject/private_endpoint.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/mongodb/mongodb-atlas-kubernetes/v2/api/v1/provider"
2828
"github.com/mongodb/mongodb-atlas-kubernetes/v2/api/v1/status"
2929
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/controller/workflow"
30+
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/httputil"
3031
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/pointer"
3132
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/set"
3233
)
@@ -291,7 +292,8 @@ func syncPeInterfaceInAtlas(ctx *workflow.Context, projectID string, endpointsTo
291292
ctx.Log.Debugw("CreatePrivateEndpoint Reply", "privateEndpoint", privateEndpoint, "err", err)
292293
if err != nil {
293294
ctx.Log.Debugw("failed to create PE Interface", "error", err)
294-
if response.StatusCode == http.StatusBadRequest || response.StatusCode == http.StatusConflict {
295+
statusCode := httputil.StatusCode(response)
296+
if statusCode == http.StatusBadRequest || statusCode == http.StatusConflict {
295297
return syncedEndpoints, err
296298
}
297299
}

internal/httputil/code.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package httputil
16+
17+
import "net/http"
18+
19+
const (
20+
HTTP_CODE_UNSET = 0
21+
)
22+
23+
func StatusCode(rsp *http.Response) int {
24+
if rsp == nil {
25+
return HTTP_CODE_UNSET
26+
}
27+
return rsp.StatusCode
28+
}

internal/httputil/diff.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,11 @@ func (t *TransportWithDiff) RoundTrip(req *http.Request) (*http.Response, error)
5959
type cleanupFunc func(map[string]interface{})
6060

6161
func cleanLinksField(data map[string]interface{}) {
62-
if _, ok := data["links"]; ok {
63-
delete(data, "links")
64-
}
62+
delete(data, "links")
6563
}
6664

6765
func cleanCreatedField(data map[string]interface{}) {
68-
if _, ok := data["created"]; ok {
69-
delete(data, "created")
70-
}
66+
delete(data, "created")
7167
}
7268

7369
func (t *TransportWithDiff) tryCalculateDiff(req *http.Request, cleanupFuncs ...cleanupFunc) (string, error) {

internal/httputil/diff_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ func TestTransportWithDiff_Integration(t *testing.T) {
392392
resp, err := transport.RoundTrip(req)
393393

394394
assert.NoError(t, err)
395-
assert.Equal(t, http.StatusOK, resp.StatusCode)
395+
assert.Equal(t, http.StatusOK, StatusCode(resp))
396396

397397
body, _ := io.ReadAll(resp.Body)
398398
assert.Equal(t, "updated", string(body))

internal/httputil/loggedclient.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ func (l loggedRoundTripper) logResponse(req *http.Request, res *http.Response, e
6464
if err != nil {
6565
l.log.Debugf("HTTP Request (%s) %s [time (ms): %d, error=%q]", req.Method, req.URL, duration, err.Error())
6666
} else {
67-
l.log.Debugf("HTTP Request (%s) %s [time (ms): %d, status: %d]", req.Method, req.URL, duration, res.StatusCode)
67+
statusCode := StatusCode(res)
68+
l.log.Debugf("HTTP Request (%s) %s [time (ms): %d, status: %d]", req.Method, req.URL, duration, statusCode)
6869
}
6970
}
7071

internal/translation/atlasorgsettings/service.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
"fmt"
2020

2121
"go.mongodb.org/atlas-sdk/v20250312009/admin"
22+
23+
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/httputil"
2224
)
2325

2426
type AtlasOrgSettingsService interface {
@@ -41,8 +43,9 @@ func (a *AtlasOrgSettingsServiceImpl) Get(ctx context.Context, orgID string) (*A
4143
if err != nil {
4244
return nil, fmt.Errorf("failed to get AtlasOrgSettings: %w", err)
4345
}
44-
if httpResp.StatusCode != 200 {
45-
return nil, fmt.Errorf("failed to get AtlasOrgSettings: expected status code 200. Got: %d", httpResp.StatusCode)
46+
statusCode := httputil.StatusCode(httpResp)
47+
if statusCode != 200 {
48+
return nil, fmt.Errorf("failed to get AtlasOrgSettings: expected status code 200. Got: %d", statusCode)
4649
}
4750

4851
return NewFromAtlas(orgID, resp), nil
@@ -58,8 +61,9 @@ func (a *AtlasOrgSettingsServiceImpl) Update(ctx context.Context, orgID string,
5861
if err != nil {
5962
return nil, fmt.Errorf("failed to update AtlasOrgSettings: %w", err)
6063
}
61-
if httpResp.StatusCode != 201 && httpResp.StatusCode != 200 {
62-
return nil, fmt.Errorf("failed to update AtlasOrgSettings: expected status code 200 or 201. Got: %d", httpResp.StatusCode)
64+
statusCode := httputil.StatusCode(httpResp)
65+
if statusCode != 201 && statusCode != 200 {
66+
return nil, fmt.Errorf("failed to update AtlasOrgSettings: expected status code 200 or 201. Got: %d", statusCode)
6367
}
6468

6569
return NewFromAtlas(orgID, resp), nil

internal/translation/customroles/custom_roles.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"net/http"
2121

2222
"go.mongodb.org/atlas-sdk/v20250312009/admin"
23+
24+
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/httputil"
2325
)
2426

2527
type CustomRoleService interface {
@@ -41,7 +43,7 @@ func NewCustomRoles(api admin.CustomDatabaseRolesApi) *CustomRoles {
4143
func (s *CustomRoles) Get(ctx context.Context, projectID string, roleName string) (CustomRole, error) {
4244
customRole, httpResp, err := s.roleAPI.GetCustomDbRole(ctx, projectID, roleName).Execute()
4345
// handle RoleNotFound error
44-
if httpResp != nil && httpResp.StatusCode == http.StatusNotFound {
46+
if httputil.StatusCode(httpResp) == http.StatusNotFound {
4547
return CustomRole{}, nil
4648
}
4749
if err != nil {

internal/translation/datafederation/datafederation.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
"net/http"
2222

2323
"go.mongodb.org/atlas-sdk/v20250312009/admin"
24+
25+
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/httputil"
2426
)
2527

2628
var (
@@ -45,7 +47,7 @@ func NewAtlasDataFederation(api admin.DataFederationApi) *AtlasDataFederationSer
4547
func (dfs *AtlasDataFederationService) Get(ctx context.Context, projectID, name string) (*DataFederation, error) {
4648
atlasDataFederation, resp, err := dfs.api.GetDataFederation(ctx, projectID, name).Execute()
4749

48-
if resp != nil && resp.StatusCode == http.StatusNotFound {
50+
if httputil.StatusCode(resp) == http.StatusNotFound {
4951
return nil, errors.Join(ErrorNotFound, err)
5052
}
5153

@@ -81,7 +83,7 @@ func (dfs *AtlasDataFederationService) Update(ctx context.Context, df *DataFeder
8183

8284
func (dfs *AtlasDataFederationService) Delete(ctx context.Context, projectID, name string) error {
8385
resp, err := dfs.api.DeleteDataFederation(ctx, projectID, name).Execute()
84-
if resp != nil && resp.StatusCode == http.StatusNotFound {
86+
if httputil.StatusCode(resp) == http.StatusNotFound {
8587
return errors.Join(ErrorNotFound, err)
8688
}
8789
if err != nil {

internal/translation/searchindex/searchIndexsvc.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
"net/http"
2222

2323
"go.mongodb.org/atlas-sdk/v20250312009/admin"
24+
25+
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/httputil"
2426
)
2527

2628
var (
@@ -45,15 +47,16 @@ func NewSearchIndexes(api admin.AtlasSearchApi) *SearchIndexes {
4547

4648
func (si *SearchIndexes) GetIndex(ctx context.Context, projectID, clusterName, indexName, indexID string) (*SearchIndex, error) {
4749
resp, httpResp, err := si.searchAPI.GetClusterSearchIndex(ctx, projectID, clusterName, indexID).Execute()
50+
statusCode := httputil.StatusCode(httpResp)
4851
if err != nil {
49-
if httpResp.StatusCode == http.StatusNotFound {
52+
if statusCode == http.StatusNotFound {
5053
return nil, errors.Join(err, ErrNotFound)
5154
}
5255
return nil, err
5356
}
5457
if resp == nil {
5558
return nil, fmt.Errorf("got empty index %s(%s), status code %d: %w",
56-
indexName, indexID, httpResp.StatusCode, err)
59+
indexName, indexID, statusCode, err)
5760
}
5861
stateInAtlas, err := fromAtlas(*resp)
5962
if err != nil {
@@ -69,8 +72,10 @@ func (si *SearchIndexes) CreateIndex(ctx context.Context, projectID, clusterName
6972
return nil, err
7073
}
7174
resp, httpResp, err := si.searchAPI.CreateClusterSearchIndex(ctx, projectID, clusterName, atlasIndex).Execute()
72-
if err != nil || httpResp.StatusCode != http.StatusCreated && httpResp.StatusCode != http.StatusOK {
73-
return nil, fmt.Errorf("failed to create index, status code %d: %w", httpResp.StatusCode, err)
75+
statusCode := httputil.StatusCode(httpResp)
76+
respNotOK := (statusCode != http.StatusCreated && statusCode != http.StatusOK)
77+
if err != nil || respNotOK {
78+
return nil, fmt.Errorf("failed to create index, status code %d: %w", statusCode, err)
7479
}
7580
if resp == nil {
7681
return nil, errors.New("empty response when creating index")
@@ -84,8 +89,9 @@ func (si *SearchIndexes) CreateIndex(ctx context.Context, projectID, clusterName
8489

8590
func (si *SearchIndexes) DeleteIndex(ctx context.Context, projectID, clusterName, indexID string) error {
8691
resp, err := si.searchAPI.DeleteClusterSearchIndex(ctx, projectID, clusterName, indexID).Execute()
87-
if resp.StatusCode != http.StatusAccepted && resp.StatusCode != http.StatusNotFound || err != nil {
88-
return fmt.Errorf("error deleting index, status code %d: %w", resp.StatusCode, err)
92+
statusCode := httputil.StatusCode(resp)
93+
if statusCode != http.StatusAccepted && statusCode != http.StatusNotFound || err != nil {
94+
return fmt.Errorf("error deleting index, status code %d: %w", statusCode, err)
8995
}
9096
return nil
9197
}
@@ -96,8 +102,10 @@ func (si *SearchIndexes) UpdateIndex(ctx context.Context, projectID, clusterName
96102
return nil, fmt.Errorf("error converting index: %w", err)
97103
}
98104
resp, httpResp, err := si.searchAPI.UpdateClusterSearchIndex(ctx, projectID, clusterName, index.GetID(), atlasIndex).Execute()
99-
if httpResp.StatusCode != http.StatusCreated && httpResp.StatusCode != http.StatusOK || err != nil {
100-
return nil, fmt.Errorf("error updating index, status code %d: %w", httpResp.StatusCode, err)
105+
statusCode := httputil.StatusCode(httpResp)
106+
respNotOK := statusCode != http.StatusCreated && statusCode != http.StatusOK
107+
if respNotOK || err != nil {
108+
return nil, fmt.Errorf("error updating index, status code %d: %w", statusCode, err)
101109
}
102110
if resp == nil {
103111
return nil, fmt.Errorf("update returned an empty index: %w", err)

0 commit comments

Comments
 (0)