module Ecluse.Composition.Worker (
workerPoliciesFor,
mirrorTransportFor,
) where
import Data.Map.Strict qualified as Map
import Ecluse.Composition (PublishTarget (ptCredentials, ptEcosystem, ptMirrorUrl))
import Ecluse.Core.Credential (AuthToken (authSecret), currentToken)
import Ecluse.Core.Ecosystem (Ecosystem, parseEcosystem)
import Ecluse.Core.Registry.Adapter (adapterFor, adapterPublish, publishCodec)
import Ecluse.Core.Registry.Metadata (fetchVersionDetails)
import Ecluse.Core.Registry.Publish (
MirrorPublish,
MirrorTransport (MirrorTransport, ptLimits, ptManager, ptMintToken),
newMirrorPublish,
)
import Ecluse.Core.Security (Limits (maxBodyBytes), Origin (UntrustedOrigin), defaultLimits, thgPublicHostPort)
import Ecluse.Core.Server.Cache (Source (Source))
import Ecluse.Core.Server.Context (
PackumentDeps,
pdBuildArtifactRequestByUrl,
pdLimits,
pdMinIntegrity,
pdNewMetadataClient,
pdNow,
pdPublicBaseUrl,
pdRules,
pdTarballHostGate,
tarballHostHonoured,
)
import Ecluse.Core.Server.Metadata (ManifestCaching (Cached))
import Ecluse.Core.Telemetry.Metrics (Upstream (Public))
import Ecluse.Core.Worker (WorkerPolicies, WorkerPolicy (..))
import Ecluse.Runtime.Env (Env, envManager, envMetadataCache, envMetrics, envPrivateManager, envTelemetry)
import Ecluse.Runtime.Server (MountBinding (bindingPackumentDeps, bindingPrefix))
import Ecluse.Runtime.Telemetry.Instruments (metricsPortOf)
import Ecluse.Runtime.Telemetry.Tracing (tracingPortOf)
workerPoliciesFor :: Env -> [MountBinding] -> [PublishTarget] -> Int -> WorkerPolicies
workerPoliciesFor :: Env -> [MountBinding] -> [PublishTarget] -> Int -> WorkerPolicies
workerPoliciesFor Env
env [MountBinding]
bindings [PublishTarget]
targets Int
artifactMaxBytes =
[(Ecosystem, WorkerPolicy)] -> WorkerPolicies
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
[ (Ecosystem
eco, Env -> PackumentDeps -> MirrorPublish -> Int -> WorkerPolicy
workerPolicyFor Env
env PackumentDeps
deps MirrorPublish
publish Int
artifactMaxBytes)
| MountBinding
binding <- [MountBinding]
bindings
, let Text
prefixHead :| [Text]
_ = MountBinding -> NonEmpty Text
bindingPrefix MountBinding
binding
, let deps :: PackumentDeps
deps = MountBinding -> PackumentDeps
bindingPackumentDeps MountBinding
binding
, Just Ecosystem
eco <- [Text -> Maybe Ecosystem
parseEcosystem Text
prefixHead]
, Just MirrorPublish
publish <- [Env
-> PackumentDeps
-> Map Ecosystem PublishTarget
-> Ecosystem
-> Maybe MirrorPublish
mirrorPublishFor Env
env PackumentDeps
deps Map Ecosystem PublishTarget
targetsByEcosystem Ecosystem
eco]
]
where
targetsByEcosystem :: Map Ecosystem PublishTarget
targetsByEcosystem = [(Ecosystem, PublishTarget)] -> Map Ecosystem PublishTarget
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(PublishTarget -> Ecosystem
ptEcosystem PublishTarget
target, PublishTarget
target) | PublishTarget
target <- [PublishTarget]
targets]
mirrorPublishFor :: Env -> PackumentDeps -> Map.Map Ecosystem PublishTarget -> Ecosystem -> Maybe MirrorPublish
mirrorPublishFor :: Env
-> PackumentDeps
-> Map Ecosystem PublishTarget
-> Ecosystem
-> Maybe MirrorPublish
mirrorPublishFor Env
env PackumentDeps
deps Map Ecosystem PublishTarget
targets Ecosystem
eco = do
target <- Ecosystem -> Map Ecosystem PublishTarget -> Maybe PublishTarget
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Ecosystem
eco Map Ecosystem PublishTarget
targets
adapter <- adapterFor eco
pure (newMirrorPublish (mirrorTransportFor env deps target) (ptMirrorUrl target) (publishCodec (adapterPublish adapter)))
mirrorTransportFor :: Env -> PackumentDeps -> PublishTarget -> MirrorTransport
mirrorTransportFor :: Env -> PackumentDeps -> PublishTarget -> MirrorTransport
mirrorTransportFor Env
env PackumentDeps
deps PublishTarget
target =
MirrorTransport
{ ptManager :: Manager
ptManager = Env -> Manager
envPrivateManager Env
env
, ptMintToken :: IO (Maybe Secret)
ptMintToken = Secret -> Maybe Secret
forall a. a -> Maybe a
Just (Secret -> Maybe Secret)
-> (AuthToken -> Secret) -> AuthToken -> Maybe Secret
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AuthToken -> Secret
authSecret (AuthToken -> Maybe Secret) -> IO AuthToken -> IO (Maybe Secret)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CredentialProvider -> IO AuthToken
currentToken (PublishTarget -> CredentialProvider
ptCredentials PublishTarget
target)
, ptLimits :: Limits
ptLimits = PackumentDeps -> Limits
pdLimits PackumentDeps
deps
}
workerPolicyFor :: Env -> PackumentDeps -> MirrorPublish -> Int -> WorkerPolicy
workerPolicyFor :: Env -> PackumentDeps -> MirrorPublish -> Int -> WorkerPolicy
workerPolicyFor Env
env PackumentDeps
deps MirrorPublish
publish Int
artifactMaxBytes =
WorkerPolicy
{ wpResolveVersion :: PackageName -> Version -> IO VersionEvaluation
wpResolveVersion = MetadataClient -> PackageName -> Version -> IO VersionEvaluation
fetchVersionDetails MetadataClient
client
, wpRules :: [PreparedRule]
wpRules = PackumentDeps -> [PreparedRule]
pdRules PackumentDeps
deps
, wpMinIntegrity :: MinIntegrity
wpMinIntegrity = PackumentDeps -> MinIntegrity
pdMinIntegrity PackumentDeps
deps
, wpArtifactHostHonoured :: Maybe HostPort -> Bool
wpArtifactHostHonoured =
Origin -> PackumentDeps -> Maybe HostPort -> Maybe HostPort -> Bool
tarballHostHonoured Origin
UntrustedOrigin PackumentDeps
deps (TarballHostGate -> Maybe HostPort
thgPublicHostPort (PackumentDeps -> TarballHostGate
pdTarballHostGate PackumentDeps
deps))
,
wpBuildArtifactRequest :: Limits
-> Manager
-> Text
-> Maybe Secret
-> Text
-> Either UrlFormationError Request
wpBuildArtifactRequest = PackumentDeps
-> Limits
-> Manager
-> Text
-> Maybe Secret
-> Text
-> Either UrlFormationError Request
pdBuildArtifactRequestByUrl PackumentDeps
deps
, wpPublish :: MirrorPublish
wpPublish = MirrorPublish
publish
,
wpArtifactLimits :: Limits
wpArtifactLimits = Limits
defaultLimits{maxBodyBytes = artifactMaxBytes}
, wpNow :: IO UTCTime
wpNow = PackumentDeps -> IO UTCTime
pdNow PackumentDeps
deps
}
where
client :: MetadataClient
client =
PackumentDeps
-> TracingPort
-> MetricsPort
-> Upstream
-> ManifestCaching
-> (PackageName -> MetadataError -> IO ())
-> (PackageName -> [InvalidEntry] -> IO ())
-> (PackageName -> IO ())
-> Limits
-> Manager
-> Text
-> Maybe Secret
-> MetadataClient
pdNewMetadataClient
PackumentDeps
deps
(Telemetry -> TracingPort
tracingPortOf (Env -> Telemetry
envTelemetry Env
env))
(Metrics -> MetricsPort
metricsPortOf (Env -> Metrics
envMetrics Env
env))
Upstream
Public
(MetadataCache -> Source -> ManifestCaching
Cached (Env -> MetadataCache
envMetadataCache Env
env) (Text -> Source
Source (PackumentDeps -> Text
pdPublicBaseUrl PackumentDeps
deps)))
(\PackageName
_ MetadataError
_ -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
(\PackageName
_ [InvalidEntry]
_ -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
(\PackageName
_ -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
(PackumentDeps -> Limits
pdLimits PackumentDeps
deps)
(Env -> Manager
envManager Env
env)
(PackumentDeps -> Text
pdPublicBaseUrl PackumentDeps
deps)
Maybe Secret
forall a. Maybe a
Nothing