176 lines
5.4 KiB
Go
176 lines
5.4 KiB
Go
// ABOUTME: Example demonstrating EdgeXR SDK usage for app deployment workflow
|
|
// ABOUTME: Shows app creation, querying, and cleanup using the typed SDK APIs
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/adapters/driven/edgeconnect"
|
|
"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/domain"
|
|
"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/infrastructure/edgeconnect_client"
|
|
)
|
|
|
|
func main() {
|
|
// Configure SDK client
|
|
baseURL := getEnvOrDefault("EDGE_CONNECT_BASE_URL", "https://hub.apps.edge.platform.mg3.mdb.osc.live")
|
|
|
|
// Support both token-based and username/password authentication
|
|
token := getEnvOrDefault("EDGE_CONNECT_TOKEN", "")
|
|
username := getEnvOrDefault("EDGE_CONNECT_USERNAME", "")
|
|
password := getEnvOrDefault("EDGE_CONNECT_PASSWORD", "")
|
|
|
|
var client *edgeconnect_client.Client
|
|
|
|
if token != "" {
|
|
// Use static token authentication
|
|
fmt.Println("🔐 Using Bearer token authentication")
|
|
client = edgeconnect_client.NewClient(baseURL,
|
|
edgeconnect_client.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}),
|
|
edgeconnect_client.WithAuthProvider(edgeconnect_client.NewStaticTokenProvider(token)),
|
|
edgeconnect_client.WithLogger(log.Default()),
|
|
)
|
|
} else if username != "" && password != "" {
|
|
// Use username/password authentication (matches existing client pattern)
|
|
fmt.Println("🔐 Using username/password authentication")
|
|
client = edgeconnect_client.NewClientWithCredentials(baseURL, username, password,
|
|
edgeconnect_client.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}),
|
|
edgeconnect_client.WithLogger(log.Default()),
|
|
)
|
|
} else {
|
|
log.Fatal("Authentication required: Set either EDGE_CONNECT_TOKEN or both EDGE_CONNECT_USERNAME and EDGE_CONNECT_PASSWORD")
|
|
}
|
|
|
|
adapter := edgeconnect.NewAdapter(client)
|
|
|
|
ctx := context.Background()
|
|
|
|
// Example application to deploy
|
|
app := &NewAppInput{
|
|
Region: "EU",
|
|
App: App{
|
|
Key: AppKey{
|
|
Organization: "edp2",
|
|
Name: "my-edge-app",
|
|
Version: "1.0.0",
|
|
},
|
|
Deployment: "docker",
|
|
ImageType: "ImageTypeDocker",
|
|
ImagePath: "https://registry-1.docker.io/library/nginx:latest",
|
|
DefaultFlavor: Flavor{Name: "EU.small"},
|
|
ServerlessConfig: struct{}{},
|
|
AllowServerless: false,
|
|
},
|
|
}
|
|
|
|
// Demonstrate app lifecycle
|
|
if err := demonstrateAppLifecycle(ctx, adapter, app); err != nil {
|
|
log.Fatalf("App lifecycle demonstration failed: %v", err)
|
|
}
|
|
|
|
fmt.Println("✅ SDK example completed successfully!")
|
|
}
|
|
|
|
func demonstrateAppLifecycle(ctx context.Context, adapter *edgeconnect.Adapter, input *NewAppInput) error {
|
|
appKey := input.App.Key
|
|
region := input.Region
|
|
var domainAppKey domain.AppKey
|
|
|
|
fmt.Printf("🚀 Demonstrating EdgeXR SDK with app: %s/%s v%s\n",
|
|
appKey.Organization, appKey.Name, appKey.Version)
|
|
|
|
// Step 1: Create the application
|
|
fmt.Println("\n1. Creating application...")
|
|
domainApp := &domain.App{
|
|
Key: domain.AppKey{
|
|
Organization: input.App.Key.Organization,
|
|
Name: input.App.Key.Name,
|
|
Version: input.App.Key.Version,
|
|
},
|
|
Deployment: input.App.Deployment,
|
|
ImageType: input.App.ImageType,
|
|
ImagePath: input.App.ImagePath,
|
|
DefaultFlavor: domain.Flavor{Name: input.App.DefaultFlavor.Name},
|
|
ServerlessConfig: input.App.ServerlessConfig,
|
|
AllowServerless: input.App.AllowServerless,
|
|
}
|
|
if err := adapter.CreateApp(ctx, input.Region, domainApp); err != nil {
|
|
return fmt.Errorf("failed to create app: %+v", err)
|
|
}
|
|
fmt.Println(" ✅ App created successfully.")
|
|
|
|
// Defer cleanup to ensure the app is deleted even if subsequent steps fail
|
|
defer func() {
|
|
fmt.Println("\n4. Cleaning up: Deleting application...")
|
|
domainAppKey = domain.AppKey{
|
|
Organization: appKey.Organization,
|
|
Name: appKey.Name,
|
|
Version: appKey.Version,
|
|
}
|
|
if err := adapter.DeleteApp(ctx, region, domainAppKey); err != nil {
|
|
fmt.Printf(" ⚠️ Cleanup failed: %v\n", err)
|
|
} else {
|
|
fmt.Println(" ✅ App deleted successfully.")
|
|
}
|
|
}()
|
|
|
|
// Step 2: Verify app creation by fetching it
|
|
fmt.Println("\n2. Verifying app creation...")
|
|
domainAppKey = domain.AppKey{
|
|
Organization: appKey.Organization,
|
|
Name: appKey.Name,
|
|
Version: appKey.Version,
|
|
}
|
|
fetchedApp, err := adapter.ShowApp(ctx, region, domainAppKey)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get app after creation: %w", err)
|
|
}
|
|
fmt.Printf(" ✅ Fetched app: %s/%s v%s\n",
|
|
fetchedApp.Key.Organization, fetchedApp.Key.Name, fetchedApp.Key.Version)
|
|
|
|
// Step 3: (Placeholder for other operations like updating or deploying)
|
|
fmt.Println("\n3. Skipping further operations in this example.")
|
|
|
|
return nil
|
|
}
|
|
|
|
// Helper to get environment variables or return a default
|
|
func getEnvOrDefault(key, defaultValue string) string {
|
|
if value, exists := os.LookupEnv(key); exists {
|
|
return value
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
// The structs below are included to make the example self-contained and runnable.
|
|
// In a real application, these would be defined in the `edgeconnect` package.
|
|
|
|
type NewAppInput struct {
|
|
Region string
|
|
App App
|
|
}
|
|
|
|
type App struct {
|
|
Key AppKey
|
|
Deployment string
|
|
ImageType string
|
|
ImagePath string
|
|
DefaultFlavor Flavor
|
|
ServerlessConfig interface{}
|
|
AllowServerless bool
|
|
}
|
|
|
|
type AppKey struct {
|
|
Organization string
|
|
Name string
|
|
Version string
|
|
}
|
|
|
|
type Flavor struct {
|
|
Name string
|
|
}
|