Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

Commit

Permalink
feat: Add v2.KeptnInterface that adds context.Context support to …
Browse files Browse the repository at this point in the history
…`api.KeptnInterface` (#449)

* Add `context.Context` to request methods

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add get method

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Use get methods

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `APIV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `AuthV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `EventsV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `LogsV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `ProjectsV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add initial context support to `ResourcesV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `ResourcesV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `SecretsV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `SequencesV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `ServicesV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `ShipyardControlV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `StagesV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `UniformV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add context to `Keptn` and `KeptnBase`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix comments

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Introduce APIV2Interface

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Second option: APIV2Interface with `...WithContext` methods

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Create `v2` as duplicate of `api` package

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.AuthInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.EventsInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.LogsInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.ProjectsInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.ResourcesInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.SecretsInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.SequencesInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.ServicesInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.ShipyardControlInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.StagesInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.UniformInterface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix `v2.Client`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* APIHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* AuthHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* EventHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* LogHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* ProjectHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* SecretHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* SequenceControlHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* ServiceHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* ShipyardControllerHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* StageHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* UniformHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Revert "Add context to `Keptn` and `KeptnBase`"

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Remove redundant test

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Revert `ResourcesV1Interface`

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Rename and export implementation methods

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Fix options for `v2.ResourceHandler` methods

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* ResourceHandler: v1 embeds v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Remove redundant test

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add construction functions

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Harmonize construction functions

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Remove deprecated functions from v2

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add v2 construction functions

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Polish v2 handlers

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* Add missing functions for APIHandler

Signed-off-by: Arthur Pitman <arthur.pitman@dynatrace.com>

* added missing api handler in GetMetadata()

Signed-off-by: Florian Bacher <florian.bacher@dynatrace.com>

* added alias for v2.ResourceNotFoundError to stay backwards compatible

Signed-off-by: Florian Bacher <florian.bacher@dynatrace.com>

* fix: Make sure all api handlers are set when using v2 api handlers in v1 (#479)

* debug output

Signed-off-by: Florian Bacher <florian.bacher@dynatrace.com>

* debug output

Signed-off-by: Florian Bacher <florian.bacher@dynatrace.com>

* ensure that uniform handler is set

Signed-off-by: Florian Bacher <florian.bacher@dynatrace.com>

* ensure that uniform handler is set

Signed-off-by: Florian Bacher <florian.bacher@dynatrace.com>

* ensure that all api handlers are set

Signed-off-by: Florian Bacher <florian.bacher@dynatrace.com>

Co-authored-by: Florian Bacher <florian.bacher@dynatrace.com>
  • Loading branch information
arthurpitman and bacherfl committed Jun 23, 2022
1 parent 647fbac commit 0874051
Show file tree
Hide file tree
Showing 43 changed files with 4,738 additions and 1,405 deletions.
163 changes: 104 additions & 59 deletions pkg/api/utils/apiServiceUtils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
"bytes"
"context"
"crypto/tls"
"fmt"
"io/ioutil"
Expand Down Expand Up @@ -61,11 +62,66 @@ func getClientTransport(rt http.RoundTripper) http.RoundTripper {
return tr
}
return rt
}

func getAndExpectOK(ctx context.Context, uri string, api APIService) ([]byte, *models.Error) {
body, statusCode, status, err := get(ctx, uri, api)
if err != nil {
return nil, err
}

if statusCode == 200 {
return body, nil
}

if len(body) > 0 {
return nil, handleErrStatusCode(statusCode, body)
}

return nil, buildErrorResponse(fmt.Sprintf("Received unexpected response: %d %s", statusCode, status))
}

func putWithEventContext(uri string, data []byte, api APIService) (*models.EventContext, *models.Error) {
req, err := http.NewRequest("PUT", uri, bytes.NewBuffer(data))
func getAndExpectSuccess(ctx context.Context, uri string, api APIService) ([]byte, *models.Error) {
body, statusCode, status, err := get(ctx, uri, api)
if err != nil {
return nil, err
}

if statusCode >= 200 && statusCode < 300 {
return body, nil
}

if len(body) > 0 {
return nil, handleErrStatusCode(statusCode, body)
}

return nil, buildErrorResponse(fmt.Sprintf("Received unexpected response: %d %s", statusCode, status))
}

func get(ctx context.Context, uri string, api APIService) ([]byte, int, string, *models.Error) {
req, err := http.NewRequestWithContext(ctx, "GET", uri, nil)
if err != nil {
return nil, 0, "", buildErrorResponse(err.Error())
}
req.Header.Set("Content-Type", "application/json")
addAuthHeader(req, api)

resp, err := api.getHTTPClient().Do(req)
if err != nil {
return nil, 0, "", buildErrorResponse(err.Error())
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, 0, "", buildErrorResponse(err.Error())
}

return body, resp.StatusCode, resp.Status, nil
}

func putWithEventContext(ctx context.Context, uri string, data []byte, api APIService) (*models.EventContext, *models.Error) {
req, err := http.NewRequestWithContext(ctx, "PUT", uri, bytes.NewBuffer(data))
if err != nil {
return nil, buildErrorResponse(err.Error())
}
Expand All @@ -84,20 +140,21 @@ func putWithEventContext(uri string, data []byte, api APIService) (*models.Event
}

if resp.StatusCode >= 200 && resp.StatusCode <= 204 {
if len(body) > 0 {
eventContext := &models.EventContext{}
if err = eventContext.FromJSON(body); err != nil {
// failed to parse json
return nil, buildErrorResponse(err.Error() + "\n" + "-----DETAILS-----" + string(body))
}

if eventContext.KeptnContext != nil {
fmt.Println("ID of Keptn context: " + *eventContext.KeptnContext)
}
return eventContext, nil
if len(body) == 0 {
return nil, nil
}

eventContext := &models.EventContext{}

if err = eventContext.FromJSON(body); err != nil {
// failed to parse json
return nil, buildErrorResponse(err.Error() + "\n" + "-----DETAILS-----" + string(body))
}

return nil, nil
if eventContext.KeptnContext != nil {
fmt.Println("ID of Keptn context: " + *eventContext.KeptnContext)
}
return eventContext, nil
}

if len(body) > 0 {
Expand All @@ -107,8 +164,8 @@ func putWithEventContext(uri string, data []byte, api APIService) (*models.Event
return nil, buildErrorResponse(fmt.Sprintf("Received unexpected response: %d %s", resp.StatusCode, resp.Status))
}

func put(uri string, data []byte, api APIService) (string, *models.Error) {
req, err := http.NewRequest("PUT", uri, bytes.NewBuffer(data))
func put(ctx context.Context, uri string, data []byte, api APIService) (string, *models.Error) {
req, err := http.NewRequestWithContext(ctx, "PUT", uri, bytes.NewBuffer(data))
if err != nil {
return "", buildErrorResponse(err.Error())
}
Expand All @@ -127,11 +184,7 @@ func put(uri string, data []byte, api APIService) (string, *models.Error) {
}

if resp.StatusCode >= 200 && resp.StatusCode <= 204 {
if len(body) > 0 {
return string(body), nil
}

return "", nil
return string(body), nil
}

if len(body) > 0 {
Expand All @@ -141,8 +194,8 @@ func put(uri string, data []byte, api APIService) (string, *models.Error) {
return "", buildErrorResponse(fmt.Sprintf("Received unexpected response: %d %s", resp.StatusCode, resp.Status))
}

func postWithEventContext(uri string, data []byte, api APIService) (*models.EventContext, *models.Error) {
req, err := http.NewRequest("POST", uri, bytes.NewBuffer(data))
func postWithEventContext(ctx context.Context, uri string, data []byte, api APIService) (*models.EventContext, *models.Error) {
req, err := http.NewRequestWithContext(ctx, "POST", uri, bytes.NewBuffer(data))
if err != nil {
return nil, buildErrorResponse(err.Error())
}
Expand All @@ -161,20 +214,20 @@ func postWithEventContext(uri string, data []byte, api APIService) (*models.Even
}

if resp.StatusCode >= 200 && resp.StatusCode <= 204 {
if len(body) > 0 {
eventContext := &models.EventContext{}
if err = eventContext.FromJSON(body); err != nil {
// failed to parse json
return nil, buildErrorResponse(err.Error() + "\n" + "-----DETAILS-----" + string(body))
}

if eventContext.KeptnContext != nil {
fmt.Println("ID of Keptn context: " + *eventContext.KeptnContext)
}
return eventContext, nil
if len(body) == 0 {
return nil, nil
}

eventContext := &models.EventContext{}
if err = eventContext.FromJSON(body); err != nil {
// failed to parse json
return nil, buildErrorResponse(err.Error() + "\n" + "-----DETAILS-----" + string(body))
}

return nil, nil
if eventContext.KeptnContext != nil {
fmt.Println("ID of Keptn context: " + *eventContext.KeptnContext)
}
return eventContext, nil
}

if len(body) > 0 {
Expand All @@ -184,8 +237,8 @@ func postWithEventContext(uri string, data []byte, api APIService) (*models.Even
return nil, buildErrorResponse(fmt.Sprintf("Received unexpected response: %d %s", resp.StatusCode, resp.Status))
}

func post(uri string, data []byte, api APIService) (string, *models.Error) {
req, err := http.NewRequest("POST", uri, bytes.NewBuffer(data))
func post(ctx context.Context, uri string, data []byte, api APIService) (string, *models.Error) {
req, err := http.NewRequestWithContext(ctx, "POST", uri, bytes.NewBuffer(data))
if err != nil {
return "", buildErrorResponse(err.Error())
}
Expand All @@ -204,11 +257,7 @@ func post(uri string, data []byte, api APIService) (string, *models.Error) {
}

if resp.StatusCode >= 200 && resp.StatusCode <= 204 {
if len(body) > 0 {
return string(body), nil
}

return "", nil
return string(body), nil
}

if len(body) > 0 {
Expand All @@ -218,8 +267,8 @@ func post(uri string, data []byte, api APIService) (string, *models.Error) {
return "", buildErrorResponse(fmt.Sprintf("Received unexpected response: %d %s", resp.StatusCode, resp.Status))
}

func deleteWithEventContext(uri string, api APIService) (*models.EventContext, *models.Error) {
req, err := http.NewRequest("DELETE", uri, nil)
func deleteWithEventContext(ctx context.Context, uri string, api APIService) (*models.EventContext, *models.Error) {
req, err := http.NewRequestWithContext(ctx, "DELETE", uri, nil)
if err != nil {
return nil, buildErrorResponse(err.Error())
}
Expand All @@ -238,23 +287,23 @@ func deleteWithEventContext(uri string, api APIService) (*models.EventContext, *
}

if resp.StatusCode >= 200 && resp.StatusCode < 300 {
if len(body) > 0 {
eventContext := &models.EventContext{}
if err = eventContext.FromJSON(body); err != nil {
// failed to parse json
return nil, buildErrorResponse(err.Error() + "\n" + "-----DETAILS-----" + string(body))
}
return eventContext, nil
if len(body) == 0 {
return nil, nil
}

return nil, nil
eventContext := &models.EventContext{}
if err = eventContext.FromJSON(body); err != nil {
// failed to parse json
return nil, buildErrorResponse(err.Error() + "\n" + "-----DETAILS-----" + string(body))
}
return eventContext, nil
}

return nil, handleErrStatusCode(resp.StatusCode, body)
}

func delete(uri string, api APIService) (string, *models.Error) {
req, err := http.NewRequest("DELETE", uri, nil)
func delete(ctx context.Context, uri string, api APIService) (string, *models.Error) {
req, err := http.NewRequestWithContext(ctx, "DELETE", uri, nil)
if err != nil {
return "", buildErrorResponse(err.Error())
}
Expand All @@ -273,11 +322,7 @@ func delete(uri string, api APIService) (string, *models.Error) {
}

if resp.StatusCode >= 200 && resp.StatusCode < 300 {
if len(body) > 0 {
return string(body), nil
}

return "", nil
return string(body), nil
}

return "", handleErrStatusCode(resp.StatusCode, body)
Expand Down
Loading

0 comments on commit 0874051

Please sign in to comment.