devenv icon indicating copy to clipboard operation
devenv copied to clipboard

Cloudflare tunnel support

Open domenkozar opened this issue 2 years ago • 1 comments

WIP:

{ pkgs, lib, config, ... }: {

  options.services.cloudflare = {
    package = lib.mkOption {
      type = lib.types.package;
      default = pkgs.cloudflared;
      defaultText = "pkgs.cloudflared";
      description = "Cloudflare Tunnel package to use.";
    };

    tunnels = lib.mkOption {
      description = ''
        Cloudflare tunnels.
      '';

      type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
        options = {

          default = lib.mkOption {
            type = lib.types.str;
            description = lib.mdDoc ''
              Catch-all service if no ingress matches.
            '';
            example = "http_status:404";
          };
          gress = lib.mkOption {
            type = with lib.types; attrsOf (either str (submodule ({ hostname, ... }: {
              options = {
                inherit originRequest;

                service = lib.mkOption {
                  type = with lib.types; nullOr str;
                  default = null;
                  description = lib.mdDoc ''
                    Service to pass the traffic.
                    See [https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/local-management/ingress/#supported-protocols](Supported protocols).
                  '';
                  example = "http://localhost:80, tcp://localhost:8000, unix:/home/production/echo.sock, hello_world or http_status:404";
                };

                path = lib.mkOption {
                  type = with lib.types; nullOr str;
                  default = null;
                  description = lib.mdDoc ''
                    Path filter.
                    If not specified, all paths will be matched.
                  '';
                  example = "/*.(jpg|png|css|js)";
                };

              };
            })));
            default = { };
            description = lib.mdDoc ''
              Ingress rules.
              See [https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/local-management/ingress/](Ingress rules).
            '';
            example = {
              "*.domain.com" = "http://localhost:80";
              "*.anotherone.com" = "http://localhost:80";
            };
          };
        };
      }));


    };
  };

  config = lib.mkIf (config.services.cloudflare.tunnels != { }) {
    processes.cloudflared-tunnel.exec = ''
      ${config.cloudflare.package}/bin/cloudflared tunnel --no-autoupdate run ${config.cloudflare.tunnel.name}
    '';

    # TODO: fullConfig
  };

  #$ cloudflared tunnel create my-first-tunnel
  #$ cloudflared tunnel route dns my-first-tunnel my-first-tunnel.mydomain.com
  #$ cloudflared tunnel run --hello-world my-first-tunnel
}

domenkozar avatar Apr 20 '23 12:04 domenkozar