Skip to content

Commit

Permalink
Add mkcert and hostctl instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
David Arnold committed Oct 9, 2020
1 parent 4859a38 commit 5a24b56
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# mimick use case where users are expected to boostrap their dev ca
# this is also better for testing devhsell ca bootstrapping
dev-ca
20 changes: 20 additions & 0 deletions devshell.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ packages = [
#
# motd = ""

# This setting helps to add a project's shared *development* root CA
# to host's local trust stores by instrumenting the mkcert third party tool.
# Defining this section also adds `mkcert` to the available packages.
# Set to the path where mkcert-generated CAROOT files are expected to exist
#
# NOTES:
# - be careful to only put *development* certificates under version control
# - create those files with the devshell generated *-install-CA command
# - optionally put this path under .gitignore, if you want users to
# generate certificates themselves on first clone (using *-install-CA)
dev-ca-path = "./dev-ca"

# Use this section to set environment variables to have in the environment.
#
# NOTE: all the values are escaped
Expand Down Expand Up @@ -54,3 +66,11 @@ help = "github utility"
name = "hub"
package = "gitAndTools.hub"
category = "utilites"

# These settings help to manage local DNS overrides via
# instrumentation of the hostcl third party tool.
# Defining this section also adds `hostctl` to the available packages.
[static-dns]
"test.domain.local" = "172.0.0.1"
"shared.domain.link-local" = "169.254.0.5"

14 changes: 8 additions & 6 deletions devshell/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ type configCommand struct {
}

type config struct {
Name string `toml:"name"`
Packages []string `toml:"packages"`
Motd *string `toml:"motd"`
Env map[string]interface{} `toml:"env"`
Bash configBash `toml:"bash,omitempty"`
Commands []configCommand `toml:"commands"`
Name string `toml:"name"`
Packages []string `toml:"packages"`
Motd *string `toml:"motd"`
DevCaPath *string `toml:"dev-ca-path,omitempty"`
Env map[string]interface{} `toml:"env"`
Bash configBash `toml:"bash,omitempty"`
Commands []configCommand `toml:"commands"`
StaticDNS map[string]interface{} `toml:"static-dns,omitempty"`
}

func configLoad(path string) (*config, error) {
Expand Down
19 changes: 19 additions & 0 deletions docs/devshell.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ packages = [
#
# motd = ""

# This setting helps to add a project's shared *development* root CA
# to host's local trust stores by instrumenting the mkcert third party tool.
# Defining this section also adds `mkcert` to the available packages.
# Set to the path where mkcert-generated CAROOT files are expected to exist
#
# NOTES:
# - be careful to only put *development* certificates under version control
# - create those files with the devshell generated *-install-CA command
# - optionally put this path under .gitignore, if you want users to
# generate certificates themselves on first clone (using *-install-CA)
# dev-ca-path = "./dev-ca"

# Use this section to set environment variables to have in the environment.
#
# NOTE: all the values are escaped
Expand Down Expand Up @@ -54,3 +66,10 @@ help = "github utility"
name = "hub"
package = "gitAndTools.hub"
category = "utilites"

# These settings help to manage local DNS overrides via
# instrumentation of the hostcl third party tool.
# Defining this section also adds `hostctl` to the available packages.
[static-dns]
"test.domain.local" = "172.0.0.1"
"shared.domain.link-local" = "169.254.0.5"
24 changes: 24 additions & 0 deletions docs/devshell.toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ packages = [
#
# motd = ""

# This setting helps to add a project's shared *development* root CA
# to host's local trust stores by instrumenting the mkcert third party tool.
# Defining this section also adds `mkcert` to the available packages.
# Set to the path where mkcert-generated CAROOT files are expected to exist
#
# NOTES:
# - be careful to only put *development* certificates under version control
# - create those files with the devshell generated *-install-CA command
# - optionally put this path under .gitignore, if you want users to
# generate certificates themselves on first clone (using *-install-CA)
# dev-ca-path = "./dev-ca"

# Use this section to set environment variables to have in the environment.
#
# NOTE: all the values are escaped
Expand Down Expand Up @@ -61,6 +73,14 @@ category = "formatters"
help = "github utility"
name = "hub"
package = "gitAndTools.hub"
category = "utilities"

# These settings help to manage local DNS overrides via
# instrumentation of the hostcl third party tool.
# Defining this section also adds `hostctl` to the available packages.
[static-dns]
"test.domain.local" = "172.0.0.1"
"shared.domain.link-local" = "169.254.0.5"
```

## Schema
Expand All @@ -84,6 +104,8 @@ The name field is optional and defaults to `devshell`.

### The `motd` field

### The `dev-ca-path` field

### The `env` section

### The `bash.extra` field
Expand All @@ -97,3 +119,5 @@ The name field is optional and defaults to `devshell`.
* `name`:
* `package`:

### The `static-dns` section

40 changes: 40 additions & 0 deletions hostctl/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{ buildGoModule, fetchFromGitHub, lib, installShellFiles }:

buildGoModule rec {
pname = "hostctl";
version = "1.0.14";

src = fetchFromGitHub {
owner = "guumaster";
repo = pname;
rev = "v${version}";
sha256 = "02bjii97l4fy43v2rb93m9b0ad8y6mjvbvp4sz6a5n0w9dm1z1q9";
};

vendorSha256 = "1lqk3cda0frqp2vwkqa4b3xkdw814wgkbr7g9r2mwxn85fpdcq5c";

doCheck = false;
buildFlagsArray = [ "-ldflags=-s -w -X github.com/guumaster/hostctl/cmd/hostctl/actions.version=${version}" ];

nativeBuildInputs = [ installShellFiles ];
postInstall = ''
$out/bin/hostctl completion bash > hostctl.bash
$out/bin/hostctl completion zsh > hostctl.zsh
installShellCompletion hostctl.{bash,zsh}
# replace above by following once merged https://github.com/NixOS/nixpkgs/pull/83630
# installShellCompletion --cmd hostctl \
# --bash <($out/bin/hostctl completion bash) \
# --zsh <($out/bin/hostctl completion zsh)
'';

meta = with lib; {
description = "Your dev tool to manage /etc/hosts like a pro!";
longDescription = ''
This tool gives you more control over the use of your hosts file.
You can have multiple profiles and switch them on/off as you need.
'';
homepage = "https://guumaster.github.io/hostctl/";
license = licenses.mit;
maintainers = with maintainers; [ blaggacao ];
};
}
64 changes: 64 additions & 0 deletions mkDevShell/instrumentation.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{ lib, pkgs, config }:
let
inherit (config)
name
dev-ca-path
static-dns
;
installProjectCA = {
name = "ca-install";
help = "install dev CA";
category = "host state";
package = pkgs.mkcert;
command = ''
echo "$(tput bold)Installing the ${name}'s dev CA into local trust stores via mkcert command ...$(tput sgr0)"
export CAROOT=${dev-ca-path}
${pkgs.mkcert}/bin/mkcert -install
'';
};
uninstallProjectCA = {
name = "ca-uninstall";
help = "uninstall dev CA";
category = "host state";
package = pkgs.mkcert;
command = ''
echo "$(tput bold)Purging the ${name}'s dev CA from local trust stores via mkcert command ...$(tput sgr0)"
export CAROOT=${dev-ca-path}
${pkgs.mkcert}/bin/mkcert -uninstall
'';
};

etcHosts = pkgs.writeText "${name}-etchosts"
(lib.concatStringsSep "\n"
(lib.mapAttrsToList (name: value: value + " " + name) static-dns)
);
# since this temporarily modifies /etc/hosts, use of sudo can't be avoided
fqdnsActivate = {
name = "dns-activate";
category = "host state";
help = "activate pre-configured static dns";
package = pkgs.hostctl;
command = ''
echo "$(tput bold)Installing ${name}'s static local DNS resolution via hostctl command ...$(tput sgr0)"
sudo ${pkgs.hostctl}/bin/hostctl add ${name} --from ${etcHosts}
'';
};
fqdnsDeactivate = {
name = "dns-deactivate";
category = "host state";
help = "deactivate pre-configured static dns";
package = pkgs.hostctl;
command = ''
echo "$(tput bold)Purging ${name}'s static local DNS resolution via hostctl command ...$(tput sgr0)"
sudo ${pkgs.hostctl}/bin/hostctl remove ${name}
'';
};
in
(
if static-dns == null || static-dns == "" then [ ]
else [ fqdnsActivate fqdnsDeactivate ]
) ++
(
if dev-ca-path == null || dev-ca-path == "" then [ ]
else [ installProjectCA uninstallProjectCA ]
)
53 changes: 50 additions & 3 deletions mkDevShell/options.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{ lib, pkgs, config, ... }:
with lib;
let
instrumentedCommands = import ./instrumentation.nix { inherit lib pkgs config; };

resolveKey = key:
let
attrs = builtins.filter builtins.isString (builtins.split "\\." key);
Expand Down Expand Up @@ -137,6 +139,27 @@ in
'';
};

# exclusively consumed by command instrumentation
dev-ca-path = mkOption {
type = types.str;
default = "";
description = ''
Path to a development CA.
Users can load/unload this dev CA easily and cleanly into their local
trust stores via a wrapper around mkcert third party tool so that browsers
and other tools would accept issued certificates under this CA as valid.
Use cases:
- Ship static dev certificates under version control and make them trusted
on user machines: add the rootCA under version control alongside the
your dev certificates.
- Provide users with easy and reliable CA bootstrapping through the mkcert
command: exempt this path from version control via .gitignore and have
users easily and reliably bootstrap a dev CA infrastructure on first use.
'';
};

commands = mkOption {
type = types.listOf (types.submodule { options = commandOptions; });
default = [ ];
Expand Down Expand Up @@ -210,6 +233,23 @@ in
'';
};

# exclusively consumed by command instrumentation
static-dns = mkOption {
type = types.attrs;
default = { };
description = ''
A list of static DNS entries, for which to enable instrumentation.
Users can enable/disable listed static DNS easily and cleanly
via a wrapper around the hostctl third party tool.
'';
example = {
"test.domain.local" = "172.0.0.1";
"shared.domain.link-local" = "169.254.0.5";
};
};


};

config = {
Expand All @@ -223,10 +263,17 @@ in
DEVSHELL_MENU
'';
}
];
] ++ instrumentedCommands;

packages =
builtins.filter (x: x != null)
(map (x: x.package) config.commands);
lib.unique (
builtins.filter
(x: x != null)
(
map
(x: x.package)
config.commands
)
);
};
}
1 change: 1 addition & 0 deletions overlay.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ final: prev:
{
devshell = prev.callPackage ./devshell { };
mkDevShell = prev.callPackage ./mkDevShell { };
hostctl = prev.callPackage ./hostctl { };
}

0 comments on commit 5a24b56

Please sign in to comment.