AppManager: Reuse cross-cluster port forwarding logic
Services define single open port with optional cluster and
outer layer converts it to cross cluster bindings.
Change-Id: I2f83270d19aaa367789d19a3ffbdf3a2158c1cf8
diff --git a/core/installer/app.go b/core/installer/app.go
index 9c658df..538e2ff 100644
--- a/core/installer/app.go
+++ b/core/installer/app.go
@@ -95,13 +95,11 @@
}
type PortForward struct {
- Cluster string `json:"cluster,omitempty"`
- Allocator string `json:"allocator"`
- ReserveAddr string `json:"reservator"`
- RemoveAddr string `json:"deallocator"`
- Protocol string `json:"protocol"`
- Port int `json:"port"`
- Service struct {
+ Cluster string `json:"clusterName,omitempty"`
+ Network Network `json:"network"`
+ Protocol string `json:"protocol"`
+ Port int `json:"port"`
+ Service struct {
Name string `json:"name"`
Namespace string `json:"namespace,omitempty"`
Port int `json:"port"`
diff --git a/core/installer/app_configs/app_base.cue b/core/installer/app_configs/app_base.cue
index 1d81e62..e64d6d5 100644
--- a/core/installer/app_configs/app_base.cue
+++ b/core/installer/app_configs/app_base.cue
@@ -110,8 +110,9 @@
}
#PortForward: {
+ name: string
network: #Network
- cluster?: string | null
+ clusterName?: string | null
port: int
service: close({
name: string
@@ -360,82 +361,16 @@
_volumeClaimName: "\(name)-mongodb"
_initdbScripts: initdbScripts
- openPort: list.FlattenN([for i, e in expose {
- if cluster == _|_ {
- network: networks[strings.ToLower(e.network)]
- port: input["port_mongodb_\(_name)_\(i)"]
- protocol: "TCP"
- service: {
- name: "mongodb-\(_name)"
- port: 27017
- }
+ openPort: [for i, e in expose {
+ name: "port_mongodb_\(_name)_\(i)"
+ network: networks[strings.ToLower(e.network)]
+ port: input[name]
+ protocol: "TCP"
+ service: {
+ name: "mongodb-\(_name)"
+ port: 27017
}
- if cluster != _|_ {
- if strings.ToLower(e.network) == "private" {
- [{
- network: #Network & {
- name: "cluster_\(cluster.name)"
- ingressClass: "default"
- domain: ""
- allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/allocate"
- reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/reserve"
- deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/remmove"
- }
- port: input["port_mongodb_\(_name)_\(i)_cluster"]
- protocol: "TCP"
- service: {
- name: "mongodb-\(_name)"
- port: 27017
- }
- }, {
- cluster: _cluster.name
- network: networks[strings.ToLower(e.network)]
- port: input["port_mongodb_\(_name)_\(i)"]
- protocol: "TCP"
- service: {
- name: "cluster-\(cluster).devices.\(global.privateDomain)"
- port: input["port_mongodb_\(_name)_\(i)_cluster"]
- }
- }]
- }
- if strings.ToLower(e.network) != "private" {
- [{
- network: #Network & {
- name: "cluster_\(cluster.name)"
- ingressClass: "default"
- domain: ""
- allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/allocate"
- reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/reserve"
- deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/remmove"
- }
- port: input["port_mongodb_\(_name)_\(i)_cluster"]
- protocol: "TCP"
- service: {
- name: "mongodb-\(_name)"
- port: 27017
- }
- }, {
- network: networks.private // TODO(gio): take corresponding private network
- cluster: _cluster.name
- port: input["port_mongodb_\(_name)_\(i)_private"]
- protocol: "TCP"
- service: {
- name: "cluster-\(cluster).devices.\(global.privateDomain)"
- port: input["port_mongodb_\(_name)_\(i)_cluster"]
- }
- }, {
- network: networks[strings.ToLower(e.network)]
- port: input["port_mongodb_\(_name)_\(i)"]
- protocol: "TCP"
- service: {
- name: "\(global.id)-nginx-private-controller"
- namespace: "\(global.namespacePrefix)ingress-private"
- port: input["port_mongodb_\(_name)_\(i)_private"]
- }
- }]
- }
- }
- }], -1)
+ }]
images: {
mongodb: {
@@ -530,7 +465,7 @@
}
openPortMap: {
for k, v in mongodb {
- "mongodb-\(k)": v.openPort
+ "mongodb-\(k)": v.openPortMap
}
...
}
@@ -582,82 +517,16 @@
_volumeClaimName: "\(name)-postgresql"
_name: name
- openPort: list.FlattenN([for i, e in expose {
- if cluster == _|_ {
- network: networks[strings.ToLower(e.network)]
- port: input["port_postgresql_\(_name)_\(i)"]
- protocol: "TCP"
- service: {
- name: "postgres-\(_name)"
- port: 5432
- }
+ openPort: [for i, e in expose {
+ name: "port_postgresql_\(_name)_\(i)"
+ network: networks[strings.ToLower(e.network)]
+ port: input[name]
+ protocol: "TCP"
+ service: {
+ name: "postgres-\(_name)"
+ port: 5432
}
- if cluster != _|_ {
- if strings.ToLower(e.network) == "private" {
- [{
- network: #Network & {
- name: "cluster_\(cluster.name)"
- ingressClass: "default"
- domain: ""
- allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/allocate"
- reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/reserve"
- deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/remmove"
- }
- port: input["port_postgresql_\(_name)_\(i)_cluster"]
- protocol: "TCP"
- service: {
- name: "postgres-\(_name)"
- port: 5432
- }
- }, {
- cluster: _cluster.name
- network: networks[strings.ToLower(e.network)]
- port: input["port_postgresql_\(_name)_\(i)"]
- protocol: "TCP"
- service: {
- name: "cluster-\(cluster).devices.\(global.privateDomain)"
- port: input["port_postgresql_\(_name)_\(i)_cluster"]
- }
- }]
- }
- if strings.ToLower(e.network) != "private" {
- [{
- network: #Network & {
- name: "cluster_\(cluster.name)"
- ingressClass: "default"
- domain: ""
- allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/allocate"
- reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/reserve"
- deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/remmove"
- }
- port: input["port_postgresql_\(_name)_\(i)_cluster"]
- protocol: "TCP"
- service: {
- name: "postgres-\(_name)"
- port: 5432
- }
- }, {
- network: networks.private // TODO(gio): take corresponding private network
- cluster: _cluster.name
- port: input["port_postgresql_\(_name)_\(i)_private"]
- protocol: "TCP"
- service: {
- name: "cluster-\(cluster).devices.\(global.privateDomain)"
- port: input["port_postgresql_\(_name)_\(i)_cluster"]
- }
- }, {
- network: networks[strings.ToLower(e.network)]
- port: input["port_postgresql_\(_name)_\(i)"]
- protocol: "TCP"
- service: {
- name: "\(global.id)-nginx-private-controller"
- namespace: "\(global.namespacePrefix)ingress-private"
- port: input["port_postgresql_\(_name)_\(i)_private"]
- }
- }]
- }
- }
- }], -1)
+ }]
images: {
postgres: {
@@ -812,8 +681,8 @@
}
}
}
- _op1: [for i in _op { i }]
- openPort: list.FlattenN(_op1, 1)
+ openPort: [...#PortForward] | *[]
+ openPort: list.FlattenN([for i in _op { i }], -1)
for _, out in outs {
images: out.images
charts: out.charts
@@ -873,7 +742,75 @@
helm: {...}
openPort: [...#PortForward] | *[]
openPortMap: {
- "_self": openPort
+ "_self": list.FlattenN([for i, e in openPort {
+ if cluster == _|_ {
+ e
+ }
+ if cluster != _|_ {
+ if strings.ToLower(e.network.name) == "private" {
+ [{
+ name: "\(e.name)_cluster"
+ network: #Network & {
+ name: "cluster_\(cluster.name)"
+ ingressClass: "default"
+ domain: ""
+ allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/allocate"
+ reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/reserve"
+ deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/remmove"
+ }
+ port: input[name]
+ protocol: e.protocol
+ service: e.service
+ }, {
+ name: e.name
+ clusterName: _cluster.name
+ network: e.network
+ port: input[e.name]
+ protocol: e.protocol
+ service: {
+ name: "cluster-\(clusterName).devices.\(global.privateDomain)"
+ port: input["\(e.name)_cluster"]
+ }
+ }]
+ }
+ if strings.ToLower(e.network.name) != "private" {
+ [{
+ name: "\(e.name)_cluster"
+ network: #Network & {
+ name: "cluster_\(cluster.name)"
+ ingressClass: "default"
+ domain: ""
+ allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/allocate"
+ reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/reserve"
+ deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/remmove"
+ }
+ port: input[name]
+ protocol: "TCP"
+ service: e.service
+ }, {
+ name: "\(e.name)_private"
+ network: networks.private // TODO(gio): take corresponding private network
+ clusterName: _cluster.name
+ port: input[name]
+ protocol: "TCP"
+ service: {
+ name: "cluster-\(clusterName).devices.\(global.privateDomain)"
+ port: input["\(e.name)_cluster"]
+ }
+ }, {
+ name: e.name
+ network: e.network
+ port: input[name]
+ protocol: "TCP"
+ service: {
+ name: "\(global.id)-nginx-private-controller"
+ namespace: "\(global.namespacePrefix)ingress-private"
+ port: input["\(e.name)_private"]
+ }
+ }]
+ }
+ }
+ }], -1)
...
}
clusterProxy: {...}
@@ -1011,7 +948,7 @@
}
openPortMap: {
for k, v in postgresql {
- "postgresql-\(k)": v.openPort
+ "postgresql-\(k)": v.openPortMap
}
...
}
diff --git a/core/installer/app_configs/dodo_app.cue b/core/installer/app_configs/dodo_app.cue
index 608d629..a22efe6 100644
--- a/core/installer/app_configs/dodo_app.cue
+++ b/core/installer/app_configs/dodo_app.cue
@@ -391,8 +391,9 @@
openPort: list.Concat([
[for i, e in svc.expose if e.port.name != _|_ {
for p in svc.ports if e.port.name == p.name {
+ name: "port_service_app_\(i)"
network: networks[strings.ToLower(e.network)]
- port: input["port_service_app_\(i)"] // TODO(gio): app name
+ port: input[name] // TODO(gio): app name
protocol: "TCP"
service: {
name: "app-app"
@@ -402,8 +403,9 @@
}],
[for i, e in svc.expose if e.port.value != _|_ {
for p in svc.ports if e.port.value == p.value {
+ name: "port_service_app_\(i)"
network: networks[strings.ToLower(e.network)]
- port: input["port_service_app_\(i)"] // TODO(gio): app name
+ port: input[name] // TODO(gio): app name
protocol: "TCP"
service: {
name: "app-app"
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 0ec6605..d95e640 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -278,7 +278,7 @@
retErr = err
continue
}
- resp, err := http.Post(p.RemoveAddr, "application/json", &buf)
+ resp, err := http.Post(p.Network.DeallocatePortAddr, "application/json", &buf)
if err != nil {
retErr = err
continue
@@ -504,10 +504,10 @@
allocators := map[string]string{}
for _, pf := range rendered.Ports {
reservators[portFields[pf.Port]] = reservePortInfo{
- reserveAddr: pf.ReserveAddr,
+ reserveAddr: pf.Network.ReservePortAddr,
RemoteProxy: pf.Cluster != "",
}
- allocators[portFields[pf.Port]] = pf.Allocator
+ allocators[portFields[pf.Port]] = pf.Network.AllocatePortAddr
}
portReservations, err := reservePorts(reservators)
if err != nil {
diff --git a/core/installer/dodo_app_test.go b/core/installer/dodo_app_test.go
index 6c4df1f..25ce4a3 100644
--- a/core/installer/dodo_app_test.go
+++ b/core/installer/dodo_app_test.go
@@ -3,6 +3,7 @@
import (
"bytes"
"encoding/json"
+ "fmt"
"testing"
"cuelang.org/go/cue/errors"
@@ -269,6 +270,7 @@
t.Fatal(err)
}
t.Log(string(r.Raw))
+ t.Log(fmt.Sprintf("%+v", r.Ports))
}
const exposeRemoteClusterPublicNetwork = `
diff --git a/core/installer/values-tmpl/dodo-app.cue b/core/installer/values-tmpl/dodo-app.cue
index 5ad606e..5b0f865 100644
--- a/core/installer/values-tmpl/dodo-app.cue
+++ b/core/installer/values-tmpl/dodo-app.cue
@@ -113,6 +113,7 @@
}
openPort: [{
+ name: "ssh"
network: input.network
port: input.sshPort
service: {
diff --git a/core/installer/values-tmpl/gerrit.cue b/core/installer/values-tmpl/gerrit.cue
index c783817..9742cdb 100644
--- a/core/installer/values-tmpl/gerrit.cue
+++ b/core/installer/values-tmpl/gerrit.cue
@@ -46,6 +46,7 @@
}
openPort: [{
+ name: "ssh"
network: input.network
port: input.sshPort
service: {
diff --git a/core/installer/values-tmpl/soft-serve.cue b/core/installer/values-tmpl/soft-serve.cue
index 23e07bb..dead3db 100644
--- a/core/installer/values-tmpl/soft-serve.cue
+++ b/core/installer/values-tmpl/soft-serve.cue
@@ -69,6 +69,7 @@
}
openPort: [{
+ name: "ssh"
network: input.network
port: input.sshPort
service: {