• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb / mongodb-atlas-cli / 16772291600

06 Aug 2025 08:54AM UTC coverage: 57.87%. First build
16772291600

Pull #4090

github

cveticm
plugs sa into httpclient and withAuthentication
Pull Request #4090: CLOUDP-329787: Make Service Account transport available in httpClient()

17 of 48 new or added lines in 5 files covered. (35.42%)

23800 of 41127 relevant lines covered (57.87%)

2.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

49.33
/internal/cli/commonerrors/errors.go
1
// Copyright 2022 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 commonerrors
16

17
import (
18
        "errors"
19
        "net/http"
20

21
        atlasClustersPinned "go.mongodb.org/atlas-sdk/v20240530005/admin"
22
        atlasv2 "go.mongodb.org/atlas-sdk/v20250312005/admin"
23
        atlas "go.mongodb.org/atlas/mongodbatlas"
24
        "golang.org/x/oauth2"
25
)
26

27
var (
28
        errClusterUnsupported         = errors.New("atlas supports this command only for M10+ clusters. You can upgrade your cluster by running the 'atlas cluster upgrade' command")
29
        errOutsideVPN                 = errors.New("forbidden action outside access allow list, if you are a MongoDB employee double check your VPN connection")
30
        errAsymmetricShardUnsupported = errors.New("trying to run a cluster wide scaling command on an independent shard scaling cluster. Use --autoScalingMode 'independentShardScaling' instead")
31
        ErrUnauthorized               = errors.New(`this action requires authentication
32
        
33
To log in using your Atlas username and password or to set credentials using API keys, run: atlas auth login`)
34
        ErrInvalidRefreshToken = errors.New(`session expired
35

36
Please note that your session expires periodically. 
37
If you use Atlas CLI for automation, see https://www.mongodb.com/docs/atlas/cli/stable/atlas-cli-automate/ for best practices.
38
To login, run: atlas auth login`)
39
)
40

41
const (
42
        unknownErrorCode                        = "UNKNOWN_ERROR"
43
        asymmetricShardUnsupportedErrorCode     = "ASYMMETRIC_SHARD_UNSUPPORTED"
44
        tenantClusterUpdateUnsupportedErrorCode = "TENANT_CLUSTER_UPDATE_UNSUPPORTED"
45
        globalUserOutsideSubnetErrorCode        = "GLOBAL_USER_OUTSIDE_SUBNET"
46
        unauthorizedErrorCode                   = "UNAUTHORIZED"
47
        invalidRefreshTokenErrorCode            = "INVALID_REFRESH_TOKEN"
48
)
49

50
// Check checks the error and returns a more user-friendly error message if applicable.
51
func Check(err error) error {
1✔
52
        if err == nil {
2✔
53
                return nil
1✔
54
        }
1✔
55

56
        apiErrorCode := getErrorCode(err)
1✔
57

1✔
58
        switch apiErrorCode {
1✔
59
        case unauthorizedErrorCode:
×
60
                return ErrUnauthorized
×
61
        case invalidRefreshTokenErrorCode:
×
62
                return ErrInvalidRefreshToken
×
63
        case tenantClusterUpdateUnsupportedErrorCode:
×
64
                return errClusterUnsupported
×
65
        case globalUserOutsideSubnetErrorCode:
×
66
                return errOutsideVPN
×
67
        case asymmetricShardUnsupportedErrorCode:
×
68
                return errAsymmetricShardUnsupported
×
NEW
69
        case "invalid_client": // oauth2 error
×
NEW
70
                return ErrUnauthorized
×
71
        }
72

73
        apiError := getError(err) // some `Unauthorized` errors do not have an error code, so we check the HTTP status code
1✔
74

1✔
75
        if apiError == http.StatusUnauthorized {
2✔
76
                return ErrUnauthorized
1✔
77
        }
1✔
78

79
        return err
1✔
80
}
81

82
// getErrorCode extracts the error code from the error if it is an Atlas error.
83
// This function checks for v2 SDK, the pinned clusters SDK and the old SDK errors.
84
// If the error is not any of these Atlas errors, it returns "UNKNOWN_ERROR".
85
func getErrorCode(err error) string {
1✔
86
        if err == nil {
1✔
87
                return unknownErrorCode
×
88
        }
×
89

90
        var atlasErr *atlas.ErrorResponse
1✔
91
        if errors.As(err, &atlasErr) {
1✔
92
                return atlasErr.ErrorCode
×
93
        }
×
94
        if sdkError, ok := atlasv2.AsError(err); ok {
2✔
95
                return sdkError.ErrorCode
1✔
96
        }
1✔
97
        if sdkPinnedError, ok := atlasClustersPinned.AsError(err); ok {
1✔
98
                return sdkPinnedError.GetErrorCode()
×
99
        }
×
100
        var oauth2Err *oauth2.RetrieveError
1✔
101
        if errors.As(err, &oauth2Err) {
1✔
NEW
102
                return oauth2Err.ErrorCode
×
NEW
103
        }
×
104

105
        return unknownErrorCode
1✔
106
}
107

108
// getError extracts the HTTP error code from the error if it is an Atlas error.
109
// This function checks for v2 SDK, the pinned clusters SDK and the old SDK errors.
110
// If the error is not any of these Atlas errors, it returns 0.
111
func getError(err error) int {
1✔
112
        if err == nil {
1✔
113
                return 0
×
114
        }
×
115

116
        var atlasErr *atlas.ErrorResponse
1✔
117
        if errors.As(err, &atlasErr) {
1✔
118
                return atlasErr.HTTPCode
×
119
        }
×
120
        if apiError, ok := atlasv2.AsError(err); ok {
2✔
121
                return apiError.GetError()
1✔
122
        }
1✔
123
        if apiPinnedError, ok := atlasClustersPinned.AsError(err); ok {
1✔
124
                return apiPinnedError.GetError()
×
125
        }
×
126

127
        return 0
1✔
128
}
129

130
func IsAsymmetricShardUnsupported(err error) bool {
×
131
        apiError, ok := atlasv2.AsError(err)
×
132
        if !ok {
×
133
                return false
×
134
        }
×
135
        return apiError.GetErrorCode() == asymmetricShardUnsupportedErrorCode
×
136
}
137

138
func IsCannotUseFlexWithClusterApis(err error) bool {
1✔
139
        apiError, ok := atlasv2.AsError(err)
1✔
140
        if !ok {
1✔
141
                return false
×
142
        }
×
143
        return apiError.GetErrorCode() == "CANNOT_USE_FLEX_CLUSTER_IN_CLUSTER_API"
1✔
144
}
145

146
func IsInvalidRefreshToken(err error) bool {
×
147
        errCode := getErrorCode(err)
×
148
        return errCode == invalidRefreshTokenErrorCode
×
149
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc