mirror of
https://github.com/portainer/portainer.git
synced 2026-06-23 07:40:11 +00:00
107 lines
3.0 KiB
Go
107 lines
3.0 KiB
Go
package workflows
|
|
|
|
import (
|
|
"context"
|
|
|
|
portainer "github.com/portainer/portainer/api"
|
|
"github.com/portainer/portainer/api/dataservices"
|
|
gittypes "github.com/portainer/portainer/api/git/types"
|
|
"github.com/portainer/portainer/api/http/security"
|
|
"github.com/portainer/portainer/api/kubernetes/cli"
|
|
"github.com/portainer/portainer/api/set"
|
|
)
|
|
|
|
// FetchWorkflows returns all GitOps workflows visible to the given user.
|
|
func FetchWorkflows(
|
|
ctx context.Context,
|
|
dataStore dataservices.DataStore,
|
|
gitService portainer.GitService,
|
|
k8sFactory *cli.ClientFactory,
|
|
sc *security.RestrictedRequestContext,
|
|
endpointIDSet set.Set[portainer.EndpointID],
|
|
) ([]Workflow, error) {
|
|
var entries []portainer.Stack
|
|
var endpointMap map[portainer.EndpointID]portainer.Endpoint
|
|
|
|
err := dataStore.ViewTx(func(tx dataservices.DataStoreTx) error {
|
|
stacks, err := tx.Stack().ReadAll(func(s portainer.Stack) bool {
|
|
return s.GitConfig != nil && (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
|
|
}
|
|
|
|
for i := range stacks {
|
|
s := stacks[i]
|
|
|
|
if ep, ok := endpointMap[s.EndpointID]; ok && !EndpointMatchesStackType(ep, s.Type) {
|
|
continue
|
|
}
|
|
entries = append(entries, s)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
accessMap, err := buildEndpointAccessMap(k8sFactory, sc, endpointMap)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
entries, err = filterK8SStacks(entries, endpointMap, k8sFactory, accessMap)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
items := make([]Workflow, 0, len(entries))
|
|
for _, s := range entries {
|
|
gitEntries := []GitEntries{
|
|
{Name: s.GitConfig.ConfigFilePath, IsFile: true},
|
|
}
|
|
for _, additionalPath := range s.AdditionalFiles {
|
|
gitEntries = append(gitEntries, GitEntries{Name: additionalPath, IsFile: true})
|
|
}
|
|
|
|
source, artifact := computePhases(ctx, gitService, s.GitConfig, gitEntries)
|
|
items = append(items, MapStackToWorkflow(s, s.GitConfig, source, artifact))
|
|
}
|
|
|
|
return items, nil
|
|
}
|
|
|
|
func computePhases(ctx context.Context, gitSvc portainer.GitService, cfg *gittypes.RepoConfig, gitEntries []GitEntries) (source, artifact WorkflowPhaseStatus) {
|
|
if gitSvc == nil || cfg == nil {
|
|
return WorkflowPhaseStatus{Status: StatusUnknown}, WorkflowPhaseStatus{Status: StatusUnknown}
|
|
}
|
|
|
|
username, password := gitCredentials(cfg)
|
|
return ComputeGitPhases(ctx, cfg.ReferenceName, gitEntries,
|
|
func(ctx context.Context) ([]string, error) {
|
|
return gitSvc.ListRefs(ctx, cfg.URL, username, password, false, cfg.TLSSkipVerify)
|
|
},
|
|
func(ctx context.Context, exts []string, dirOnly bool) ([]string, error) {
|
|
return gitSvc.ListFiles(ctx, cfg.URL, cfg.ReferenceName, username, password, dirOnly, false, exts, cfg.TLSSkipVerify)
|
|
},
|
|
)
|
|
}
|
|
|
|
func gitCredentials(cfg *gittypes.RepoConfig) (username, password string) {
|
|
if cfg.Authentication != nil {
|
|
return cfg.Authentication.Username, cfg.Authentication.Password
|
|
}
|
|
return "", ""
|
|
}
|