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/charts/access-secrets/.helmignore b/charts/access-secrets/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/charts/access-secrets/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/access-secrets/Chart.yaml b/charts/access-secrets/Chart.yaml
new file mode 100644
index 0000000..e17b6af
--- /dev/null
+++ b/charts/access-secrets/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: access-secrets
+description: A Helm chart giving service account access to secrets in the same namespace
+type: application
+version: 0.0.1
+appVersion: "0.0.1"
diff --git a/charts/access-secrets/templates/install.yaml b/charts/access-secrets/templates/install.yaml
new file mode 100644
index 0000000..9b57f13
--- /dev/null
+++ b/charts/access-secrets/templates/install.yaml
@@ -0,0 +1,23 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: {{ .Values.serviceAccountName }}-access-secrets
+  namespace: {{ .Release.Namespace }}
+rules:
+- apiGroups: [""]
+  resources: ["secrets"]
+  verbs: ["get", "watch", "list", "patch", "update", "create"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: {{ .Values.serviceAccountName }}-access-secrets
+  namespace: {{ .Release.Namespace }}
+subjects:
+- kind: ServiceAccount
+  name: {{ .Values.serviceAccountName }}
+  namespace: {{ .Release.Namespace }}
+roleRef:
+  kind: Role
+  name: {{ .Values.serviceAccountName }}-access-secrets
+  apiGroup: rbac.authorization.k8s.io
diff --git a/charts/access-secrets/values.yaml b/charts/access-secrets/values.yaml
new file mode 100644
index 0000000..14f425b
--- /dev/null
+++ b/charts/access-secrets/values.yaml
@@ -0,0 +1 @@
+serviceAccountName: default
diff --git a/charts/appmanager/Chart.yaml b/charts/appmanager/Chart.yaml
index e7ff245..c39b82a 100644
--- a/charts/appmanager/Chart.yaml
+++ b/charts/appmanager/Chart.yaml
@@ -2,5 +2,5 @@
 name: welcome
 description: A Helm chart for PCloud App Manager
 type: application
-version: 0.0.2
-appVersion: "0.0.2"
+version: 0.0.3
+appVersion: "0.0.3"
diff --git a/charts/appmanager/templates/install.yaml b/charts/appmanager/templates/install.yaml
index ba50e10..8cfb306 100644
--- a/charts/appmanager/templates/install.yaml
+++ b/charts/appmanager/templates/install.yaml
@@ -91,6 +91,8 @@
         - --repo-addr={{ .Values.repoAddr }}
         - --ssh-key=/pcloud/ssh-key/private
         - --headscale-api-addr={{ .Values.headscaleAPIAddr }}
+        - --dns-api-addr={{ .Values.dnsAPIAddr }}
+        - --cluster-proxy-config-path={{ .Values.clusterProxyConfigPath }}
         - --port=8080
         {{- if .Values.appRepoAddr }}
         - --app-repo-addr={{ .Values.appRepoAddr }}
diff --git a/charts/appmanager/values.yaml b/charts/appmanager/values.yaml
index d570f51..672d2bb 100644
--- a/charts/appmanager/values.yaml
+++ b/charts/appmanager/values.yaml
@@ -12,3 +12,5 @@
 appRepoAddr: ""
 portName: http
 headscaleAPIAddr: ""
+dnsAPIAddr: ""
+clusterProxyConfigPath: ""
diff --git a/charts/ingress/templates/install.yaml b/charts/ingress/templates/install.yaml
index c50a741..edae330 100644
--- a/charts/ingress/templates/install.yaml
+++ b/charts/ingress/templates/install.yaml
@@ -3,8 +3,10 @@
 metadata:
   name: ingress-{{ .Values.domain }}
   namespace: {{ .Release.Namespace }}
-  {{- if or .Values.certificateIssuer .Values.appRoot }}
   annotations:
+    {{- if .Values.annotations }}
+    {{ toYaml .Values.annotations | nindent 4 }}
+    {{- end }}
     {{- if .Values.certificateIssuer }}
     acme.cert-manager.io/http01-edit-in-place: "true"
     cert-manager.io/cluster-issuer: {{ .Values.certificateIssuer }}
@@ -13,7 +15,6 @@
     {{- if .Values.appRoot }}
     nginx.ingress.kubernetes.io/app-root: {{ .Values.appRoot }}
     {{- end }}
-  {{- end }}
 spec:
   ingressClassName: {{ .Values.ingressClassName }}
   {{- if .Values.certificateIssuer }}
diff --git a/charts/ingress/values.yaml b/charts/ingress/values.yaml
index 0640557..20c1eb8 100644
--- a/charts/ingress/values.yaml
+++ b/charts/ingress/values.yaml
@@ -7,3 +7,4 @@
   port:
     number: 80
     name: ""
+annotations: {}
diff --git a/charts/namespace/templates/namespace.yaml b/charts/namespace/templates/namespace.yaml
index 58d5d46..15d3b28 100644
--- a/charts/namespace/templates/namespace.yaml
+++ b/charts/namespace/templates/namespace.yaml
@@ -1,7 +1,7 @@
 apiVersion: v1
 kind: Namespace
 metadata:
-  name: {{ .Values.namespace }}
+  name: {{ .Values.name }}
   labels:
     {{ range .Values.labels }}
     {{ . }}
diff --git a/charts/secret/.helmignore b/charts/secret/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/charts/secret/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/secret/Chart.yaml b/charts/secret/Chart.yaml
new file mode 100644
index 0000000..eee9abd
--- /dev/null
+++ b/charts/secret/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: secret
+description: A Helm chart for secret
+type: application
+version: 0.0.1
+appVersion: "0.0.1"
diff --git a/charts/secret/templates/install.yaml b/charts/secret/templates/install.yaml
new file mode 100644
index 0000000..62eb096
--- /dev/null
+++ b/charts/secret/templates/install.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: Secret
+metadata:
+    name: {{ .Values.name }}
+    {{- if .Values.keep }}
+    helm.sh/resource-policy: keep
+    {{- end }}
+data:
+  {{ .Values.key }}: {{ .Values.value }}
diff --git a/charts/secret/values.yaml b/charts/secret/values.yaml
new file mode 100644
index 0000000..fce03b2
--- /dev/null
+++ b/charts/secret/values.yaml
@@ -0,0 +1,4 @@
+name: secret
+key: key
+value: value
+keep: false
diff --git a/charts/tailscale-proxy/templates/install.yaml b/charts/tailscale-proxy/templates/install.yaml
index 76241da..f85f753 100644
--- a/charts/tailscale-proxy/templates/install.yaml
+++ b/charts/tailscale-proxy/templates/install.yaml
@@ -64,8 +64,10 @@
         #       key: key
         - name: TS_HOSTNAME
           value: {{ .Values.hostname }}
+        {{- if .Values.ipSubnet }}
         - name: TS_ROUTES
           value: {{ .Values.ipSubnet }}
+        {{- end }}
         - name: TS_EXTRA_ARGS
           value: --login-server={{ .Values.loginServer }}
         # volumeMounts: