Compare commits

..

No commits in common. "main" and "v2.2.0" have entirely different histories.
main ... v2.2.0

10 changed files with 23 additions and 48 deletions

Binary file not shown.

View file

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

View file

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

View file

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

View file

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

View file

@ -180,23 +180,10 @@ func (c *Client) parseStreamingResponse(resp *http.Response, result interface{})
var responses []Response[App] var responses []Response[App]
parseErr := sdkhttp.ParseJSONLines(resp.Body, func(line []byte) error { parseErr := sdkhttp.ParseJSONLines(resp.Body, func(line []byte) error {
if len(line) == 0 { // On permission denied, Edge API returns just an empty array []!
if len(line) == 0 || line[0] == '[' {
return fmt.Errorf("%w", ErrFaultyResponsePerhaps403) 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] var response Response[App]
if err := json.Unmarshal(line, &response); err != nil { if err := json.Unmarshal(line, &response); err != nil {
return err return err

View file

@ -229,23 +229,6 @@ func (c *Client) parseStreamingCloudletResponse(resp *http.Response, result inte
var responses []Response[Cloudlet] var responses []Response[Cloudlet]
parseErr := sdkhttp.ParseJSONLines(resp.Body, func(line []byte) error { 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] var response Response[Cloudlet]
if err := json.Unmarshal(line, &response); err != nil { if err := json.Unmarshal(line, &response); err != nil {
return err return err

View file

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

View file

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

View file

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