cluster/nix: locally build nixos derivations

We change the existing behaviour (copy files & run nixos-rebuild switch)
to something closer to nixops-style. This now means that provisioning
admin machines need Nix installed locally, but that's probably an okay
choice to make.

The upside of this approach is that it's easier to debug and test
derivations, as all data is local to the repo and the workstation, and
deploying just means copying a configuration closure and switching the
system to it. At some point we should even be able to run the entire
cluster within a set of test VMs.

We also bump the kubernetes control plane to 1.14. Kubelets are still at
1.13 and their upgrade is comint up today too.

Change-Id: Ia9832c47f258ee223d93893d27946d1161cc4bbd
diff --git a/cluster/nix/defs-cluster-k0.nix b/cluster/nix/defs-cluster-k0.nix
new file mode 100644
index 0000000..832c741
--- /dev/null
+++ b/cluster/nix/defs-cluster-k0.nix
@@ -0,0 +1,76 @@
+machineName:
+
+let
+  machines = (import ./defs-machines.nix);
+in rec {
+  domain = ".hswaw.net";
+  k8sapi = "k0.hswaw.net";
+  acmeEmail = "q3k@hackerspace.pl";
+
+  fqdn = machineName + domain;
+  machine = (builtins.head (builtins.filter (n: n.fqdn == fqdn) machines));
+  otherMachines = (builtins.filter (n: n.fqdn != fqdn) machines);
+  inherit machines;
+
+  pki = rec {
+    make = (radix: name: rec {
+      ca = ./../certs + "/ca-${radix}.crt";
+      cert = ./../certs + "/${radix}-${name}.cert";
+      key = ./../secrets/plain + "/${radix}-${name}.key";
+
+      json = (builtins.toJSON {
+        ca = (builtins.toString ca);
+        cert = (builtins.toString cert);
+        key = (builtins.toString key);
+      });
+    });
+
+    etcdPeer = (make "etcdpeer" fqdn);
+
+    etcd = {
+        server = (make "etcd" fqdn);
+        kube = (make "etcd" "kube");
+    };
+
+    makeKube = (name: (make "kube" name) // {
+      config = {
+        server = "https://${k8sapi}:${toString ports.k8sAPIServerSecure}";
+        certFile = (make "kube" name).cert;
+        keyFile = (make "kube" name).key;
+      };
+    });
+
+    kube = rec {
+      ca = apiserver.ca;
+      
+      # Used to identify apiserver.
+      apiserver = (makeKube "apiserver");
+
+      # Used to identify controller-manager.
+      controllermanager = (makeKube "controllermanager");
+
+      # Used to identify scheduler.
+      scheduler = (makeKube "scheduler");
+
+      # Used to identify kube-proxy.
+      proxy = (makeKube "proxy");
+
+      # Used to identify kubelet.
+      kubelet = (makeKube "kubelet-${fqdn}");
+
+      # Used to encrypt service accounts.
+      serviceaccounts = (makeKube "serviceaccounts");
+    };
+
+    kubeFront = {
+      apiserver = (make "kubefront" "apiserver");
+    };
+  };
+
+  ports = {
+    k8sAPIServerPlain = 4000;
+    k8sAPIServerSecure = 4001;
+    k8sControllerManagerPlain = 0; # 4002; do not serve plain http
+    k8sControllerManagerSecure = 4003;
+  };
+}