cluster: deploy coredns
diff --git a/tools/clustercfg.py b/tools/clustercfg.py
index 29e42a4..a36664a 100644
--- a/tools/clustercfg.py
+++ b/tools/clustercfg.py
@@ -96,8 +96,20 @@
     if san:
         config.seek(0, 2)
         config.write(b'\n[SAN]\n')
+        config.write(b'subjectAltName = @alt_names\n')
+        config.write(b'basicConstraints = CA:FALSE\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment\n')
+        config.write(b'[alt_names]\n')
+
+        ipcnt = 1
+        dnscnt = 1
         for s in san:
-            config.write('subjectAltName=DNS:{}\n'.format(s).encode())
+            parts = s.split(':')
+            if s.startswith('DNS'):
+                config.write('DNS.{} = {}\n'.format(dnscnt, parts[1]).encode())
+                dnscnt += 1
+            elif s.startswith('IP'):
+                config.write('IP.{} = {}\n'.format(ipcnt, parts[1]).encode())
+                ipcnt += 1
 
     f = tempfile.NamedTemporaryFile(delete=False)
     path = f.name
@@ -192,32 +204,30 @@
     else:
         generate_cert = True
 
-    if not generate_cert:
-        return False
+    if generate_cert:
+        local_csr_f = tempfile.NamedTemporaryFile(delete=False)
+        local_csr = local_csr_f.name
+        local_csr_f.close()
 
-    local_csr_f = tempfile.NamedTemporaryFile(delete=False)
-    local_csr = local_csr_f.name
-    local_csr_f.close()
+        local_config = openssl_config(san)
 
-    local_config = openssl_config(san)
+        subprocess.check_call([
+            'openssl', 'req', '-new',
+            '-key', local_key,
+            '-out', local_csr,
+            '-subj', str(subj),
+            '-config', local_config,
+        ] + ([
+            '-reqexts', 'SAN',
+        ] if san else []))
 
-    subprocess.check_call([
-        'openssl', 'req', '-new',
-        '-key', local_key,
-        '-out', local_csr,
-        '-subj', str(subj),
-        '-config', local_config,
-    ] + ([
-        '-reqexts', 'SAN',
-    ] if san else []))
-
-    pki.sign(local_csr, local_cert, local_config, days)
+        pki.sign(local_csr, local_cert, local_config, days)
+        os.remove(local_csr)
+        os.remove(local_config)
 
     c.put(local=local_key, remote=remote_key)
     c.put(local=local_cert, remote=remote_cert)
 
-    os.remove(local_csr)
-    os.remove(local_config)
     return True
 
 
@@ -312,27 +322,15 @@
 
     modified = False
     modified |= remote_cert(p, c, fqdn, "node", Subject(Subject.hswaw, 'Node Certificate', fqdn))
-    modified |= remote_cert(p, c, fqdn, "kube-node", Subject('system:nodes', 'Kubelet Certificate', 'system:node:' + fqdn), san=[fqdn,])
+    modified |= remote_cert(p, c, fqdn, "kube-node", Subject('system:nodes', 'Kubelet Certificate', 'system:node:' + fqdn), san=["DNS:"+fqdn,])
     for component in ['controller-manager', 'proxy', 'scheduler']:
         o = 'system:kube-{}'.format(component)
         ou = 'Kuberneter Component {}'.format(component)
         modified |= shared_cert(p, c, fqdn, 'kube-{}'.format(component), Subject(o, ou, o))
-    modified |= shared_cert(p, c, fqdn, 'kube-apiserver', Subject(Subject.hswaw, 'Kubernetes API', cluster))
+    modified |= shared_cert(p, c, fqdn, 'kube-apiserver', Subject(Subject.hswaw, 'Kubernetes API', cluster), san=['IP:10.10.12.1', 'DNS:' + cluster])
     modified |= shared_cert(p, c, fqdn, 'kube-serviceaccounts', Subject(Subject.hswaw, 'Kubernetes Service Account Signer', 'service-accounts'))
 
-    if modified:
-        logger.info('{}: cert(s) modified, restarting services...'.format(fqdn))
-
-        services = [
-            'kubelet', 'kube-proxy',
-            'kube-apiserver', 'kube-controller-manager', 'kube-scheduler',
-            'etcd'
-        ]
-
-        for s in services:
-            c.run('systemctl stop {}'.format(s))
-        for s in services[::-1]:
-            c.run('systemctl start {}'.format(s))
+    c.run('nixos-rebuild switch')
 
 def usage():
     sys.stderr.write("Usage: {} <nodestrap|admincreds>\n".format(sys.argv[0]))