diff --git a/cmd/osbuild-worker/config.go b/cmd/osbuild-worker/config.go index 9834436e9e..cc38385417 100644 --- a/cmd/osbuild-worker/config.go +++ b/cmd/osbuild-worker/config.go @@ -78,6 +78,13 @@ type executorConfig struct { CloudWatchGroup string `toml:"cloudwatch_group"` } +type repositoryMTLSConfig struct { + BaseURL string `toml:"baseurl"` + CA string `toml:"ca"` + MTLSClientKey string `toml:"mtls_client_key"` + MTLSClientCert string `toml:"mtls_client_cert"` +} + type workerConfig struct { Composer *composerConfig `toml:"composer"` Koji map[string]kojiServerConfig `toml:"koji"` @@ -93,7 +100,8 @@ type workerConfig struct { BasePath string `toml:"base_path"` DNFJson string `toml:"dnf-json"` // default value: &{ Type: host } - OSBuildExecutor *executorConfig `toml:"osbuild_executor"` + OSBuildExecutor *executorConfig `toml:"osbuild_executor"` + RepositoryMTLSConfig *repositoryMTLSConfig `toml:"repository_mtls"` } func parseConfig(file string) (*workerConfig, error) { diff --git a/cmd/osbuild-worker/jobimpl-depsolve.go b/cmd/osbuild-worker/jobimpl-depsolve.go index 3b3d356c48..e817103645 100644 --- a/cmd/osbuild-worker/jobimpl-depsolve.go +++ b/cmd/osbuild-worker/jobimpl-depsolve.go @@ -2,6 +2,8 @@ package main import ( "fmt" + "net/url" + "strings" "github.com/sirupsen/logrus" @@ -11,8 +13,36 @@ import ( "github.com/osbuild/osbuild-composer/internal/worker/clienterrors" ) +// Used by both depsolve and osbuild jobs +type RepositoryMTLSConfig struct { + BaseURL *url.URL + CA string + MTLSClientKey string + MTLSClientCert string +} + +func (rmc *RepositoryMTLSConfig) CompareBaseURL(baseURLStr string) (bool, error) { + baseURL, err := url.Parse(baseURLStr) + if err != nil { + return false, err + } + + if baseURL.Scheme != rmc.BaseURL.Scheme { + return false, nil + } + if baseURL.Host != rmc.BaseURL.Host { + return false, nil + } + if !strings.HasPrefix(baseURL.Path, rmc.BaseURL.Path) { + return false, nil + } + + return true, nil +} + type DepsolveJobImpl struct { - Solver *dnfjson.BaseSolver + Solver *dnfjson.BaseSolver + RepositoryMTLSConfig *RepositoryMTLSConfig } // depsolve each package set in the pacakgeSets map. The repositories defined @@ -43,6 +73,28 @@ func (impl *DepsolveJobImpl) Run(job worker.Job) error { } var result worker.DepsolveJobResult + + if impl.RepositoryMTLSConfig != nil { + for _, pkgsets := range args.PackageSets { + for _, pkgset := range pkgsets { + for _, repo := range pkgset.Repositories { + for _, baseurlstr := range repo.BaseURLs { + match, err := impl.RepositoryMTLSConfig.CompareBaseURL(baseurlstr) + if err != nil { + result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidRepositoryURL, "Repository URL is malformed", err) + return err + } + if match { + repo.SSLCACert = impl.RepositoryMTLSConfig.CA + repo.SSLClientKey = impl.RepositoryMTLSConfig.MTLSClientKey + repo.SSLClientCert = impl.RepositoryMTLSConfig.MTLSClientCert + } + } + } + } + } + } + result.PackageSpecs, err = impl.depsolve(args.PackageSets, args.ModulePlatformID, args.Arch, args.Releasever) if err != nil { switch e := err.(type) { diff --git a/cmd/osbuild-worker/jobimpl-osbuild.go b/cmd/osbuild-worker/jobimpl-osbuild.go index b8207dd748..8cff0e1d3c 100644 --- a/cmd/osbuild-worker/jobimpl-osbuild.go +++ b/cmd/osbuild-worker/jobimpl-osbuild.go @@ -84,18 +84,19 @@ type ExecutorConfiguration struct { } type OSBuildJobImpl struct { - Store string - Output string - OSBuildExecutor ExecutorConfiguration - KojiServers map[string]kojiServer - GCPConfig GCPConfiguration - AzureConfig AzureConfiguration - OCIConfig OCIConfiguration - AWSCreds string - AWSBucket string - S3Config S3Configuration - ContainersConfig ContainersConfiguration - PulpConfig PulpConfiguration + Store string + Output string + OSBuildExecutor ExecutorConfiguration + KojiServers map[string]kojiServer + GCPConfig GCPConfiguration + AzureConfig AzureConfiguration + OCIConfig OCIConfiguration + AWSCreds string + AWSBucket string + S3Config S3Configuration + ContainersConfig ContainersConfiguration + PulpConfig PulpConfiguration + RepositoryMTLSConfig *RepositoryMTLSConfig } // Returns an *awscloud.AWS object with the credentials of the request. If they @@ -484,6 +485,14 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error { } } + if impl.RepositoryMTLSConfig != nil { + if impl.RepositoryMTLSConfig.CA != "" { + extraEnv = append(extraEnv, fmt.Sprintf("OSBUILD_SOURCES_CURL_SSL_CLIENT_CERT=%s", impl.RepositoryMTLSConfig.CA)) + } + extraEnv = append(extraEnv, fmt.Sprintf("OSBUILD_SOURCES_CURL_SSL_CLIENT_KEY=%s", impl.RepositoryMTLSConfig.MTLSClientKey)) + extraEnv = append(extraEnv, fmt.Sprintf("OSBUILD_SOURCES_CURL_SSL_CLIENT_CERT=%s", impl.RepositoryMTLSConfig.MTLSClientCert)) + } + // Run osbuild and handle two kinds of errors var executor osbuildexecutor.Executor switch impl.OSBuildExecutor.Type { diff --git a/cmd/osbuild-worker/main.go b/cmd/osbuild-worker/main.go index 27dd700f35..2ae3b3fd27 100644 --- a/cmd/osbuild-worker/main.go +++ b/cmd/osbuild-worker/main.go @@ -7,6 +7,7 @@ import ( "errors" "flag" "fmt" + "net/url" "os" "path" "strings" @@ -433,6 +434,20 @@ func main() { pulpAddress = config.Pulp.ServerURL } + var repositoryMTLSConfig *RepositoryMTLSConfig + if config.RepositoryMTLSConfig != nil { + baseURL, err := url.Parse(config.RepositoryMTLSConfig.BaseURL) + if err != nil { + logrus.Fatalf("Repository MTL baseurl not valid: %v", err) + } + repositoryMTLSConfig = &RepositoryMTLSConfig{ + BaseURL: baseURL, + CA: config.RepositoryMTLSConfig.CA, + MTLSClientKey: config.RepositoryMTLSConfig.MTLSClientKey, + MTLSClientCert: config.RepositoryMTLSConfig.MTLSClientCert, + } + } + // depsolve jobs can be done during other jobs depsolveCtx, depsolveCtxCancel := context.WithCancel(context.Background()) solver := dnfjson.NewBaseSolver(rpmmd_cache) @@ -443,7 +458,8 @@ func main() { go func() { jobImpls := map[string]JobImplementation{ worker.JobTypeDepsolve: &DepsolveJobImpl{ - Solver: solver, + Solver: solver, + RepositoryMTLSConfig: repositoryMTLSConfig, }, } acceptedJobTypes := []string{} @@ -504,6 +520,7 @@ func main() { CredsFilePath: pulpCredsFilePath, ServerAddress: pulpAddress, }, + RepositoryMTLSConfig: repositoryMTLSConfig, }, worker.JobTypeKojiInit: &KojiInitJobImpl{ KojiServers: kojiServers, diff --git a/internal/worker/clienterrors/errors.go b/internal/worker/clienterrors/errors.go index 2692cdd31a..e575c57412 100644 --- a/internal/worker/clienterrors/errors.go +++ b/internal/worker/clienterrors/errors.go @@ -43,6 +43,7 @@ const ( ErrorRemoteFileResolution ClientErrorCode = 36 ErrorJobPanicked ClientErrorCode = 37 ErrorGeneratingSignedURL ClientErrorCode = 38 + ErrorInvalidRepositoryURL ClientErrorCode = 39 ) type ClientErrorCode int