feat(gitops): general improvements BE-12919 (#2780)
This commit is contained in:
@@ -16,115 +16,105 @@ import (
|
||||
// FetchWorkflows returns all GitOps workflows visible to the given user.
|
||||
func FetchWorkflows(
|
||||
ctx context.Context,
|
||||
dataStore dataservices.DataStore,
|
||||
tx dataservices.DataStoreTx,
|
||||
gitService portainer.GitService,
|
||||
k8sFactory *cli.ClientFactory,
|
||||
sc *security.RestrictedRequestContext,
|
||||
endpointIDSet set.Set[portainer.EndpointID],
|
||||
) ([]Workflow, error) {
|
||||
var stacks []portainer.Stack
|
||||
var endpointMap map[portainer.EndpointID]portainer.Endpoint
|
||||
gitConfigs := map[portainer.StackID]*gittypes.RepoConfig{}
|
||||
|
||||
err := dataStore.ViewTx(func(tx dataservices.DataStoreTx) error {
|
||||
var err error
|
||||
stacks, err = tx.Stack().ReadAll(func(s portainer.Stack) bool {
|
||||
return s.WorkflowID != 0 && (len(endpointIDSet) == 0 || endpointIDSet.Contains(s.EndpointID))
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
endpointMap, err = buildEndpointMap(tx, stacks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stacks, err = filterDockerStacksByAccess(tx, stacks, sc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// First pass: filter by endpoint/stack-type match and collect workflow IDs.
|
||||
preFiltered := make([]portainer.Stack, 0, len(stacks))
|
||||
workflowIDSet := make(map[portainer.WorkflowID]struct{}, len(stacks))
|
||||
for _, stack := range stacks {
|
||||
if ep, ok := endpointMap[stack.EndpointID]; ok && !EndpointMatchesStackType(ep, stack.Type) {
|
||||
continue
|
||||
}
|
||||
preFiltered = append(preFiltered, stack)
|
||||
workflowIDSet[stack.WorkflowID] = struct{}{}
|
||||
}
|
||||
|
||||
// Batch-load all needed workflows in one scan.
|
||||
workflows, err := tx.Workflow().ReadAll(func(wf portainer.Workflow) bool {
|
||||
_, ok := workflowIDSet[wf.ID]
|
||||
return ok
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
workflowMap := make(map[portainer.WorkflowID]portainer.Workflow, len(workflows))
|
||||
var allArtifacts []portainer.ArtifactSources
|
||||
for _, wf := range workflows {
|
||||
workflowMap[wf.ID] = wf
|
||||
allArtifacts = append(allArtifacts, wf.Artifacts...)
|
||||
}
|
||||
sourceSet := ArtifactsToSourceSet(allArtifacts...)
|
||||
|
||||
// Batch-load all needed sources in one scan.
|
||||
srcs, err := tx.Source().ReadAll(func(src portainer.Source) bool {
|
||||
return sourceSet.Contains(src.ID)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sourceMap := make(map[portainer.SourceID]portainer.Source, len(srcs))
|
||||
for _, src := range srcs {
|
||||
sourceMap[src.ID] = src
|
||||
}
|
||||
|
||||
// Second pass: build filtered list using in-memory lookups.
|
||||
var filtered []portainer.Stack
|
||||
for _, stack := range preFiltered {
|
||||
wf, ok := workflowMap[stack.WorkflowID]
|
||||
if !ok {
|
||||
log.Warn().Int("stackID", int(stack.ID)).Msg("workflow record missing for stack, skipping")
|
||||
continue
|
||||
}
|
||||
|
||||
outer:
|
||||
for _, as := range wf.Artifacts {
|
||||
if as.Artifact.StackID != stack.ID {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, srcID := range as.SourceIDs {
|
||||
src, ok := sourceMap[srcID]
|
||||
if !ok {
|
||||
log.Warn().Int("stackID", int(stack.ID)).Msg("source record missing for stack, skipping")
|
||||
break outer
|
||||
}
|
||||
|
||||
if src.Type == portainer.SourceTypeGit {
|
||||
gitConfigs[stack.ID] = MergeSourceAndArtifact(&src, &as.Artifact)
|
||||
break outer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filtered = append(filtered, stack)
|
||||
}
|
||||
stacks = filtered
|
||||
|
||||
return nil
|
||||
stacks, err := tx.Stack().ReadAll(func(s portainer.Stack) bool {
|
||||
return s.WorkflowID != 0 && (len(endpointIDSet) == 0 || endpointIDSet.Contains(s.EndpointID))
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
endpointMap, err := buildEndpointMap(tx, stacks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stacks, err = filterDockerStacksByAccess(tx, stacks, sc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// First pass: filter by endpoint/stack-type match and collect workflow IDs.
|
||||
preFiltered := make([]portainer.Stack, 0, len(stacks))
|
||||
workflowIDSet := make(map[portainer.WorkflowID]struct{}, len(stacks))
|
||||
for _, stack := range stacks {
|
||||
if ep, ok := endpointMap[stack.EndpointID]; ok && !EndpointMatchesStackType(ep, stack.Type) {
|
||||
continue
|
||||
}
|
||||
preFiltered = append(preFiltered, stack)
|
||||
workflowIDSet[stack.WorkflowID] = struct{}{}
|
||||
}
|
||||
|
||||
// Batch-load all needed workflows in one scan.
|
||||
wfs, err := tx.Workflow().ReadAll(func(wf portainer.Workflow) bool {
|
||||
_, ok := workflowIDSet[wf.ID]
|
||||
return ok
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
workflowMap := make(map[portainer.WorkflowID]portainer.Workflow, len(wfs))
|
||||
var allArtifacts []portainer.ArtifactSources
|
||||
for _, wf := range wfs {
|
||||
workflowMap[wf.ID] = wf
|
||||
allArtifacts = append(allArtifacts, wf.Artifacts...)
|
||||
}
|
||||
sourceSet := ArtifactsToSourceSet(allArtifacts...)
|
||||
|
||||
// Batch-load all needed sources in one scan.
|
||||
srcs, err := tx.Source().ReadAll(func(src portainer.Source) bool {
|
||||
return sourceSet.Contains(src.ID)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sourceMap := make(map[portainer.SourceID]portainer.Source, len(srcs))
|
||||
for _, src := range srcs {
|
||||
sourceMap[src.ID] = src
|
||||
}
|
||||
|
||||
// Second pass: build filtered list using in-memory lookups.
|
||||
var filtered []portainer.Stack
|
||||
for _, stack := range preFiltered {
|
||||
wf, ok := workflowMap[stack.WorkflowID]
|
||||
if !ok {
|
||||
log.Warn().Int("stackID", int(stack.ID)).Msg("workflow record missing for stack, skipping")
|
||||
continue
|
||||
}
|
||||
|
||||
outer:
|
||||
for _, as := range wf.Artifacts {
|
||||
if as.Artifact.StackID != stack.ID {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, srcID := range as.SourceIDs {
|
||||
src, ok := sourceMap[srcID]
|
||||
if !ok {
|
||||
log.Warn().Int("stackID", int(stack.ID)).Msg("source record missing for stack, skipping")
|
||||
break outer
|
||||
}
|
||||
|
||||
if src.Type == portainer.SourceTypeGit {
|
||||
gitConfigs[stack.ID] = MergeSourceAndArtifact(&src, &as.Artifact)
|
||||
break outer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filtered = append(filtered, stack)
|
||||
}
|
||||
stacks = filtered
|
||||
|
||||
accessMap, err := buildEndpointAccessMap(k8sFactory, sc, endpointMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user