Skip to content

Commit

Permalink
Improve debug for Ctrl+C cases, and add readiness check for JSON/RPC …
Browse files Browse the repository at this point in the history
…endpoints

Signed-off-by: Peter Broadhurst <[email protected]>
  • Loading branch information
peterbroadhurst committed Mar 8, 2024
1 parent 77ca8f5 commit f54067e
Show file tree
Hide file tree
Showing 16 changed files with 361 additions and 37 deletions.
6 changes: 6 additions & 0 deletions examples/platform_stack/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ resource "kaleido_platform_service" "gws_0" {
})
}

data "kaleido_platform_evm_netinfo" "gws_0" {
environment = kaleido_platform_environment.env_0.id
service = kaleido_platform_service.gws_0.id
}

resource "kaleido_platform_runtime" "kmr_0" {
type = "KeyManager"
name = "kmr_0"
Expand Down Expand Up @@ -197,4 +202,5 @@ resource "kaleido_platform_cms_action_deploy" "deploy0" {
name = "deploy_0"
firefly_namespace = kaleido_platform_service.ffs_0.name
signing_key = kaleido_platform_kms_key.key_0.address
depends_on = [ data.kaleido_platform_evm_netinfo.gws_0 ]
}
2 changes: 1 addition & 1 deletion kaleido/kaleidobase/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (r *CustomRetry) Do(ctx context.Context, logDescription string, f func(atte
// Check the context isn't canceled
select {
case <-ctx.Done():
return fmt.Errorf("context cancelled")
return fmt.Errorf("context cancelled (last error: %s)", err)
default:
}

Expand Down
4 changes: 3 additions & 1 deletion kaleido/platform/cms_action_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@ func (r *cms_action_deployResource) apiPath(data *CMSActionDeployResourceModel)

func (r *cms_action_deployResource) waitForActionStatus(ctx context.Context, data *CMSActionDeployResourceModel, api *CMSActionDeployAPIModel, diagnostics *diag.Diagnostics) {
path := r.apiPath(data)
cancelInfo := APICancelInfo()
_ = kaleidobase.Retry.Do(ctx, fmt.Sprintf("build-check %s", path), func(attempt int) (retry bool, err error) {
ok, _ := r.apiRequest(ctx, http.MethodGet, path, nil, &api, diagnostics)
ok, _ := r.apiRequest(ctx, http.MethodGet, path, nil, &api, diagnostics, cancelInfo)
if !ok {
return false, fmt.Errorf("action-check failed") // already set in diag
}
cancelInfo.CancelInfo = fmt.Sprintf("waiting for completion - status: %s", api.Output.Status)
switch api.Output.Status {
case "succeeded":
return false, nil
Expand Down
4 changes: 2 additions & 2 deletions kaleido/platform/cms_action_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func (r *cms_action_deployResource) Read(ctx context.Context, req resource.ReadR

var api CMSActionDeployAPIModel
api.ID = data.ID.ValueString()
ok, status := r.apiRequest(ctx, http.MethodGet, r.apiPath(&data), nil, &api, &resp.Diagnostics, Allow404)
ok, status := r.apiRequest(ctx, http.MethodGet, r.apiPath(&data), nil, &api, &resp.Diagnostics, Allow404())
if !ok {
return
}
Expand All @@ -224,7 +224,7 @@ func (r *cms_action_deployResource) Delete(ctx context.Context, req resource.Del
var data CMSActionDeployResourceModel
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)

_, _ = r.apiRequest(ctx, http.MethodDelete, r.apiPath(&data), nil, nil, &resp.Diagnostics, Allow404)
_, _ = r.apiRequest(ctx, http.MethodDelete, r.apiPath(&data), nil, nil, &resp.Diagnostics, Allow404())

r.waitForRemoval(ctx, r.apiPath(&data), &resp.Diagnostics)
}
8 changes: 5 additions & 3 deletions kaleido/platform/cms_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,13 @@ func (r *cms_buildResource) apiPath(data *CMSBuildResourceModel) string {

func (r *cms_buildResource) waitForBuildStatus(ctx context.Context, data *CMSBuildResourceModel, api *CMSBuildAPIModel, diagnostics *diag.Diagnostics) {
path := r.apiPath(data)
cancelInfo := APICancelInfo()
_ = kaleidobase.Retry.Do(ctx, fmt.Sprintf("build-check %s", path), func(attempt int) (retry bool, err error) {
ok, _ := r.apiRequest(ctx, http.MethodGet, path, nil, &api, diagnostics)
ok, _ := r.apiRequest(ctx, http.MethodGet, path, nil, &api, diagnostics, cancelInfo)
if !ok {
return false, fmt.Errorf("build-check failed") // already set in diag
}
cancelInfo.CancelInfo = fmt.Sprintf("(waiting for completion - status: %s)", api.Status)
switch api.Status {
case "succeeded":
return false, nil
Expand Down Expand Up @@ -366,7 +368,7 @@ func (r *cms_buildResource) Read(ctx context.Context, req resource.ReadRequest,

var api CMSBuildAPIModel
api.ID = data.ID.ValueString()
ok, status := r.apiRequest(ctx, http.MethodGet, r.apiPath(&data), nil, &api, &resp.Diagnostics, Allow404)
ok, status := r.apiRequest(ctx, http.MethodGet, r.apiPath(&data), nil, &api, &resp.Diagnostics, Allow404())
if !ok {
return
}
Expand All @@ -383,7 +385,7 @@ func (r *cms_buildResource) Delete(ctx context.Context, req resource.DeleteReque
var data CMSBuildResourceModel
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)

_, _ = r.apiRequest(ctx, http.MethodDelete, r.apiPath(&data), nil, nil, &resp.Diagnostics, Allow404)
_, _ = r.apiRequest(ctx, http.MethodDelete, r.apiPath(&data), nil, nil, &resp.Diagnostics, Allow404())

r.waitForRemoval(ctx, r.apiPath(&data), &resp.Diagnostics)
}
79 changes: 65 additions & 14 deletions kaleido/platform/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ import (
"strings"

"github.com/go-resty/resty/v2"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/kaleido-io/terraform-provider-kaleido/kaleido/kaleidobase"
)

type HttpOptions int

const (
Allow404 HttpOptions = iota
)
type APIRequestOption struct {
allow404 bool
captureLastError bool
CancelInfo string
}

type commonResource struct {
*kaleidobase.ProviderData
Expand All @@ -42,7 +43,27 @@ func (r *commonResource) Configure(_ context.Context, req resource.ConfigureRequ
r.ProviderData = kaleidobase.ConfigureProviderData(req.ProviderData, &resp.Diagnostics)
}

func (r *commonResource) apiRequest(ctx context.Context, method, path string, body, result interface{}, diagnostics *diag.Diagnostics, options ...HttpOptions) (bool, int) {
type commonDataSource struct {
*kaleidobase.ProviderData
}

func (r *commonDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
r.ProviderData = kaleidobase.ConfigureProviderData(req.ProviderData, &resp.Diagnostics)
}

func Allow404() *APIRequestOption {
return &APIRequestOption{
allow404: true,
}
}

func APICancelInfo() *APIRequestOption {
return &APIRequestOption{
captureLastError: true,
}
}

func (r *commonResource) apiRequest(ctx context.Context, method, path string, body, result interface{}, diagnostics *diag.Diagnostics, options ...*APIRequestOption) (bool, int) {
var bodyBytes []byte
var err error
bodyString := ""
Expand Down Expand Up @@ -88,24 +109,44 @@ func (r *commonResource) apiRequest(ctx context.Context, method, path string, bo
ok := true
if err != nil {
ok = false
diagnostics.AddError(
fmt.Sprintf("%s failed", method),
fmt.Sprintf("%s %s failed with error: %s", method, path, err),
)
isCancelled := false
select {
case <-ctx.Done():
isCancelled = true
default:
}
errorInfo := fmt.Sprintf("%s %s failed with error: %s", method, path, err)
if isCancelled {
for _, o := range options {
if o.CancelInfo != "" {
errorInfo = fmt.Sprintf("%s %s", errorInfo, o.CancelInfo)
}
}
diagnostics.AddError(
fmt.Sprintf("%s cancelled", method),
errorInfo,
)
} else {
diagnostics.AddError(
fmt.Sprintf("%s failed", method),
errorInfo,
)
}
} else if !res.IsSuccess() {
isOk404 := false
if statusCode == 404 {
for _, o := range options {
if o == Allow404 {
if o.allow404 {
isOk404 = true
}
}
}
if !isOk404 {
ok = false
errorInfo := fmt.Sprintf("%s %s returned status code %d: %s", method, path, statusCode, rawBytes)
diagnostics.AddError(
fmt.Sprintf("%s failed", method),
fmt.Sprintf("%s %s returned status code %d: %s", method, path, statusCode, rawBytes),
errorInfo,
)
}
}
Expand All @@ -116,12 +157,14 @@ func (r *commonResource) waitForReadyStatus(ctx context.Context, path string, di
type statusResponse struct {
Status string `json:"status"`
}
cancelInfo := APICancelInfo()
_ = kaleidobase.Retry.Do(ctx, fmt.Sprintf("ready-check %s", path), func(attempt int) (retry bool, err error) {
var res statusResponse
ok, _ := r.apiRequest(ctx, http.MethodGet, path, nil, &res, diagnostics)
ok, _ := r.apiRequest(ctx, http.MethodGet, path, nil, &res, diagnostics, cancelInfo)
if !ok {
return false, fmt.Errorf("ready-check failed") // already set in diag
}
cancelInfo.CancelInfo = fmt.Sprintf("(waiting for ready - status: %s)", res.Status)
if !strings.EqualFold(res.Status, "ready") {
return true, fmt.Errorf("not ready yet")
}
Expand All @@ -133,9 +176,11 @@ func (r *commonResource) waitForRemoval(ctx context.Context, path string, diagno
type statusResponse struct {
Status string `json:"status"`
}
cancelInfo := APICancelInfo()
cancelInfo.CancelInfo = "(waiting for removal)"
_ = kaleidobase.Retry.Do(ctx, fmt.Sprintf("ready-check %s", path), func(attempt int) (retry bool, err error) {
var res statusResponse
ok, status := r.apiRequest(ctx, http.MethodGet, path, nil, &res, diagnostics, Allow404)
ok, status := r.apiRequest(ctx, http.MethodGet, path, nil, &res, diagnostics, Allow404(), cancelInfo)
if !ok {
return false, fmt.Errorf("ready-check failed") // already set in diag
}
Expand All @@ -146,6 +191,12 @@ func (r *commonResource) waitForRemoval(ctx context.Context, path string, diagno
})
}

func DataSources() []func() datasource.DataSource {
return []func() datasource.DataSource{
EVMNetInfoDataSourceFactory,
}
}

func Resources() []func() resource.Resource {
return []func() resource.Resource{
EnvironmentResourceFactory,
Expand Down
3 changes: 1 addition & 2 deletions kaleido/platform/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/kaleido-io/terraform-provider-kaleido/kaleido/kaleidobase"
Expand All @@ -42,7 +41,7 @@ func init() {
kaleidoProvider := kaleidobase.New(
"0.0.1-unittest",
Resources(),
[]func() datasource.DataSource{},
DataSources(),
)
testAccProviders = map[string]func() (tfprotov6.ProviderServer, error){
"kaleido": providerserver.NewProtocol6WithError(kaleidoProvider),
Expand Down
4 changes: 2 additions & 2 deletions kaleido/platform/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (r *environmentResource) Read(ctx context.Context, req resource.ReadRequest

var api EnvironmentAPIModel
api.ID = data.ID.ValueString()
ok, status := r.apiRequest(ctx, http.MethodGet, r.apiPath(&data), nil, &api, &resp.Diagnostics, Allow404)
ok, status := r.apiRequest(ctx, http.MethodGet, r.apiPath(&data), nil, &api, &resp.Diagnostics, Allow404())
if !ok {
return
}
Expand All @@ -139,7 +139,7 @@ func (r *environmentResource) Delete(ctx context.Context, req resource.DeleteReq
var data EnvironmentResourceModel
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)

_, _ = r.apiRequest(ctx, http.MethodDelete, r.apiPath(&data), nil, nil, &resp.Diagnostics, Allow404)
_, _ = r.apiRequest(ctx, http.MethodDelete, r.apiPath(&data), nil, nil, &resp.Diagnostics, Allow404())

r.waitForRemoval(ctx, r.apiPath(&data), &resp.Diagnostics)
}
Loading

0 comments on commit f54067e

Please sign in to comment.