Skip to content

Commit c5a831a

Browse files
CLOUDP-304437: Evaluate the use of pre-built bin for api-generator (#3735)
1 parent a7e6910 commit c5a831a

27 files changed

+4274
-4221
lines changed

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ linters-settings:
3131
alias: pluginCmd
3232
- pkg: github.com/mongodb/mongodb-atlas-cli/atlascli/internal/transport
3333
alias: storeTransport
34+
- pkg: github.com/mongodb/mongodb-atlas-cli/atlascli/tools/shared/api
35+
alias: shared_api
3436
misspell:
3537
locale: US
3638
ignore-words:

Makefile

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,11 @@ addcopy: ## Add missing license to files
105105
.PHONY: generate
106106
generate: gen-docs gen-mocks gen-api-commands ## Generate docs, mocks, code, api commands, all auto generated assets
107107

108-
bin/api-generator:
109-
go build -o ./bin/api-generator ./tools/cmd/api-generator
110-
111108
.PHONY: gen-api-commands
112-
gen-api-commands: bin/api-generator ## Generate api commands
109+
gen-api-commands: ## Generate api commands
113110
@echo "==> Generating api commands"
114-
bin/api-generator --spec ./tools/cmd/api-generator/spec.yaml --overlay ./tools/cmd/api-generator/overlays --output-type commands > ./internal/api/commands.go
115-
bin/api-generator --spec ./tools/cmd/api-generator/spec.yaml --overlay ./tools/cmd/api-generator/overlays --output-type metadata > ./tools/cmd/docs/metadata.go
111+
go run ./tools/cmd/api-generator --spec ./tools/cmd/api-generator/spec.yaml --overlay ./tools/cmd/api-generator/overlays --output-type commands > ./internal/api/commands.go
112+
go run ./tools/cmd/api-generator --spec ./tools/cmd/api-generator/spec.yaml --overlay ./tools/cmd/api-generator/overlays --output-type metadata > ./tools/cmd/docs/metadata.go
116113

117114
.PHONY: otel
118115
otel: ## Generate code

internal/api/commands.go

Lines changed: 3980 additions & 3976 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/api/httprequest.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"net/http"
2121
"net/url"
2222
"strings"
23+
24+
shared_api "github.com/mongodb/mongodb-atlas-cli/atlascli/tools/shared/api"
2325
)
2426

