...

Source file src/edge-infra.dev/pkg/edge/device-registrar/services/device_pair_service.go

Documentation: edge-infra.dev/pkg/edge/device-registrar/services

     1  package services
     2  
     3  import (
     4  	"net/http"
     5  
     6  	api "edge-infra.dev/pkg/edge/device-registrar/api/v1alpha1"
     7  	"edge-infra.dev/pkg/edge/device-registrar/config"
     8  
     9  	"github.com/gin-gonic/gin"
    10  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  )
    13  
    14  // DevicePairResponse represents the response after pairing a device
    15  // swagger:model DevicePairResponse
    16  type DevicePairResponse struct {
    17  	// example: https://edge-bootstrap.store.ncr.corp/connect/F7RAXZXBFZQRPAU
    18  	ConnectURL  string      `json:"connectURL"`
    19  	HostMapping HostMapping `json:"hostMapping"`
    20  }
    21  
    22  // swagger:route POST /pair core pair
    23  // Initiates a paring process
    24  //
    25  // Initiates a paring process and returns a URL with an activation code for device to connect
    26  // responses:
    27  //
    28  //	200: DevicePairResponse Success
    29  //	500: description:Internal Server Error
    30  //
    31  // Pair initiates the pairing process for a device
    32  func Pair(c *gin.Context) {
    33  	// step 1: create ActivationCode
    34  	// Generate new activation code
    35  	ac, err := generateActivationCode()
    36  	if err != nil {
    37  		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create activation code: " + err.Error()})
    38  		return
    39  	}
    40  
    41  	// step 2: create DeviceBinding
    42  	deviceBinding := &api.DeviceBinding{
    43  		ObjectMeta: metav1.ObjectMeta{
    44  			GenerateName: "pair-",
    45  			Namespace:    config.Namespace,
    46  		},
    47  	}
    48  	k8sClient, ctx, cancel := config.GetClientandContext(c)
    49  	defer cancel()
    50  	if err := k8sClient.Create(ctx, deviceBinding); err != nil && !k8serrors.IsAlreadyExists(err) {
    51  		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create device binding: " + err.Error()})
    52  		return
    53  	}
    54  
    55  	deviceBinding.Status.ActivationCode = ac.Plain()
    56  	deviceBinding.Status.Timestamp = metav1.Now()
    57  	deviceBinding.Status.CodeUsed = false
    58  
    59  	err = k8sClient.Status().Update(ctx, deviceBinding)
    60  	if err != nil {
    61  		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to update deviceBinding status: " + err.Error()})
    62  		return
    63  	}
    64  
    65  	vip, err := config.GetVIP(ctx, k8sClient)
    66  	if err != nil {
    67  		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to retrieve VIP address: " + err.Error()})
    68  		return
    69  	}
    70  
    71  	resp := DevicePairResponse{
    72  		ConnectURL: config.ConnectURL + "/" + deviceBinding.Status.ActivationCode,
    73  		HostMapping: HostMapping{
    74  			Host: config.BootstrapHost,
    75  			VIP:  vip,
    76  		},
    77  	}
    78  	c.JSON(http.StatusOK, resp)
    79  }
    80  

View as plain text