121 lines
3.9 KiB
Go
121 lines
3.9 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"gitea.maximumdirect.net/eric/distributor/internal/bundle"
|
|
"gitea.maximumdirect.net/eric/distributor/internal/config"
|
|
"gitea.maximumdirect.net/eric/distributor/internal/storage"
|
|
)
|
|
|
|
type sourceCommandOptions struct {
|
|
CommandName string
|
|
Path string
|
|
ConfigPath string
|
|
PipelineID string
|
|
BundlePath string
|
|
}
|
|
|
|
type sourceSelection struct {
|
|
Bundles []bundle.Bundle
|
|
PipelineID string
|
|
SourceBackend string
|
|
ConfigMode bool
|
|
Warnings []OutputWarning
|
|
}
|
|
|
|
func selectSourceBundles(ctx context.Context, options sourceCommandOptions, provider backendFactoryProvider) (sourceSelection, error) {
|
|
if err := ctx.Err(); err != nil {
|
|
return sourceSelection{}, err
|
|
}
|
|
if options.ConfigPath != "" {
|
|
cfg, err := config.LoadFile(options.ConfigPath)
|
|
if err != nil {
|
|
return sourceSelection{}, err
|
|
}
|
|
return selectSourceBundlesFromConfig(ctx, cfg, options, provider)
|
|
}
|
|
if options.PipelineID != "" {
|
|
return sourceSelection{}, fmt.Errorf("configured source mode requires --config")
|
|
}
|
|
if options.BundlePath != "" {
|
|
return sourceSelection{}, fmt.Errorf("configured source mode requires --config")
|
|
}
|
|
if options.Path == "" {
|
|
return sourceSelection{}, fmt.Errorf("%s command requires a path", options.CommandName)
|
|
}
|
|
backend, err := newBackendFactory().openLocalPath(ctx, options.Path)
|
|
if err != nil {
|
|
return sourceSelection{}, err
|
|
}
|
|
defer closeBackend(backend)
|
|
bundles, err := bundle.Discover(ctx, backend, "")
|
|
if err != nil {
|
|
return sourceSelection{}, err
|
|
}
|
|
return sourceSelection{Bundles: bundles}, nil
|
|
}
|
|
|
|
func selectSourceBundlesFromConfig(ctx context.Context, cfg config.Config, options sourceCommandOptions, provider backendFactoryProvider) (sourceSelection, error) {
|
|
if options.Path != "" {
|
|
return sourceSelection{}, fmt.Errorf("configured source mode does not accept a local path")
|
|
}
|
|
if options.PipelineID == "" {
|
|
return sourceSelection{}, fmt.Errorf("configured source mode requires --pipeline")
|
|
}
|
|
secretLoad, err := config.LoadSecretEnvironment(cfg.Secrets.Directory, nil)
|
|
if err != nil {
|
|
return sourceSelection{}, err
|
|
}
|
|
pipeline, ok := findPipeline(cfg, options.PipelineID)
|
|
if !ok {
|
|
return sourceSelection{}, fmt.Errorf("pipeline %q not found", options.PipelineID)
|
|
}
|
|
backends := provider(secretLoad.Environment)
|
|
sourceBackend, err := backends.openSource(ctx, pipeline.Source)
|
|
if err != nil {
|
|
return sourceSelection{}, fmt.Errorf("pipeline %s source backend %s: %w", pipeline.ID, pipeline.Source.Backend, err)
|
|
}
|
|
defer closeBackend(sourceBackend)
|
|
|
|
var bundles []bundle.Bundle
|
|
if options.BundlePath != "" {
|
|
sourceBundle, err := bundle.Validate(ctx, sourceBackend, options.BundlePath)
|
|
if err != nil {
|
|
return sourceSelection{}, fmt.Errorf("pipeline %s source backend %s bundle %s: %w", pipeline.ID, pipeline.Source.Backend, storage.DisplayPath(options.BundlePath), err)
|
|
}
|
|
bundles = []bundle.Bundle{sourceBundle}
|
|
} else {
|
|
bundles, err = bundle.Discover(ctx, sourceBackend, "")
|
|
if err != nil {
|
|
return sourceSelection{}, fmt.Errorf("pipeline %s source backend %s discover source bundles: %w", pipeline.ID, pipeline.Source.Backend, err)
|
|
}
|
|
}
|
|
return sourceSelection{
|
|
Bundles: bundles,
|
|
PipelineID: pipeline.ID,
|
|
SourceBackend: pipeline.Source.Backend,
|
|
ConfigMode: true,
|
|
Warnings: append(secretConflictWarnings(secretLoad.Conflicts), sourceSSHWarnings(pipeline)...),
|
|
}, nil
|
|
}
|
|
|
|
func findPipeline(cfg config.Config, id string) (config.Pipeline, bool) {
|
|
for _, pipeline := range cfg.Pipelines {
|
|
if pipeline.ID == id {
|
|
return pipeline, true
|
|
}
|
|
}
|
|
return config.Pipeline{}, false
|
|
}
|
|
|
|
func sourceSSHWarnings(pipeline config.Pipeline) []OutputWarning {
|
|
if pipeline.Source.Backend != config.BackendSSH || pipeline.Source.SSH.HostKeyPolicy != config.HostKeyPolicyOff {
|
|
return nil
|
|
}
|
|
return []OutputWarning{{
|
|
Message: fmt.Sprintf("pipeline=%s source host_key_policy=off disables SSH host key checking", pipeline.ID),
|
|
}}
|
|
}
|