github.com/cozy/cozy-stack@v0.0.0-20240327093429-939e4a21320e/model/cloudery/service.go (about)

     1  package cloudery
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/url"
     7  
     8  	"github.com/cozy/cozy-stack/model/instance"
     9  	"github.com/cozy/cozy-stack/pkg/config/config"
    10  	"github.com/cozy/cozy-stack/pkg/manager"
    11  )
    12  
    13  var (
    14  	ErrInvalidContext = errors.New("missing or invalid context")
    15  )
    16  
    17  // ClouderyService handle all the Cloudery actions.
    18  type ClouderyService struct {
    19  	contexts map[string]config.ClouderyConfig
    20  }
    21  
    22  // NewService instantiate a new [ClouderyService].
    23  //
    24  // If contexts arg is nil, nil will be returned.
    25  func NewService(contexts map[string]config.ClouderyConfig) *ClouderyService {
    26  	if contexts == nil {
    27  		return nil
    28  	}
    29  
    30  	return &ClouderyService{contexts}
    31  }
    32  
    33  type SaveCmd struct {
    34  	Locale     string
    35  	Email      string
    36  	PublicName string
    37  }
    38  
    39  // SaveInstance data into the cloudery matching the instance context.
    40  func (s *ClouderyService) SaveInstance(inst *instance.Instance, cmd *SaveCmd) error {
    41  	client, err := s.getClient(inst)
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	url := fmt.Sprintf("/api/v1/instances/%s?source=stack", url.PathEscape(inst.UUID))
    47  	if err := client.Put(url, map[string]interface{}{
    48  		"locale":      cmd.Locale,
    49  		"email":       cmd.Email,
    50  		"public_name": cmd.PublicName,
    51  	}); err != nil {
    52  		return fmt.Errorf("request failed: %w", err)
    53  	}
    54  
    55  	return nil
    56  }
    57  
    58  func (s *ClouderyService) HasBlockingSubscription(inst *instance.Instance) (bool, error) {
    59  	client, err := s.getClient(inst)
    60  	if err != nil {
    61  		return false, err
    62  	}
    63  
    64  	url := fmt.Sprintf("/api/v1/instances/%s", url.PathEscape(inst.UUID))
    65  	res, err := client.Get(url)
    66  	if err != nil {
    67  		return false, fmt.Errorf("request failed: %w", err)
    68  	}
    69  
    70  	return hasBlockingSubscription(res), nil
    71  }
    72  
    73  func hasBlockingSubscription(clouderyInstance map[string]interface{}) bool {
    74  	return clouderyInstance["has_blocking_subscription"] == true
    75  }
    76  
    77  func (s *ClouderyService) getClient(inst *instance.Instance) (*manager.APIClient, error) {
    78  	cfg, ok := s.contexts[inst.ContextName]
    79  	if !ok {
    80  		cfg, ok = s.contexts[config.DefaultInstanceContext]
    81  	}
    82  
    83  	if !ok {
    84  		return nil, fmt.Errorf("%w: tried %q and %q", ErrInvalidContext, inst.ContextName, config.DefaultInstanceContext)
    85  	}
    86  
    87  	client := manager.NewAPIClient(cfg.API.URL, cfg.API.Token)
    88  
    89  	return client, nil
    90  }