Files
sub2api-cn-relay-manager/internal/provision/access_status_aggregation.go

129 lines
3.9 KiB
Go

package provision
import (
"context"
"strings"
"sub2api-cn-relay-manager/internal/pack"
"sub2api-cn-relay-manager/internal/store/sqlite"
)
type ModeAccessStatuses struct {
Subscription string
SelfService string
}
func SuggestResourceNamesForMode(provider pack.ProviderManifest, accessMode string) ResourceNames {
base := SuggestResourceNames(provider)
suffix := accessModeResourceSuffix(accessMode)
if suffix == "" {
return base
}
return ResourceNames{
Group: appendResourceNameSuffix(base.Group, suffix),
Channel: appendResourceNameSuffix(base.Channel, suffix),
Plan: appendResourceNameSuffix(base.Plan, suffix),
}
}
func accessModeResourceSuffix(accessMode string) string {
switch strings.TrimSpace(accessMode) {
case AccessModeSubscription:
return "subscription"
case AccessModeSelfService:
return "self-service"
default:
return ""
}
}
func appendResourceNameSuffix(name, suffix string) string {
name = strings.TrimSpace(name)
suffix = strings.TrimSpace(suffix)
if name == "" || suffix == "" {
return name
}
if strings.HasSuffix(name, "-"+suffix) {
return name
}
return name + "-" + suffix
}
func LatestModeAccessStatuses(ctx context.Context, store *sqlite.DB, batches []sqlite.ImportBatch) (ModeAccessStatuses, error) {
var statuses ModeAccessStatuses
for _, batch := range batches {
if statuses.Subscription != "" && statuses.SelfService != "" {
break
}
closures, err := store.AccessClosures().GetByBatchID(ctx, batch.ID)
if err != nil {
return ModeAccessStatuses{}, err
}
batchStatuses := modeAccessStatusesForBatch(batch, closures)
if statuses.Subscription == "" && strings.TrimSpace(batchStatuses.Subscription) != "" {
statuses.Subscription = strings.TrimSpace(batchStatuses.Subscription)
}
if statuses.SelfService == "" && strings.TrimSpace(batchStatuses.SelfService) != "" {
statuses.SelfService = strings.TrimSpace(batchStatuses.SelfService)
}
}
return statuses, nil
}
func modeAccessStatusesForBatch(batch sqlite.ImportBatch, closures []sqlite.AccessClosureRecord) ModeAccessStatuses {
statuses := ModeAccessStatuses{}
for _, closure := range closures {
status := strings.TrimSpace(closure.Status)
switch strings.TrimSpace(closure.ClosureType) {
case AccessModeSubscription:
statuses.Subscription = status
case AccessModeSelfService:
statuses.SelfService = status
}
}
if statuses.Subscription == "" && statuses.SelfService == "" {
return seedModeAccessStatuses(batch.AccessStatus)
}
return statuses
}
func seedModeAccessStatuses(accessStatus string) ModeAccessStatuses {
switch strings.TrimSpace(accessStatus) {
case AccessStatusFullyReady:
return ModeAccessStatuses{Subscription: AccessStatusSubscriptionReady, SelfService: AccessStatusSelfServiceReady}
case AccessStatusSubscriptionReady:
return ModeAccessStatuses{Subscription: AccessStatusSubscriptionReady}
case AccessStatusSelfServiceReady:
return ModeAccessStatuses{SelfService: AccessStatusSelfServiceReady}
default:
return ModeAccessStatuses{}
}
}
func AggregateAccessStatus(statuses ModeAccessStatuses) string {
subscriptionReady := isReadyAccessStatus(statuses.Subscription, AccessModeSubscription)
selfServiceReady := isReadyAccessStatus(statuses.SelfService, AccessModeSelfService)
switch {
case subscriptionReady && selfServiceReady:
return AccessStatusFullyReady
case subscriptionReady:
return AccessStatusSubscriptionReady
case selfServiceReady:
return AccessStatusSelfServiceReady
default:
return AccessStatusBroken
}
}
func isReadyAccessStatus(status, mode string) bool {
status = strings.TrimSpace(status)
switch mode {
case AccessModeSubscription:
return status == AccessStatusSubscriptionReady || status == AccessStatusFullyReady
case AccessModeSelfService:
return status == AccessStatusSelfServiceReady || status == AccessStatusFullyReady
default:
return status != "" && status != AccessStatusBroken
}
}