ClusterManager: Implements support of remote clusters.

After this change users will be able to:
* Create cluster and add/remove servers to it
* Install apps on remote cluster
* Move already installed apps between clusters
* Apps running on server being removed will auto-migrate
  to another server from that same cluster

This is achieved by:
* Installing and running minimal version of dodo on remote cluster
* Ingress-nginx is installed automatically on new clusters
* Next to nginx we run VPN client in the same pod, so that
  default cluster can establish secure communication with it
* Multiple reverse proxies are configured to get to the
  remote cluster service from ingress installed on default cluster.

Next steps:
* Support remote clusters in dodo apps (prototype ready)
* Clean up old cluster when moving app to the new one. Currently
  old cluster keeps running app pods even though no ingress can
  reach it anymore.

Change-Id: Iffc908c93416d4126a8e1c2832eae7b659cb8044
diff --git a/core/dns-api/records_file.go b/core/dns-api/records_file.go
index 6916a5e..a25c342 100644
--- a/core/dns-api/records_file.go
+++ b/core/dns-api/records_file.go
@@ -35,11 +35,8 @@
 func (z *RecordsFile) DeleteTxtRecord(name, value string) {
 	z.lock.Lock()
 	defer z.lock.Unlock()
-	fmt.Printf("%s %s\n", name, value)
 	for i, rr := range z.rrs {
-		fmt.Printf("%+v\n", rr)
 		if txt, ok := rr.(*dns.TXT); ok {
-			fmt.Printf("%+v\n", txt)
 			if txt.Hdr.Name == name && strings.Join(txt.Txt, "") == value {
 				z.rrs = append(z.rrs[:i], z.rrs[i+1:]...)
 			}
@@ -47,6 +44,20 @@
 	}
 }
 
+func (z *RecordsFile) DeleteARecord(name, value string) error {
+	z.lock.Lock()
+	defer z.lock.Unlock()
+	for i, rr := range z.rrs {
+		if a, ok := rr.(*dns.A); ok {
+			if a.Hdr.Name == name && a.A.String() == value {
+				z.rrs = append(z.rrs[:i], z.rrs[i+1:]...)
+				return nil
+			}
+		}
+	}
+	return fmt.Errorf("not found")
+}
+
 // func (z *RecordsFile) DeleteRecordsFor(name string) {
 // 	z.lock.Lock()
 // 	defer z.lock.Unlock()