Compare commits

...

3 commits
v2.2.0 ... main

Author SHA1 Message Date
51c24718e4
Stop considering empty array responses to be errors
Some checks failed
test / test (push) Failing after 1s
ci / goreleaser (push) Failing after 1s
2026-02-10 15:51:39 +01:00
d38707aea4
Add support for v1 reading of array responses
Some checks failed
test / test (push) Failing after 1s
ci / goreleaser (push) Failing after 0s
2026-02-10 15:31:08 +01:00
ff6441dafc
removed not specified field
All checks were successful
test / test (push) Successful in 56s
2026-01-19 14:54:42 +01:00
10 changed files with 48 additions and 23 deletions

BIN
comprehensive Executable file

Binary file not shown.

View file

@ -360,7 +360,6 @@ func (p *EdgeConnectPlanner) getCurrentInstanceState(ctx context.Context, desire
CloudletName: instance.Key.CloudletKey.Name,
FlavorName: instance.Flavor.Name,
State: instance.State,
PowerState: instance.PowerState,
Exists: true,
LastUpdated: time.Now(), // EdgeConnect doesn't provide this
}

View file

@ -223,8 +223,7 @@ func TestPlanExistingDeploymentNoChanges(t *testing.T) {
Flavor: v2.Flavor{
Name: "small",
},
State: "Ready",
PowerState: "PowerOn",
State: "Ready",
}
mockClient.On("ShowApp", mock.Anything, mock.AnythingOfType("v2.AppKey"), "US").

View file

@ -170,9 +170,6 @@ type InstanceState struct {
// State of the instance (e.g., "Ready", "Pending", "Error")
State string
// PowerState of the instance
PowerState string
// LastUpdated timestamp when the instance was last modified
LastUpdated time.Time

View file

@ -213,10 +213,20 @@ func (c *Client) parseStreamingAppInstanceResponse(resp *http.Response, result i
var errorMessage string
parseErr := sdkhttp.ParseJSONLines(resp.Body, func(line []byte) error {
// On permission denied, Edge API returns just an empty array []!
if len(line) == 0 || line[0] == '[' {
if len(line) == 0 {
return fmt.Errorf("%w", ErrFaultyResponsePerhaps403)
}
// Handle array responses (current API format)
if line[0] == '[' {
var directInstances []AppInstance
if err := json.Unmarshal(line, &directInstances); err != nil {
return err
}
appInstances = append(appInstances, directInstances...)
return nil
}
// Try parsing as ResultResponse first (error format)
var resultResp ResultResponse
if err := json.Unmarshal(line, &resultResp); err == nil && resultResp.Result.Message != "" {
@ -228,7 +238,7 @@ func (c *Client) parseStreamingAppInstanceResponse(resp *http.Response, result i
return nil
}
// Try parsing as Response[AppInstance]
// Try parsing as Response[AppInstance] (legacy streaming format)
var response Response[AppInstance]
if err := json.Unmarshal(line, &response); err != nil {
return err

View file

@ -180,10 +180,23 @@ func (c *Client) parseStreamingResponse(resp *http.Response, result interface{})
var responses []Response[App]
parseErr := sdkhttp.ParseJSONLines(resp.Body, func(line []byte) error {
// On permission denied, Edge API returns just an empty array []!
if len(line) == 0 || line[0] == '[' {
if len(line) == 0 {
return fmt.Errorf("%w", ErrFaultyResponsePerhaps403)
}
// Handle array responses (current API format)
if line[0] == '[' {
var directApps []App
if err := json.Unmarshal(line, &directApps); err != nil {
return err
}
for _, app := range directApps {
responses = append(responses, Response[App]{Data: app})
}
return nil
}
// Try parsing as Response[App] (legacy streaming format)
var response Response[App]
if err := json.Unmarshal(line, &response); err != nil {
return err

View file

@ -229,6 +229,23 @@ func (c *Client) parseStreamingCloudletResponse(resp *http.Response, result inte
var responses []Response[Cloudlet]
parseErr := sdkhttp.ParseJSONLines(resp.Body, func(line []byte) error {
if len(line) == 0 {
return fmt.Errorf("%w", ErrFaultyResponsePerhaps403)
}
// Handle array responses (current API format)
if line[0] == '[' {
var directCloudlets []Cloudlet
if err := json.Unmarshal(line, &directCloudlets); err != nil {
return err
}
for _, cl := range directCloudlets {
responses = append(responses, Response[Cloudlet]{Data: cl})
}
return nil
}
// Try parsing as Response[Cloudlet] (legacy streaming format)
var response Response[Cloudlet]
if err := json.Unmarshal(line, &response); err != nil {
return err

View file

@ -300,8 +300,7 @@ func TestUpdateAppInstance(t *testing.T) {
Name: "testapp",
Version: "1.0.0",
},
Flavor: Flavor{Name: "m4.medium"},
PowerState: "PowerOn",
Flavor: Flavor{Name: "m4.medium"},
},
},
mockStatusCode: 200,

View file

@ -113,7 +113,6 @@ const (
AppInstFieldConfigsKind = "27.1"
AppInstFieldConfigsConfig = "27.2"
AppInstFieldHealthCheck = "29"
AppInstFieldPowerState = "31"
AppInstFieldExternalVolumeSize = "32"
AppInstFieldAvailabilityZone = "33"
AppInstFieldVmFlavor = "34"
@ -201,7 +200,6 @@ type App struct {
GlobalID string `json:"global_id,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
Fields []string `json:"fields,omitempty"`
}
// AppInstance represents a deployed application instance
@ -216,8 +214,6 @@ type AppInstance struct {
UniqueID string `json:"unique_id,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
PowerState string `json:"power_state,omitempty"`
Fields []string `json:"fields,omitempty"`
}
// Cloudlet represents edge infrastructure

View file

@ -203,7 +203,6 @@ func runComprehensiveWorkflow(ctx context.Context, c *v2.Client, config Workflow
fmt.Printf(" • Cloudlet: %s/%s\n", instanceDetails.Key.CloudletKey.Organization, instanceDetails.Key.CloudletKey.Name)
fmt.Printf(" • Flavor: %s\n", instanceDetails.Flavor.Name)
fmt.Printf(" • State: %s\n", instanceDetails.State)
fmt.Printf(" • Power State: %s\n", instanceDetails.PowerState)
// 6. List Application Instances
fmt.Println("\n6⃣ Listing application instances...")
@ -328,11 +327,7 @@ func waitForInstanceReady(ctx context.Context, c *v2.Client, instanceKey v2.AppI
continue
}
fmt.Printf(" 📊 Instance state: %s", instance.State)
if instance.PowerState != "" {
fmt.Printf(" (power: %s)", instance.PowerState)
}
fmt.Printf("\n")
fmt.Printf(" 📊 Instance state: %s\n", instance.State)
// Check if instance is ready (not in creating state)
state := strings.ToLower(instance.State)