diff --git a/CHANGELOG.md b/CHANGELOG.md index dc62eaf..4889e39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [1.6.0](https://github.com/cloudquery/cloudquery-api-go/compare/v1.5.1...v1.6.0) (2023-11-16) + + +### Features + +* Add method to return token type ([#75](https://github.com/cloudquery/cloudquery-api-go/issues/75)) ([e07af9f](https://github.com/cloudquery/cloudquery-api-go/commit/e07af9f5d7ff20cee004d497a30a50427ee31790)) + + +### Bug Fixes + +* Generate CloudQuery Go API Client from `spec.json` ([#73](https://github.com/cloudquery/cloudquery-api-go/issues/73)) ([db26b9c](https://github.com/cloudquery/cloudquery-api-go/commit/db26b9c0db72240072ef5f075a098c0c6153b6bc)) + ## [1.5.1](https://github.com/cloudquery/cloudquery-api-go/compare/v1.5.0...v1.5.1) (2023-11-15) diff --git a/auth/token.go b/auth/token.go index e0f8b04..aadab9a 100644 --- a/auth/token.go +++ b/auth/token.go @@ -66,8 +66,8 @@ func NewTokenClient() *TokenClient { // GetToken returns the ID token // If CLOUDQUERY_API_KEY is set, it returns that value, otherwise it returns an ID token generated from the refresh token. func (tc *TokenClient) GetToken() (Token, error) { - if token := os.Getenv(EnvVarCloudQueryAPIKey); token != "" { - return Token{Type: APIKey, Value: token}, nil + if tc.GetTokenType() == APIKey { + return Token{Type: APIKey, Value: os.Getenv(EnvVarCloudQueryAPIKey)}, nil } // If the token is not expired, return it @@ -98,6 +98,14 @@ func (tc *TokenClient) GetToken() (Token, error) { return Token{Type: BearerToken, Value: tc.idToken}, nil } +// GetTokenType returns the type of token that will be returned by GetToken +func (tc *TokenClient) GetTokenType() TokenType { + if token := os.Getenv(EnvVarCloudQueryAPIKey); token != "" { + return APIKey + } + return BearerToken +} + func (tc *TokenClient) generateToken(refreshToken string) (*tokenResponse, error) { data := url.Values{} data.Set("grant_type", "refresh_token") diff --git a/auth/token_test.go b/auth/token_test.go index 799683d..dbc8e56 100644 --- a/auth/token_test.go +++ b/auth/token_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -103,6 +104,20 @@ func TestTokenClient_GetToken_LongExpiry(t *testing.T) { require.Equal(t, Token{Type: BearerToken, Value: "my_id_token_0"}, token, "expected to reuse token") } +func TestTokenClient_BearerTokenType(t *testing.T) { + tc := NewTokenClient() + + assert.Equal(t, BearerToken, tc.GetTokenType()) +} + +func TestTokenClient_APIKeyTokenType(t *testing.T) { + t.Setenv(EnvVarCloudQueryAPIKey, "my_token") + + tc := NewTokenClient() + + assert.Equal(t, APIKey, tc.GetTokenType()) +} + func overrideEnvironmentVariable(t *testing.T, key, value string) func() { originalValue := os.Getenv(key) resetFn := func() { diff --git a/client.gen.go b/client.gen.go index 8813281..1e63336 100644 --- a/client.gen.go +++ b/client.gen.go @@ -219,6 +219,9 @@ type ClientInterface interface { UpdateTeam(ctx context.Context, teamName TeamName, body UpdateTeamJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // ListAddonOrdersByTeam request + ListAddonOrdersByTeam(ctx context.Context, teamName TeamName, params *ListAddonOrdersByTeamParams, reqEditors ...RequestEditorFn) (*http.Response, error) + // DeleteAddonsByTeam request DeleteAddonsByTeam(ctx context.Context, teamName TeamName, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -894,6 +897,18 @@ func (c *Client) UpdateTeam(ctx context.Context, teamName TeamName, body UpdateT return c.Client.Do(req) } +func (c *Client) ListAddonOrdersByTeam(ctx context.Context, teamName TeamName, params *ListAddonOrdersByTeamParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewListAddonOrdersByTeamRequest(c.Server, teamName, params) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) DeleteAddonsByTeam(ctx context.Context, teamName TeamName, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewDeleteAddonsByTeamRequest(c.Server, teamName) if err != nil { @@ -3485,6 +3500,78 @@ func NewUpdateTeamRequestWithBody(server string, teamName TeamName, contentType return req, nil } +// NewListAddonOrdersByTeamRequest generates requests for ListAddonOrdersByTeam +func NewListAddonOrdersByTeamRequest(server string, teamName TeamName, params *ListAddonOrdersByTeamParams) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "team_name", runtime.ParamLocationPath, teamName) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/teams/%s/addon-orders", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + if params != nil { + queryValues := queryURL.Query() + + if params.Page != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "page", runtime.ParamLocationQuery, *params.Page); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + if params.PerPage != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "per_page", runtime.ParamLocationQuery, *params.PerPage); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + + queryURL.RawQuery = queryValues.Encode() + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + // NewDeleteAddonsByTeamRequest generates requests for DeleteAddonsByTeam func NewDeleteAddonsByTeamRequest(server string, teamName TeamName) (*http.Request, error) { var err error @@ -5269,6 +5356,9 @@ type ClientWithResponsesInterface interface { UpdateTeamWithResponse(ctx context.Context, teamName TeamName, body UpdateTeamJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateTeamResponse, error) + // ListAddonOrdersByTeamWithResponse request + ListAddonOrdersByTeamWithResponse(ctx context.Context, teamName TeamName, params *ListAddonOrdersByTeamParams, reqEditors ...RequestEditorFn) (*ListAddonOrdersByTeamResponse, error) + // DeleteAddonsByTeamWithResponse request DeleteAddonsByTeamWithResponse(ctx context.Context, teamName TeamName, reqEditors ...RequestEditorFn) (*DeleteAddonsByTeamResponse, error) @@ -6275,6 +6365,35 @@ func (r UpdateTeamResponse) StatusCode() int { return 0 } +type ListAddonOrdersByTeamResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *struct { + Items []AddonOrder `json:"items"` + Metadata ListMetadata `json:"metadata"` + } + JSON401 *RequiresAuthentication + JSON403 *Forbidden + JSON404 *NotFound + JSON500 *InternalError +} + +// Status returns HTTPResponse.Status +func (r ListAddonOrdersByTeamResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r ListAddonOrdersByTeamResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type DeleteAddonsByTeamResponse struct { Body []byte HTTPResponse *http.Response @@ -7442,6 +7561,15 @@ func (c *ClientWithResponses) UpdateTeamWithResponse(ctx context.Context, teamNa return ParseUpdateTeamResponse(rsp) } +// ListAddonOrdersByTeamWithResponse request returning *ListAddonOrdersByTeamResponse +func (c *ClientWithResponses) ListAddonOrdersByTeamWithResponse(ctx context.Context, teamName TeamName, params *ListAddonOrdersByTeamParams, reqEditors ...RequestEditorFn) (*ListAddonOrdersByTeamResponse, error) { + rsp, err := c.ListAddonOrdersByTeam(ctx, teamName, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseListAddonOrdersByTeamResponse(rsp) +} + // DeleteAddonsByTeamWithResponse request returning *DeleteAddonsByTeamResponse func (c *ClientWithResponses) DeleteAddonsByTeamWithResponse(ctx context.Context, teamName TeamName, reqEditors ...RequestEditorFn) (*DeleteAddonsByTeamResponse, error) { rsp, err := c.DeleteAddonsByTeam(ctx, teamName, reqEditors...) @@ -9594,6 +9722,63 @@ func ParseUpdateTeamResponse(rsp *http.Response) (*UpdateTeamResponse, error) { return response, nil } +// ParseListAddonOrdersByTeamResponse parses an HTTP response from a ListAddonOrdersByTeamWithResponse call +func ParseListAddonOrdersByTeamResponse(rsp *http.Response) (*ListAddonOrdersByTeamResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &ListAddonOrdersByTeamResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest struct { + Items []AddonOrder `json:"items"` + Metadata ListMetadata `json:"metadata"` + } + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest RequiresAuthentication + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403: + var dest Forbidden + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON403 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404: + var dest NotFound + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON404 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest InternalError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + // ParseDeleteAddonsByTeamResponse parses an HTTP response from a DeleteAddonsByTeamWithResponse call func ParseDeleteAddonsByTeamResponse(rsp *http.Response) (*DeleteAddonsByTeamResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/models.gen.go b/models.gen.go index bdf53ca..dc7f1ff 100644 --- a/models.gen.go +++ b/models.gen.go @@ -265,6 +265,22 @@ type AddonFormat string // AddonName The unique name for the addon. type AddonName = string +// AddonOrder CloudQuery Addon Order +type AddonOrder struct { + // AddonName The unique name for the addon. + AddonName AddonName `json:"addon_name"` + + // AddonTeam The unique name for the team. + AddonTeam TeamName `json:"addon_team"` + + // AddonType Supported types for addons + AddonType AddonType `json:"addon_type"` + PurchaseDate time.Time `json:"purchase_date"` + + // TeamName The unique name for the team. + TeamName TeamName `json:"team_name"` +} + // AddonTier Supported tiers for addons type AddonTier string @@ -1201,6 +1217,15 @@ type UpdateTeamJSONBody struct { DisplayName *string `json:"display_name,omitempty"` } +// ListAddonOrdersByTeamParams defines parameters for ListAddonOrdersByTeam. +type ListAddonOrdersByTeamParams struct { + // Page Page number of the results to fetch + Page *Page `form:"page,omitempty" json:"page,omitempty"` + + // PerPage The number of results per page (max 1000). + PerPage *PerPage `form:"per_page,omitempty" json:"per_page,omitempty"` +} + // ListAddonsByTeamParams defines parameters for ListAddonsByTeam. type ListAddonsByTeamParams struct { // Page Page number of the results to fetch diff --git a/spec.json b/spec.json index 4387f32..062ac91 100644 --- a/spec.json +++ b/spec.json @@ -2283,6 +2283,64 @@ ] } }, + "/teams/{team_name}/addon-orders": { + "get": { + "description": "List all addon orders for the team.", + "operationId": "ListAddonOrdersByTeam", + "parameters": [ + { + "$ref": "#/components/parameters/team_name" + }, + { + "$ref": "#/components/parameters/page" + }, + { + "$ref": "#/components/parameters/per_page" + } + ], + "responses": { + "200": { + "description": "Response", + "content": { + "application/json": { + "schema": { + "required": [ + "items", + "metadata" + ], + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/AddonOrder" + }, + "type": "array" + }, + "metadata": { + "$ref": "#/components/schemas/ListMetadata" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/RequiresAuthentication" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + }, + "tags": [ + "addons" + ] + } + }, "/teams/{team_name}/memberships": { "get": { "description": "Get memberships to the team.", @@ -4743,6 +4801,38 @@ "title": "Team", "type": "object" }, + "AddonOrder": { + "additionalProperties": false, + "description": "CloudQuery Addon Order", + "properties": { + "team_name": { + "$ref": "#/components/schemas/TeamName" + }, + "addon_team": { + "$ref": "#/components/schemas/TeamName" + }, + "addon_type": { + "$ref": "#/components/schemas/AddonType" + }, + "addon_name": { + "$ref": "#/components/schemas/AddonName" + }, + "purchase_date": { + "type": "string", + "format": "date-time", + "example": "2017-07-14T16:53:42Z" + } + }, + "required": [ + "team_name", + "addon_team", + "addon_type", + "addon_name", + "purchase_date" + ], + "title": "CloudQuery Addon", + "type": "object" + }, "Email": { "type": "string", "example": "user@cloudquery.io",