{ lib, config, inputs, ... }: let inherit (lib) mkOption types; inherit (lib.types) attrsOf attrTag deferredModuleWith submoduleWith submodule ; functionType = import ./interface.nix; application-resources = { options.resources = mkOption { type = attrsOf ( attrTag ( lib.mapAttrs' (name: resource: { ${name} = mkOption { type = resource.consumer; }; }) config.resources ) ); }; }; nixops4Deployment = inputs.nixops4.modules.nixops4Deployment.default; in { options = { resources = mkOption { description = "Collection of deployment resources that can be configured by hosting providers and required by applications"; type = attrsOf ( submodule ( { config, ... }: { _class = "fediversity-resource"; options = { consumer = mkOption { description = "Configuration of the resource by an application, a description of how the resource is consumed"; type = deferredModuleWith { staticModules = [ { _class = "fediversity-resource-consumer"; } ]; }; }; provider = mkOption { description = "Configuration of the resource by the hosting provider, a description of how the resource is made available"; type = deferredModuleWith { staticModules = [ { _class = "fediversity-resource-provider"; } ]; }; }; }; } ) ); }; applications = mkOption { description = "Collection of Fediversity applications"; type = attrsOf ( submodule (application: { _class = "fediversity-application"; options = { module = mkOption { description = "Operator-facing configuration options for the application"; type = deferredModuleWith { staticModules = [ { _class = "fediversity-application-config"; } ]; }; }; config-mapping = mkOption { description = "Mapping of application configuration to deployment resources, a description of what an application needs to run"; type = application.config.function.implementation; }; # TODO: somewhere we still need to # - apply = { implementation = config-mapping; input = ; } # - apply.output (applications required by resources) function = mkOption { description = "Function type for the mapping from application configuration to required resources"; type = submodule functionType; readOnly = true; default = { input-type = application.config.module; output-type = application-resources; }; }; }; }) ); }; environments = mkOption { description = "Run-time environments for Fediversity applications to be deployed to"; type = attrsOf ( submodule (environment: { _class = "fediversity-environment"; options = { resources = mkOption { description = "Resources made available by the hosting provider"; type = attrsOf ( attrTag ( lib.mapAttrs' (name: resource: { ${name} = mkOption { type = resource.provider; }; }) config.resources ) ); }; resource-mapping = mkOption { description = "Mapping of resources required by applications to available resources; the result can be deployed"; type = environment.config.function.implementation; }; # TODO: somewhere we still need to # - apply = { implementation = resource-mapping; input = ; } # - apply.output (deployment) function = mkOption { description = "Function type for the mapping from resources to a (NixOps4) deployment"; type = submodule functionType; readOnly = true; default = { input-type = application-resources; output-type = submodule nixops4Deployment; }; }; }; }) ); }; configurations = mkOption { description = "Application configurations set by operators"; type = attrsOf (submodule { options = { enable = mkOption { description = "Whether to enable the configuration"; type = types.bool; }; applications = mapAttrs (name: application: submodule application.module) config.applications; }; }); }; }; }