{
  pkgs ? (import <nixpkgs> { }),
}:
let
  lib = pkgs.lib;
  hive_mod =
    {
      lib,
      config,
      name,
      ...
    }:
    with lib;
    {
      options.deployment = {
        targetHost = mkOption { type = types.str; };
        rpc = mkOption {
          type = types.package;
          readOnly = true;
        };
        cmd = mkOption {
          type = types.package;
          readOnly = true;
        };
      };
      config.deployment = rec {
        rpc = pkgs.writeText "config-${name}_rpc.xml" ''
          <rpc>
            <edit-config>
              <config>
                ${config.netconf.xmls.configuration}
              </config>
              <target>
                <candidate/>
              </target>
            </edit-config>
          </rpc>
          <rpc>
            <commit/>
          </rpc>
        '';
        cmd = pkgs.writeShellApplication {
          name = "deploy-${name}.sh";
          runtimeInputs = with pkgs; [ openssh ];
          text = ''ssh "${config.deployment.targetHost}" -p 830 -s netconf < ${rpc}'';
        };
      };
    };
  evaluator =
    name: module_inst:
    let
      cfg = pkgs.lib.evalModules {
        specialArgs = {
          inherit name;
        };
        modules = [
          ./junos
          ./ex2300.nix
          hive_mod
          module_inst
        ];
      };
    in
    "ln -s ${lib.getExe cfg.config.deployment.cmd} $out/${name}";
  hive = import ./netconf-hive.nix;
  cmds = builtins.attrValues (builtins.mapAttrs evaluator hive);
in
pkgs.runCommand "netconf-deploy" { } (builtins.concatStringsSep "\n" ([ "mkdir $out" ] ++ cmds))