env-manager: dynamically generate cidr for new env (#85)

* env-manager: allocate env cidrs dynamically

* fix: net.IP to netip.Addr conversion

* bootstrapper: generate empty env-cidrs.yaml

* fix: net.IP to netip.Addr conversion for IP pool

* infra: expose provided startIP subnet via tailscale proxy

* headscale: pass private network ip subnet to expose to api service

* dns: make ingress IP configurable

---------

Co-authored-by: Giorgi Lekveishvili <lekva@gl-mbp-m1-max.local>
diff --git a/core/installer/tasks/dns.go b/core/installer/tasks/dns.go
index 02d8fee..0880782 100644
--- a/core/installer/tasks/dns.go
+++ b/core/installer/tasks/dns.go
@@ -14,10 +14,10 @@
 
 type Check func(ch Check) error
 
-func SetupZoneTask(env Env, st *state) Task {
+func SetupZoneTask(env Env, ingressIP net.IP, st *state) Task {
 	return newSequentialParentTask(
 		fmt.Sprintf("Setup DNS zone records for %s", env.Domain),
-		CreateZoneRecords(env.Domain, st.publicIPs, env, st),
+		CreateZoneRecords(env.Domain, st.publicIPs, ingressIP, env, st),
 		WaitToPropagate(env.Domain, st.publicIPs),
 	)
 }
@@ -25,6 +25,7 @@
 func CreateZoneRecords(
 	name string,
 	expected []net.IP,
+	ingressIP net.IP,
 	env Env,
 	st *state,
 ) Task {
@@ -52,7 +53,7 @@
   namespace: {{ .namespace }}
 spec:
   zone: {{ .zone }}
-  privateIP: 10.1.0.1
+  privateIP: {{ .ingressIP }}
   publicIPs:
 {{ range .publicIPs }}
   - {{ .String }}
@@ -85,6 +86,7 @@
 				"zone":      env.Domain,
 				"dnssec":    key,
 				"publicIPs": st.publicIPs,
+				"ingressIP": ingressIP.String(),
 			}); err != nil {
 				return err
 			}