2527
var (
@@ -98,7 +100,7 @@ func ConvertToHTTPRequest(baseURL string, request CommandRequest) (*http.Request
98100
// > The default serialization method is style: simple and explode: false.
99101
// > Given the path /users/{id}, the path parameter id is serialized as follows:
100102
// > style: simple + exploded: false, example template /users/{id}, single value: /users/5, array: /users/3,4,5.
101-
func buildPath(path string, commandURLParameters []Parameter, parameterValues map[string][]string) (string, error) {
103+
func buildPath(path string, commandURLParameters []shared_api.Parameter, parameterValues map[string][]string) (string, error) {
102104
for _, commandURLParameter := range commandURLParameters {
103105
values, exist := parameterValues[commandURLParameter.Name]
104106
if !exist || len(values) == 0 {
@@ -120,7 +122,7 @@ func buildPath(path string, commandURLParameters []Parameter, parameterValues ma
120122
// https://swagger.io/docs/specification/v3_0/serialization/#query-parameters
121123
// Our spec only contains the default:
122124
// style: form + exploded: true, example template /users{?id*}, single value: /users?id=5, array: /users?id=3&id=4&id=5
123-
func buildQueryParameters(commandQueryParameters []Parameter, parameterValues map[string][]string) (string, error) {
125+
func buildQueryParameters(commandQueryParameters []shared_api.Parameter, parameterValues map[string][]string) (string, error) {
124126
query := new(url.URL).Query()
125127

126128
for _, commandQueryParameter := range commandQueryParameters {
@@ -143,7 +145,7 @@ func buildQueryParameters(commandQueryParameters []Parameter, parameterValues ma
143145
}
144146

145147
// select a version from a list of versions, throws an error if no match is found.
146-
func selectVersion(versionString string, versions []Version) (*Version, error) {
148+
func selectVersion(versionString string, versions []shared_api.Version) (*shared_api.Version, error) {
147149
for _, version := range versions {
148150
if version.Version == versionString {
149151
return &version, nil
@@ -155,7 +157,7 @@ func selectVersion(versionString string, versions []Version) (*Version, error) {
155157

156158
// generate the accept header using the given format string
157159
// try to find the content type in the list of response content types, if not found set the type to json.
158-
func acceptHeader(version *Version, requestedContentType string) (string, error) {
160+
func acceptHeader(version *shared_api.Version, requestedContentType string) (string, error) {
159161
contentType := ""
160162
supportedTypes := make([]string, 0)
161163

@@ -174,7 +176,7 @@ func acceptHeader(version *Version, requestedContentType string) (string, error)
174176
return fmt.Sprintf("application/vnd.atlas.%s+%s", version.Version, contentType), nil
175177
}
176178

177-
func contentType(version *Version) *string {
179+
func contentType(version *shared_api.Version) *string {
178180
if version.RequestContentType != "" {
179181
contentType := fmt.Sprintf("application/vnd.atlas.%s+%s", version.Version, version.RequestContentType)
180182
return &contentType

internal/api/httprequest_test.go

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ import (
2020
"strings"
2121
"testing"
2222

23+
shared_api "github.com/mongodb/mongodb-atlas-cli/atlascli/tools/shared/api"
2324
"github.com/stretchr/testify/require"
2425
)
2526

2627
func TestBuildQueryParameters(t *testing.T) {
2728
tests := []struct {
2829
name string
29-
commandQueryParameters []Parameter
30+
commandQueryParameters []shared_api.Parameter
3031
parameterValues map[string][]string
3132
shouldFail bool
3233
expectedValue string
@@ -87,7 +88,7 @@ func TestBuildQueryParameters(t *testing.T) {
8788

8889
{
8990
name: "missing query parameters",
90-
commandQueryParameters: []Parameter{{Name: "required-test-query-parameter", Required: true, Type: ParameterType{IsArray: false, Type: TypeBool}}},
91+
commandQueryParameters: []shared_api.Parameter{{Name: "required-test-query-parameter", Required: true, Type: shared_api.ParameterType{IsArray: false, Type: shared_api.TypeBool}}},
9192
parameterValues: map[string][]string{},
9293
shouldFail: true,
9394
},
@@ -111,7 +112,7 @@ func TestBuildPath(t *testing.T) {
111112
tests := []struct {
112113
name string
113114
pathTemplate string
114-
commandURLParameters []Parameter
115+
commandURLParameters []shared_api.Parameter
115116
parameterValues map[string][]string
116117
shouldFail bool
117118
expectedValue string
@@ -154,9 +155,9 @@ func TestBuildPath(t *testing.T) {
154155
{
155156
name: "escape path values",
156157
pathTemplate: "/api/atlas/v2/groups/{groupId}/accessList/{entryValue}",
157-
commandURLParameters: []Parameter{
158-
{Name: "groupId", Required: true, Type: ParameterType{IsArray: false, Type: TypeString}},
159-
{Name: "entryValue", Required: true, Type: ParameterType{IsArray: false, Type: TypeString}},
158+
commandURLParameters: []shared_api.Parameter{
159+
{Name: "groupId", Required: true, Type: shared_api.ParameterType{IsArray: false, Type: shared_api.TypeString}},
160+
{Name: "entryValue", Required: true, Type: shared_api.ParameterType{IsArray: false, Type: shared_api.TypeString}},
160161
},
161162
parameterValues: map[string][]string{
162163
"groupId": {"groupId-01"},
@@ -314,17 +315,17 @@ func TestConvertToHttpRequest(t *testing.T) {
314315

315316
// Please keep fixtures below this command
316317
// Trying to keep this file readable.
317-
var getCollStatsLatencyNamespaceClusterMeasurementsCommand = Command{
318+
var getCollStatsLatencyNamespaceClusterMeasurementsCommand = shared_api.Command{
318319
OperationID: `getCollStatsLatencyNamespaceClusterMeasurements`,
319320
Description: `Get a list of the Coll Stats Latency cluster-level measurements for the given namespace.`,
320-
RequestParameters: RequestParameters{
321+
RequestParameters: shared_api.RequestParameters{
321322
URL: `/api/atlas/v2/groups/{groupId}/clusters/{clusterName}/{clusterView}/{databaseName}/{collectionName}/collStats/measurements`,
322-
QueryParameters: []Parameter{
323+
QueryParameters: []shared_api.Parameter{
323324
{
324325
Name: `envelope`,
325326
Description: `Flag that indicates whether Application wraps the response in an envelope JSON object. Some API clients cannot access the HTTP response headers or status code. To remediate this, set envelope=true in the query. Endpoints that return a list of results use the results object as an envelope. Application adds the status parameter to the response body.`,
326327
Required: false,
327-
Type: ParameterType{
328+
Type: shared_api.ParameterType{
328329
IsArray: false,
329330
Type: `bool`,
330331
},
@@ -333,7 +334,7 @@ var getCollStatsLatencyNamespaceClusterMeasurementsCommand = Command{
333334
Name: `metrics`,
334335
Description: `List that contains the metrics that you want to retrieve for the associated data series. If you don't set this parameter, this resource returns data series for all Coll Stats Latency metrics.`,
335336
Required: false,
336-
Type: ParameterType{
337+
Type: shared_api.ParameterType{
337338
IsArray: true,
338339
Type: `string`,
339340
},
@@ -342,7 +343,7 @@ var getCollStatsLatencyNamespaceClusterMeasurementsCommand = Command{
342343
Name: `start`,
343344
Description: `Date and time when MongoDB Cloud begins reporting the metrics. This parameter expresses its value in the ISO 8601 timestamp format in UTC. Include this parameter when you do not set period.`,
344345
Required: false,
345-
Type: ParameterType{
346+
Type: shared_api.ParameterType{
346347
IsArray: false,
347348
Type: `string`,
348349
},
@@ -351,7 +352,7 @@ var getCollStatsLatencyNamespaceClusterMeasurementsCommand = Command{
351352
Name: `end`,
352353
Description: `Date and time when MongoDB Cloud stops reporting the metrics. This parameter expresses its value in the ISO 8601 timestamp format in UTC. Include this parameter when you do not set period.`,
353354
Required: false,
354-
Type: ParameterType{
355+
Type: shared_api.ParameterType{
355356
IsArray: false,
356357
Type: `string`,
357358
},
@@ -360,21 +361,21 @@ var getCollStatsLatencyNamespaceClusterMeasurementsCommand = Command{
360361
Name: `period`,
361362
Description: `Duration over which Atlas reports the metrics. This parameter expresses its value in the ISO 8601 duration format in UTC. Include this parameter when you do not set start and end.`,
362363
Required: false,
363-
Type: ParameterType{
364+
Type: shared_api.ParameterType{
364365
IsArray: false,
365366
Type: `string`,
366367
},
367368
},
368369
},
369-
URLParameters: []Parameter{
370+
URLParameters: []shared_api.Parameter{
370371
{
371372
Name: `groupId`,
372373
Description: `Unique 24-hexadecimal digit string that identifies your project. Use the /groups endpoint to retrieve all projects to which the authenticated user has access.
373374
374375
375376
NOTE: Groups and projects are synonymous terms. Your group id is the same as your project id. For existing groups, your group/project id remains the same. The resource and corresponding endpoints use the term groups.`,
376377
Required: true,
377-
Type: ParameterType{
378+
Type: shared_api.ParameterType{
378379
IsArray: false,
379380
Type: `string`,
380381
},
@@ -383,7 +384,7 @@ NOTE: Groups and projects are synonymous terms. Your group id is the same as you
383384
Name: `clusterName`,
384385
Description: `Human-readable label that identifies the cluster to retrieve metrics for.`,
385386
Required: true,
386-
Type: ParameterType{
387+
Type: shared_api.ParameterType{
387388
IsArray: false,
388389
Type: `string`,
389390
},
@@ -392,7 +393,7 @@ NOTE: Groups and projects are synonymous terms. Your group id is the same as you
392393
Name: `clusterView`,
393394
Description: `Human-readable label that identifies the cluster topology to retrieve metrics for.`,
394395
Required: true,
395-
Type: ParameterType{
396+
Type: shared_api.ParameterType{
396397
IsArray: false,
397398
Type: `string`,
398399
},
@@ -401,7 +402,7 @@ NOTE: Groups and projects are synonymous terms. Your group id is the same as you
401402
Name: `databaseName`,
402403
Description: `Human-readable label that identifies the database.`,
403404
Required: true,
404-
Type: ParameterType{
405+
Type: shared_api.ParameterType{
405406
IsArray: false,
406407
Type: `string`,
407408
},
@@ -410,15 +411,15 @@ NOTE: Groups and projects are synonymous terms. Your group id is the same as you
410411
Name: `collectionName`,
411412
Description: `Human-readable label that identifies the collection.`,
412413
Required: true,
413-
Type: ParameterType{
414+
Type: shared_api.ParameterType{
414415
IsArray: false,
415416
Type: `string`,
416417
},
417418
},
418419
},
419420
Verb: http.MethodGet,
420421
},
421-
Versions: []Version{
422+
Versions: []shared_api.Version{
422423
{
423424
Version: `2023-11-15`,
424425
RequestContentType: ``,
@@ -429,17 +430,17 @@ NOTE: Groups and projects are synonymous terms. Your group id is the same as you
429430
},
430431
}
431432

432-
var createClusterCommand = Command{
433+
var createClusterCommand = shared_api.Command{
433434
OperationID: `createCluster`,
434435
Description: `Creates one cluster in the specified project. Clusters contain a group of hosts that maintain the same data set. This resource can create clusters with asymmetrically-sized shards. Each project supports up to 25 database deployments. To use this resource, the requesting API Key must have the Project Owner role. This feature is not available for serverless clusters.`,
435-
RequestParameters: RequestParameters{
436+
RequestParameters: shared_api.RequestParameters{
436437
URL: `/api/atlas/v2/groups/{groupId}/clusters`,
437-
QueryParameters: []Parameter{
438+
QueryParameters: []shared_api.Parameter{
438439
{
439440
Name: `envelope`,
440441
Description: `Flag that indicates whether Application wraps the response in an envelope JSON object. Some API clients cannot access the HTTP response headers or status code. To remediate this, set envelope=true in the query. Endpoints that return a list of results use the results object as an envelope. Application adds the status parameter to the response body.`,
441442
Required: false,
442-
Type: ParameterType{
443+
Type: shared_api.ParameterType{
443444
IsArray: false,
444445
Type: `bool`,
445446
},
@@ -448,29 +449,29 @@ var createClusterCommand = Command{
448449
Name: `pretty`,
449450
Description: `Flag that indicates whether the response body should be in the prettyprint format.`,
450451
Required: false,
451-
Type: ParameterType{
452+
Type: shared_api.ParameterType{
452453
IsArray: false,
453454
Type: `bool`,
454455
},
455456
},
456457
},
457-
URLParameters: []Parameter{
458+
URLParameters: []shared_api.Parameter{
458459
{
459460
Name: `groupId`,
460461
Description: `Unique 24-hexadecimal digit string that identifies your project. Use the /groups endpoint to retrieve all projects to which the authenticated user has access.
461462
462463
463464
NOTE: Groups and projects are synonymous terms. Your group id is the same as your project id. For existing groups, your group/project id remains the same. The resource and corresponding endpoints use the term groups.`,
464465
Required: true,
465-
Type: ParameterType{
466+
Type: shared_api.ParameterType{
466467
IsArray: false,
467468
Type: `string`,
468469
},
469470
},
470471
},
471472
Verb: http.MethodPost,
472473
},
473-
Versions: []Version{
474+
Versions: []shared_api.Version{
474475
{
475476
Version: `2023-01-01`,
476477
RequestContentType: `json`,

internal/api/interface.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
"context"
1919
"io"
2020
"net/http"
21+
22+
"github.com/mongodb/mongodb-atlas-cli/atlascli/tools/shared/api"
2123
)
2224

2325
type CommandExecutor interface {
@@ -37,7 +39,7 @@ type CommandConverter interface {
3739
}
3840

3941
type CommandRequest struct {
40-
Command Command
42+
Command api.Command
4143
Content io.Reader
4244
ContentType string
4345
Format string

internal/api/watcher.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"time"
2727

2828
"github.com/PaesslerAG/jsonpath"
29+
"github.com/mongodb/mongodb-atlas-cli/atlascli/tools/shared/api"
2930
)
3031

3132
var (
@@ -51,7 +52,7 @@ const (
5152
type Watcher struct {
5253
executor CommandExecutor
5354
request *CommandRequest
54-
expect *WatcherExpectProperties
55+
expect *api.WatcherExpectProperties
5556
}
5657

5758
// Create a new watcher
@@ -62,7 +63,7 @@ type Watcher struct {
6263
// were used to execute the deleteCluster operation.
6364
// - responseBody: the body from the preceding call
6465
// - props: the watcher configuration, this is generated using the api-generator tool
65-
func NewWatcher(executor CommandExecutor, requestParams map[string][]string, responseBody []byte, props WatcherProperties) (*Watcher, error) {
66+
func NewWatcher(executor CommandExecutor, requestParams map[string][]string, responseBody []byte, props api.WatcherProperties) (*Watcher, error) {
6667
// We're making the same request over and over again, so we only have to build it once
6768
request, err := buildRequest(Commands, requestParams, responseBody, props)
6869
if err != nil || request == nil {
@@ -80,9 +81,9 @@ func NewWatcher(executor CommandExecutor, requestParams map[string][]string, res
8081
//
8182
// - `allCommands`, array with all command definitions, realistically this will always be the static `Commands` variable, but this allows easier unit testing
8283
// See `NewWatcher` for other parameter descriptions.
83-
func buildRequest(allCommands GroupedAndSortedCommands, requestParams map[string][]string, responseBody []byte, props WatcherProperties) (*CommandRequest, error) {
84+
func buildRequest(allCommands api.GroupedAndSortedCommands, requestParams map[string][]string, responseBody []byte, props api.WatcherProperties) (*CommandRequest, error) {
8485
// Search for the command definition that we're expected to execute
85-
var command *Command
86+
var command *api.Command
8687
for _, commandGroup := range allCommands {
8788
for _, loopCommand := range commandGroup.Commands {
8889
if loopCommand.OperationID == props.Get.OperationID {
@@ -164,7 +165,7 @@ func (w *Watcher) WatchOne(ctx context.Context) (bool, error) {
164165
}
165166

166167
// Actual watcher logic without handling.
167-
func watchInner(ctx context.Context, executor CommandExecutor, expect *WatcherExpectProperties, commandRequest CommandRequest) (bool, error) {
168+
func watchInner(ctx context.Context, executor CommandExecutor, expect *api.WatcherExpectProperties, commandRequest CommandRequest) (bool, error) {
168169
// execute the command using the executor
169170
response, err := executor.ExecuteCommand(ctx, commandRequest)
170171
if err != nil {

0 commit comments

Comments
 (0)