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 } }