705 lines
25 KiB
Go
705 lines
25 KiB
Go
package edgeconnect
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/domain"
|
|
"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/infrastructure/edgeconnect_client"
|
|
"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/ports/driven"
|
|
)
|
|
|
|
// Adapter implements the driven ports for the EdgeConnect API.
|
|
// It acts as a bridge between the application's core logic and the
|
|
// underlying infrastructure client, translating domain requests into
|
|
// infrastructure calls.
|
|
type Adapter struct {
|
|
client *edgeconnect_client.Client
|
|
}
|
|
|
|
// NewAdapter creates a new EdgeConnect adapter.
|
|
// It requires a configured infrastructure client to communicate with the API.
|
|
func NewAdapter(client *edgeconnect_client.Client) *Adapter {
|
|
return &Adapter{client: client}
|
|
}
|
|
|
|
// Ensure the adapter implements all required repository interfaces.
|
|
var _ driven.AppRepository = (*Adapter)(nil)
|
|
var _ driven.AppInstanceRepository = (*Adapter)(nil)
|
|
var _ driven.CloudletRepository = (*Adapter)(nil)
|
|
var _ driven.OrganizationRepository = (*Adapter)(nil)
|
|
|
|
// OrganizationRepository implementation
|
|
|
|
// CreateOrganization creates a new organization.
|
|
func (a *Adapter) CreateOrganization(ctx context.Context, org *domain.Organization) error {
|
|
apiPath := "/api/v1/auth/org/create"
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, org, nil)
|
|
if err != nil {
|
|
// TODO: Improve error handling to return domain-specific errors
|
|
return fmt.Errorf("failed to create organization %s: %w", org.Name, err)
|
|
}
|
|
a.client.Logf("Successfully created organization: %s", org.Name)
|
|
return nil
|
|
}
|
|
|
|
// ShowOrganization retrieves a single organization by name.
|
|
func (a *Adapter) ShowOrganization(ctx context.Context, name string) (*domain.Organization, error) {
|
|
apiPath := "/api/v1/auth/org/show"
|
|
reqBody := map[string]string{"name": name}
|
|
var orgs []domain.Organization
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, reqBody, &orgs)
|
|
if err != nil {
|
|
// TODO: Improve error handling, check for 404 and return domain.ErrResourceNotFound
|
|
return nil, fmt.Errorf("failed to show organization %s: %w", name, err)
|
|
}
|
|
|
|
if len(orgs) == 0 {
|
|
return nil, fmt.Errorf("organization '%s' not found", name)
|
|
}
|
|
|
|
if len(orgs) > 1 {
|
|
a.client.Logf("warning: ShowOrganization for '%s' returned %d results, expected 1", name, len(orgs))
|
|
}
|
|
|
|
return &orgs[0], nil
|
|
}
|
|
|
|
// UpdateOrganization updates an existing organization.
|
|
func (a *Adapter) UpdateOrganization(ctx context.Context, org *domain.Organization) error {
|
|
apiPath := "/api/v1/auth/org/update"
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, org, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to update organization %s: %w", org.Name, err)
|
|
}
|
|
a.client.Logf("Successfully updated organization: %s", org.Name)
|
|
return nil
|
|
}
|
|
|
|
// DeleteOrganization deletes an organization by name.
|
|
func (a *Adapter) DeleteOrganization(ctx context.Context, name string) error {
|
|
apiPath := "/api/v1/auth/org/delete"
|
|
reqBody := map[string]string{"name": name}
|
|
|
|
resp, err := a.client.Call(ctx, http.MethodPost, apiPath, reqBody, nil)
|
|
if err != nil {
|
|
// A 404 status is acceptable, means it's already deleted.
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
a.client.Logf("Organization %s not found for deletion, considered successful.", name)
|
|
return nil
|
|
}
|
|
return fmt.Errorf("failed to delete organization %s: %w", name, err)
|
|
}
|
|
// The Call method now handles the response body closure if result is not nil.
|
|
// If result is nil, we must close it.
|
|
if resp != nil && resp.Body != nil {
|
|
defer func() {
|
|
_ = resp.Body.Close()
|
|
}()
|
|
}
|
|
|
|
a.client.Logf("Successfully deleted organization: %s", name)
|
|
return nil
|
|
}
|
|
|
|
// AppRepository implementation
|
|
|
|
// CreateApp creates a new application.
|
|
func (a *Adapter) CreateApp(ctx context.Context, region string, app *domain.App) error {
|
|
apiPath := "/api/v1/auth/ctrl/CreateApp"
|
|
apiApp := toAPIApp(app)
|
|
input := &edgeconnect_client.NewAppInput{
|
|
Region: region,
|
|
App: *apiApp,
|
|
}
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, input, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("CreateApp failed: %w", err)
|
|
}
|
|
a.client.Logf("CreateApp: %s/%s version %s created successfully",
|
|
input.App.Key.Organization, input.App.Key.Name, input.App.Key.Version)
|
|
return nil
|
|
}
|
|
|
|
// ShowApp retrieves a single application.
|
|
func (a *Adapter) ShowApp(ctx context.Context, region string, appKey domain.AppKey) (*domain.App, error) {
|
|
apiPath := "/api/v1/auth/ctrl/ShowApp"
|
|
apiAppKey := toAPIAppKey(appKey)
|
|
filter := edgeconnect_client.AppFilter{
|
|
App: edgeconnect_client.App{Key: *apiAppKey},
|
|
Region: region,
|
|
}
|
|
|
|
var apps []edgeconnect_client.App
|
|
resp, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
return nil, domain.NewAppError(domain.ErrResourceNotFound, "ShowApp", appKey, region, "application not found")
|
|
}
|
|
return nil, fmt.Errorf("ShowApp failed: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = resp.Body.Close()
|
|
}()
|
|
|
|
if err := a.client.ParseStreamingResponse(resp, &apps); err != nil {
|
|
return nil, fmt.Errorf("ShowApp failed to parse response: %w", err)
|
|
}
|
|
|
|
if len(apps) == 0 {
|
|
return nil, domain.NewAppError(domain.ErrResourceNotFound, "ShowApp", appKey, region, "application not found")
|
|
}
|
|
|
|
domainApp := toDomainApp(&apps[0])
|
|
return &domainApp, nil
|
|
}
|
|
|
|
// ShowApps retrieves all applications matching the filter.
|
|
func (a *Adapter) ShowApps(ctx context.Context, region string, appKey domain.AppKey) ([]domain.App, error) {
|
|
apiPath := "/api/v1/auth/ctrl/ShowApp"
|
|
apiAppKey := toAPIAppKey(appKey)
|
|
filter := edgeconnect_client.AppFilter{
|
|
App: edgeconnect_client.App{Key: *apiAppKey},
|
|
Region: region,
|
|
}
|
|
|
|
var apiApps []edgeconnect_client.App
|
|
resp, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
return []domain.App{}, nil // Return empty slice for not found
|
|
}
|
|
return nil, fmt.Errorf("ShowApps failed: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = resp.Body.Close()
|
|
}()
|
|
|
|
if err := a.client.ParseStreamingResponse(resp, &apiApps); err != nil {
|
|
return nil, fmt.Errorf("ShowApps failed to parse response: %w", err)
|
|
}
|
|
|
|
a.client.Logf("ShowApps: found %d apps matching criteria", len(apiApps))
|
|
domainApps := make([]domain.App, len(apiApps))
|
|
for i := range apiApps {
|
|
domainApps[i] = toDomainApp(&apiApps[i])
|
|
}
|
|
return domainApps, nil
|
|
}
|
|
|
|
// UpdateApp updates an existing application.
|
|
func (a *Adapter) UpdateApp(ctx context.Context, region string, app *domain.App) error {
|
|
apiPath := "/api/v1/auth/ctrl/UpdateApp"
|
|
apiApp := toAPIApp(app)
|
|
input := &edgeconnect_client.UpdateAppInput{
|
|
Region: region,
|
|
App: *apiApp,
|
|
}
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, input, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("UpdateApp failed: %w", err)
|
|
}
|
|
a.client.Logf("UpdateApp: %s/%s version %s updated successfully",
|
|
input.App.Key.Organization, input.App.Key.Name, input.App.Key.Version)
|
|
return nil
|
|
}
|
|
|
|
// DeleteApp deletes an application.
|
|
func (a *Adapter) DeleteApp(ctx context.Context, region string, appKey domain.AppKey) error {
|
|
apiPath := "/api/v1/auth/ctrl/DeleteApp"
|
|
apiAppKey := toAPIAppKey(appKey)
|
|
filter := edgeconnect_client.AppFilter{
|
|
App: edgeconnect_client.App{Key: *apiAppKey},
|
|
Region: region,
|
|
}
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
a.client.Logf("App %v not found for deletion, considered successful.", appKey)
|
|
return nil
|
|
}
|
|
return fmt.Errorf("DeleteApp failed: %w", err)
|
|
}
|
|
a.client.Logf("DeleteApp: %s/%s version %s deleted successfully",
|
|
appKey.Organization, appKey.Name, appKey.Version)
|
|
return nil
|
|
}
|
|
|
|
// AppInstanceRepository implementation
|
|
|
|
// CreateAppInstance creates a new application instance.
|
|
func (a *Adapter) CreateAppInstance(ctx context.Context, region string, appInst *domain.AppInstance) error {
|
|
apiPath := "/api/v1/auth/ctrl/CreateAppInst"
|
|
apiAppInst := toAPIAppInstance(appInst)
|
|
input := &edgeconnect_client.NewAppInstanceInput{
|
|
Region: region,
|
|
AppInst: *apiAppInst,
|
|
}
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, input, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("CreateAppInstance failed: %w", err)
|
|
}
|
|
a.client.Logf("CreateAppInstance: %s/%s created successfully",
|
|
input.AppInst.Key.Organization, input.AppInst.Key.Name)
|
|
return nil
|
|
}
|
|
|
|
// ShowAppInstance retrieves a single application instance.
|
|
func (a *Adapter) ShowAppInstance(ctx context.Context, region string, appInstKey domain.AppInstanceKey) (*domain.AppInstance, error) {
|
|
apiPath := "/api/v1/auth/ctrl/ShowAppInst"
|
|
apiAppInstKey := toAPIAppInstanceKey(appInstKey)
|
|
filter := edgeconnect_client.AppInstanceFilter{
|
|
AppInstance: edgeconnect_client.AppInstance{Key: *apiAppInstKey},
|
|
Region: region,
|
|
}
|
|
|
|
var appInstances []edgeconnect_client.AppInstance
|
|
resp, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
return nil, domain.NewInstanceError(domain.ErrResourceNotFound, "ShowAppInstance", appInstKey, region, "app instance not found")
|
|
}
|
|
return nil, fmt.Errorf("ShowAppInstance failed: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = resp.Body.Close()
|
|
}()
|
|
|
|
if err := a.client.ParseStreamingAppInstanceResponse(resp, &appInstances); err != nil {
|
|
return nil, fmt.Errorf("ShowAppInstance failed to parse response: %w", err)
|
|
}
|
|
|
|
if len(appInstances) == 0 {
|
|
return nil, domain.NewInstanceError(domain.ErrResourceNotFound, "ShowAppInstance", appInstKey, region, "app instance not found")
|
|
}
|
|
|
|
domainAppInst := toDomainAppInstance(&appInstances[0])
|
|
return &domainAppInst, nil
|
|
}
|
|
|
|
// ShowAppInstances retrieves all application instances matching the filter.
|
|
func (a *Adapter) ShowAppInstances(ctx context.Context, region string, appInstKey domain.AppInstanceKey) ([]domain.AppInstance, error) {
|
|
apiPath := "/api/v1/auth/ctrl/ShowAppInst"
|
|
apiAppInstKey := toAPIAppInstanceKey(appInstKey)
|
|
filter := edgeconnect_client.AppInstanceFilter{
|
|
AppInstance: edgeconnect_client.AppInstance{Key: *apiAppInstKey},
|
|
Region: region,
|
|
}
|
|
|
|
var appInstances []edgeconnect_client.AppInstance
|
|
resp, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
return []domain.AppInstance{}, nil
|
|
}
|
|
return nil, fmt.Errorf("ShowAppInstances failed: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = resp.Body.Close()
|
|
}()
|
|
|
|
if err := a.client.ParseStreamingAppInstanceResponse(resp, &appInstances); err != nil {
|
|
return nil, fmt.Errorf("ShowAppInstances failed to parse response: %w", err)
|
|
}
|
|
|
|
a.client.Logf("ShowAppInstances: found %d app instances matching criteria", len(appInstances))
|
|
domainAppInsts := make([]domain.AppInstance, len(appInstances))
|
|
for i := range appInstances {
|
|
domainAppInsts[i] = toDomainAppInstance(&appInstances[i])
|
|
}
|
|
return domainAppInsts, nil
|
|
}
|
|
|
|
// UpdateAppInstance updates an existing application instance.
|
|
func (a *Adapter) UpdateAppInstance(ctx context.Context, region string, appInst *domain.AppInstance) error {
|
|
apiPath := "/api/v1/auth/ctrl/UpdateAppInst"
|
|
apiAppInst := toAPIAppInstance(appInst)
|
|
input := &edgeconnect_client.UpdateAppInstanceInput{
|
|
Region: region,
|
|
AppInst: *apiAppInst,
|
|
}
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, input, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("UpdateAppInstance failed: %w", err)
|
|
}
|
|
a.client.Logf("UpdateAppInstance: %s/%s updated successfully",
|
|
input.AppInst.Key.Organization, input.AppInst.Key.Name)
|
|
return nil
|
|
}
|
|
|
|
// RefreshAppInstance refreshes an application instance.
|
|
func (a *Adapter) RefreshAppInstance(ctx context.Context, region string, appInstKey domain.AppInstanceKey) error {
|
|
apiPath := "/api/v1/auth/ctrl/RefreshAppInst"
|
|
apiAppInstKey := toAPIAppInstanceKey(appInstKey)
|
|
filter := edgeconnect_client.AppInstanceFilter{
|
|
AppInstance: edgeconnect_client.AppInstance{Key: *apiAppInstKey},
|
|
Region: region,
|
|
}
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("RefreshAppInstance failed: %w", err)
|
|
}
|
|
a.client.Logf("RefreshAppInstance: %s/%s refreshed successfully",
|
|
appInstKey.Organization, appInstKey.Name)
|
|
return nil
|
|
}
|
|
|
|
// DeleteAppInstance deletes an application instance.
|
|
func (a *Adapter) DeleteAppInstance(ctx context.Context, region string, appInstKey domain.AppInstanceKey) error {
|
|
apiPath := "/api/v1/auth/ctrl/DeleteAppInst"
|
|
apiAppInstKey := toAPIAppInstanceKey(appInstKey)
|
|
filter := edgeconnect_client.AppInstanceFilter{
|
|
AppInstance: edgeconnect_client.AppInstance{Key: *apiAppInstKey},
|
|
Region: region,
|
|
}
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
a.client.Logf("AppInstance %v not found for deletion, considered successful.", appInstKey)
|
|
return nil
|
|
}
|
|
return fmt.Errorf("DeleteAppInstance failed: %w", err)
|
|
}
|
|
a.client.Logf("DeleteAppInstance: %s/%s deleted successfully",
|
|
appInstKey.Organization, appInstKey.Name)
|
|
return nil
|
|
}
|
|
|
|
// CloudletRepository implementation
|
|
|
|
// CreateCloudlet creates a new cloudlet.
|
|
func (a *Adapter) CreateCloudlet(ctx context.Context, region string, cloudlet *domain.Cloudlet) error {
|
|
apiPath := "/api/v1/auth/ctrl/CreateCloudlet"
|
|
apiCloudlet := toAPICloudlet(cloudlet)
|
|
input := &edgeconnect_client.NewCloudletInput{
|
|
Region: region,
|
|
Cloudlet: *apiCloudlet,
|
|
}
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, input, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("CreateCloudlet failed: %w", err)
|
|
}
|
|
a.client.Logf("CreateCloudlet: %s/%s created successfully",
|
|
input.Cloudlet.Key.Organization, input.Cloudlet.Key.Name)
|
|
return nil
|
|
}
|
|
|
|
// ShowCloudlet retrieves a single cloudlet.
|
|
func (a *Adapter) ShowCloudlet(ctx context.Context, region string, cloudletKey domain.CloudletKey) (*domain.Cloudlet, error) {
|
|
apiPath := "/api/v1/auth/ctrl/ShowCloudlet"
|
|
apiCloudletKey := toAPICloudletKey(cloudletKey)
|
|
filter := edgeconnect_client.CloudletFilter{
|
|
Cloudlet: edgeconnect_client.Cloudlet{Key: apiCloudletKey},
|
|
Region: region,
|
|
}
|
|
|
|
var cloudlets []edgeconnect_client.Cloudlet
|
|
resp, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
return nil, domain.NewCloudletError(domain.ErrResourceNotFound, "ShowCloudlet", cloudletKey, region, "cloudlet not found")
|
|
}
|
|
return nil, fmt.Errorf("ShowCloudlet failed: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = resp.Body.Close()
|
|
}()
|
|
|
|
if err := a.client.ParseStreamingCloudletResponse(resp, &cloudlets); err != nil {
|
|
return nil, fmt.Errorf("ShowCloudlet failed to parse response: %w", err)
|
|
}
|
|
|
|
if len(cloudlets) == 0 {
|
|
return nil, domain.NewCloudletError(domain.ErrResourceNotFound, "ShowCloudlet", cloudletKey, region, "cloudlet not found")
|
|
}
|
|
|
|
domainCloudlet := toDomainCloudlet(&cloudlets[0])
|
|
return &domainCloudlet, nil
|
|
}
|
|
|
|
// ShowCloudlets retrieves all cloudlets matching the filter.
|
|
func (a *Adapter) ShowCloudlets(ctx context.Context, region string, cloudletKey domain.CloudletKey) ([]domain.Cloudlet, error) {
|
|
apiPath := "/api/v1/auth/ctrl/ShowCloudlet"
|
|
apiCloudletKey := toAPICloudletKey(cloudletKey)
|
|
filter := edgeconnect_client.CloudletFilter{
|
|
Cloudlet: edgeconnect_client.Cloudlet{Key: apiCloudletKey},
|
|
Region: region,
|
|
}
|
|
|
|
var cloudlets []edgeconnect_client.Cloudlet
|
|
resp, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
return []domain.Cloudlet{}, nil
|
|
}
|
|
return nil, fmt.Errorf("ShowCloudlets failed: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = resp.Body.Close()
|
|
}()
|
|
|
|
if err := a.client.ParseStreamingCloudletResponse(resp, &cloudlets); err != nil {
|
|
return nil, fmt.Errorf("ShowCloudlets failed to parse response: %w", err)
|
|
}
|
|
|
|
a.client.Logf("ShowCloudlets: found %d cloudlets matching criteria", len(cloudlets))
|
|
domainCloudlets := make([]domain.Cloudlet, len(cloudlets))
|
|
for i := range cloudlets {
|
|
domainCloudlets[i] = toDomainCloudlet(&cloudlets[i])
|
|
}
|
|
return domainCloudlets, nil
|
|
}
|
|
|
|
// DeleteCloudlet deletes a cloudlet.
|
|
func (a *Adapter) DeleteCloudlet(ctx context.Context, region string, cloudletKey domain.CloudletKey) error {
|
|
apiPath := "/api/v1/auth/ctrl/DeleteCloudlet"
|
|
apiCloudletKey := toAPICloudletKey(cloudletKey)
|
|
filter := edgeconnect_client.CloudletFilter{
|
|
Cloudlet: edgeconnect_client.Cloudlet{Key: apiCloudletKey},
|
|
Region: region,
|
|
}
|
|
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, nil)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
a.client.Logf("Cloudlet %v not found for deletion, considered successful.", cloudletKey)
|
|
return nil
|
|
}
|
|
return fmt.Errorf("DeleteCloudlet failed: %w", err)
|
|
}
|
|
a.client.Logf("DeleteCloudlet: %s/%s deleted successfully",
|
|
cloudletKey.Organization, cloudletKey.Name)
|
|
return nil
|
|
}
|
|
|
|
// GetCloudletManifest retrieves the deployment manifest for a cloudlet.
|
|
func (a *Adapter) GetCloudletManifest(ctx context.Context, cloudletKey domain.CloudletKey, region string) (*edgeconnect_client.CloudletManifest, error) {
|
|
apiPath := "/api/v1/auth/ctrl/GetCloudletManifest"
|
|
apiCloudletKey := toAPICloudletKey(cloudletKey)
|
|
filter := edgeconnect_client.CloudletFilter{
|
|
Cloudlet: edgeconnect_client.Cloudlet{Key: apiCloudletKey},
|
|
Region: region,
|
|
}
|
|
|
|
var manifest edgeconnect_client.CloudletManifest
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, &manifest)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
return nil, domain.NewCloudletError(domain.ErrResourceNotFound, "GetCloudletManifest", cloudletKey, region, "cloudlet manifest not found")
|
|
}
|
|
return nil, fmt.Errorf("GetCloudletManifest failed: %w", err)
|
|
}
|
|
a.client.Logf("GetCloudletManifest: retrieved manifest for %s/%s",
|
|
cloudletKey.Organization, cloudletKey.Name)
|
|
return &manifest, nil
|
|
}
|
|
|
|
// GetCloudletResourceUsage retrieves resource usage for a cloudlet.
|
|
func (a *Adapter) GetCloudletResourceUsage(ctx context.Context, cloudletKey domain.CloudletKey, region string) (*edgeconnect_client.CloudletResourceUsage, error) {
|
|
apiPath := "/api/v1/auth/ctrl/GetCloudletResourceUsage"
|
|
apiCloudletKey := toAPICloudletKey(cloudletKey)
|
|
filter := edgeconnect_client.CloudletFilter{
|
|
Cloudlet: edgeconnect_client.Cloudlet{Key: apiCloudletKey},
|
|
Region: region,
|
|
}
|
|
|
|
var usage edgeconnect_client.CloudletResourceUsage
|
|
_, err := a.client.Call(ctx, http.MethodPost, apiPath, filter, &usage)
|
|
if err != nil {
|
|
if apiErr, ok := err.(*edgeconnect_client.APIError); ok && apiErr.StatusCode == http.StatusNotFound {
|
|
return nil, domain.NewCloudletError(domain.ErrResourceNotFound, "GetCloudletResourceUsage", cloudletKey, region, "cloudlet resource usage not found")
|
|
}
|
|
return nil, fmt.Errorf("GetCloudletResourceUsage failed: %w", err)
|
|
}
|
|
a.client.Logf("GetCloudletResourceUsage: retrieved usage for %s/%s",
|
|
cloudletKey.Organization, cloudletKey.Name)
|
|
return &usage, nil
|
|
}
|
|
|
|
// Data mapping functions (domain <-> API)
|
|
|
|
func toAPIApp(app *domain.App) *edgeconnect_client.App {
|
|
return &edgeconnect_client.App{
|
|
Key: *toAPIAppKey(app.Key),
|
|
Deployment: app.Deployment,
|
|
ImageType: app.ImageType,
|
|
ImagePath: app.ImagePath,
|
|
AllowServerless: app.AllowServerless,
|
|
DefaultFlavor: toAPIFlavor(app.DefaultFlavor),
|
|
ServerlessConfig: app.ServerlessConfig,
|
|
DeploymentGenerator: app.DeploymentGenerator,
|
|
DeploymentManifest: app.DeploymentManifest,
|
|
RequiredOutboundConnections: toAPISecurityRules(app.RequiredOutboundConnections),
|
|
Fields: app.Fields,
|
|
}
|
|
}
|
|
|
|
func toDomainApp(app *edgeconnect_client.App) domain.App {
|
|
return domain.App{
|
|
Key: toDomainAppKey(app.Key),
|
|
Deployment: app.Deployment,
|
|
ImageType: app.ImageType,
|
|
ImagePath: app.ImagePath,
|
|
AllowServerless: app.AllowServerless,
|
|
DefaultFlavor: toDomainFlavor(app.DefaultFlavor),
|
|
ServerlessConfig: app.ServerlessConfig,
|
|
DeploymentGenerator: app.DeploymentGenerator,
|
|
DeploymentManifest: app.DeploymentManifest,
|
|
RequiredOutboundConnections: toDomainSecurityRules(app.RequiredOutboundConnections),
|
|
Fields: app.Fields,
|
|
}
|
|
}
|
|
|
|
func toAPIAppKey(appKey domain.AppKey) *edgeconnect_client.AppKey {
|
|
return &edgeconnect_client.AppKey{
|
|
Organization: appKey.Organization,
|
|
Name: appKey.Name,
|
|
Version: appKey.Version,
|
|
}
|
|
}
|
|
|
|
func toDomainAppKey(appKey edgeconnect_client.AppKey) domain.AppKey {
|
|
return domain.AppKey{
|
|
Organization: appKey.Organization,
|
|
Name: appKey.Name,
|
|
Version: appKey.Version,
|
|
}
|
|
}
|
|
|
|
func toAPIFlavor(flavor domain.Flavor) edgeconnect_client.Flavor {
|
|
return edgeconnect_client.Flavor{Name: flavor.Name}
|
|
}
|
|
|
|
func toDomainFlavor(flavor edgeconnect_client.Flavor) domain.Flavor {
|
|
return domain.Flavor{Name: flavor.Name}
|
|
}
|
|
|
|
func toAPISecurityRules(rules []domain.SecurityRule) []edgeconnect_client.SecurityRule {
|
|
apiRules := make([]edgeconnect_client.SecurityRule, len(rules))
|
|
for i, r := range rules {
|
|
apiRules[i] = edgeconnect_client.SecurityRule{
|
|
PortRangeMax: r.PortRangeMax,
|
|
PortRangeMin: r.PortRangeMin,
|
|
Protocol: r.Protocol,
|
|
RemoteCIDR: r.RemoteCIDR,
|
|
}
|
|
}
|
|
return apiRules
|
|
}
|
|
|
|
func toDomainSecurityRules(rules []edgeconnect_client.SecurityRule) []domain.SecurityRule {
|
|
domainRules := make([]domain.SecurityRule, len(rules))
|
|
for i, r := range rules {
|
|
domainRules[i] = domain.SecurityRule{
|
|
PortRangeMax: r.PortRangeMax,
|
|
PortRangeMin: r.PortRangeMin,
|
|
Protocol: r.Protocol,
|
|
RemoteCIDR: r.RemoteCIDR,
|
|
}
|
|
}
|
|
return domainRules
|
|
}
|
|
|
|
func toAPIAppInstance(appInst *domain.AppInstance) *edgeconnect_client.AppInstance {
|
|
return &edgeconnect_client.AppInstance{
|
|
Key: *toAPIAppInstanceKey(appInst.Key),
|
|
AppKey: *toAPIAppKey(appInst.AppKey),
|
|
Flavor: toAPIFlavor(appInst.Flavor),
|
|
State: appInst.State,
|
|
PowerState: appInst.PowerState,
|
|
Fields: appInst.Fields,
|
|
}
|
|
}
|
|
|
|
func toDomainAppInstance(appInst *edgeconnect_client.AppInstance) domain.AppInstance {
|
|
return domain.AppInstance{
|
|
Key: toDomainAppInstanceKey(appInst.Key),
|
|
AppKey: toDomainAppKey(appInst.AppKey),
|
|
Flavor: toDomainFlavor(appInst.Flavor),
|
|
State: appInst.State,
|
|
PowerState: appInst.PowerState,
|
|
Fields: appInst.Fields,
|
|
}
|
|
}
|
|
|
|
func toAPIAppInstanceKey(key domain.AppInstanceKey) *edgeconnect_client.AppInstanceKey {
|
|
return &edgeconnect_client.AppInstanceKey{
|
|
Organization: key.Organization,
|
|
Name: key.Name,
|
|
CloudletKey: toAPICloudletKey(key.CloudletKey),
|
|
}
|
|
}
|
|
|
|
func toDomainAppInstanceKey(key edgeconnect_client.AppInstanceKey) domain.AppInstanceKey {
|
|
return domain.AppInstanceKey{
|
|
Organization: key.Organization,
|
|
Name: key.Name,
|
|
CloudletKey: toDomainCloudletKey(key.CloudletKey),
|
|
}
|
|
}
|
|
|
|
func toAPICloudletKey(key domain.CloudletKey) edgeconnect_client.CloudletKey {
|
|
return edgeconnect_client.CloudletKey{
|
|
Organization: key.Organization,
|
|
Name: key.Name,
|
|
}
|
|
}
|
|
|
|
func toDomainCloudletKey(key edgeconnect_client.CloudletKey) domain.CloudletKey {
|
|
return domain.CloudletKey{
|
|
Organization: key.Organization,
|
|
Name: key.Name,
|
|
}
|
|
}
|
|
|
|
func toAPICloudlet(cloudlet *domain.Cloudlet) *edgeconnect_client.Cloudlet {
|
|
return &edgeconnect_client.Cloudlet{
|
|
Key: toAPICloudletKey(cloudlet.Key),
|
|
Location: toAPILocation(cloudlet.Location),
|
|
IpSupport: cloudlet.IpSupport,
|
|
NumDynamicIps: cloudlet.NumDynamicIps,
|
|
State: cloudlet.State,
|
|
Flavor: toAPIFlavor(cloudlet.Flavor),
|
|
PhysicalName: cloudlet.PhysicalName,
|
|
Region: cloudlet.Region,
|
|
NotifySrvAddr: cloudlet.NotifySrvAddr,
|
|
}
|
|
}
|
|
|
|
func toDomainCloudlet(cloudlet *edgeconnect_client.Cloudlet) domain.Cloudlet {
|
|
return domain.Cloudlet{
|
|
Key: toDomainCloudletKey(cloudlet.Key),
|
|
Location: toDomainLocation(cloudlet.Location),
|
|
IpSupport: cloudlet.IpSupport,
|
|
NumDynamicIps: cloudlet.NumDynamicIps,
|
|
State: cloudlet.State,
|
|
Flavor: toDomainFlavor(cloudlet.Flavor),
|
|
PhysicalName: cloudlet.PhysicalName,
|
|
Region: cloudlet.Region,
|
|
NotifySrvAddr: cloudlet.NotifySrvAddr,
|
|
}
|
|
}
|
|
|
|
func toAPILocation(location domain.Location) edgeconnect_client.Location {
|
|
return edgeconnect_client.Location{
|
|
Latitude: location.Latitude,
|
|
Longitude: location.Longitude,
|
|
}
|
|
}
|
|
|
|
func toDomainLocation(location edgeconnect_client.Location) domain.Location {
|
|
return domain.Location{
|
|
Latitude: location.Latitude,
|
|
Longitude: location.Longitude,
|
|
}
|
|
}
|