{ lib, config, ... }: let inherit (lib) mkOption types; inherit (lib.types) attrsOf attrTag deferredModuleWith submodule optionType functionTo ; functionType = import ./function.nix; application-resources = { options.resources = mkOption { # TODO: maybe transpose, and group the resources by type instead type = attrsOf ( attrTag (lib.mapAttrs (_name: resource: mkOption { type = resource.request; }) config.resources) ); }; }; in { _class = "nixops4Deployment"; options = { applications = mkOption { description = "Collection of Fediversity applications"; type = attrsOf ( submodule (application: { _class = "fediversity-application"; options = { description = mkOption { description = "Description to be shown in the application overview"; type = types.str; }; module = mkOption { description = "Operator-facing configuration options for the application"; type = deferredModuleWith { staticModules = [ { _class = "fediversity-application-config"; } ]; }; }; implementation = mkOption { description = "Mapping of application configuration to deployment resources, a description of what an application needs to run"; type = application.config.config-mapping.function-type; }; resources = mkOption { description = "Compute resources required by an application"; type = functionTo application.config.config-mapping.output-type; readOnly = true; default = input: (application.config.implementation input).output; }; config-mapping = 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; }; }; }; }) ); }; configuration = mkOption { description = "Configuration type declaring options to be set by operators"; type = optionType; readOnly = true; default = submodule { options = { enable = lib.mkEnableOption { description = "your Fediversity configuration"; }; applications = lib.mapAttrs ( _name: application: mkOption { description = application.description; type = submodule application.module; default = { }; } ) config.applications; }; }; }; 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"; # TODO: type = consumer-resources /* same as the output of application.config-mapping, should be in a `let` */ -> nixops4Deployment }; }; }) ); }; }; }