AppManager: Support exposing ports on public networks
Sets up [public ingress -> private ingress -> remote cluster] proxy chain
Change-Id: I6376a006b2692c31f3cb895bbfd6e373182e8824
diff --git a/core/installer/app.go b/core/installer/app.go
index e57fee8..9c658df 100644
--- a/core/installer/app.go
+++ b/core/installer/app.go
@@ -102,8 +102,9 @@
Protocol string `json:"protocol"`
Port int `json:"port"`
Service struct {
- Name string `json:"name"`
- Port int `json:"port"`
+ Name string `json:"name"`
+ Namespace string `json:"namespace,omitempty"`
+ Port int `json:"port"`
} `json:"service"`
}
diff --git a/core/installer/app_configs/app_base.cue b/core/installer/app_configs/app_base.cue
index 7330b1e..8a674ee 100644
--- a/core/installer/app_configs/app_base.cue
+++ b/core/installer/app_configs/app_base.cue
@@ -115,6 +115,7 @@
port: int
service: close({
name: string
+ namespace: string | *""
port: #PortValue
})
protocol: "TCP" | "UDP" | *"TCP"
@@ -518,31 +519,69 @@
}
}
if 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["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).private-network-proxy.devices.\(global.privateDomain)"
+ 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).private-network-proxy.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).private-network-proxy.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)
diff --git a/core/installer/app_configs/dodo_app.cue b/core/installer/app_configs/dodo_app.cue
index 6f7001a..963421e 100644
--- a/core/installer/app_configs/dodo_app.cue
+++ b/core/installer/app_configs/dodo_app.cue
@@ -26,6 +26,9 @@
"port_postgresql_\(v.name)_\(i)": int @role(port)
if input.cluster != _|_ {
"port_postgresql_\(v.name)_\(i)_cluster": int @role(port)
+ if strings.ToLower(e.network) == "public" {
+ "port_postgresql_\(v.name)_\(i)_private": int @role(port)
+ }
}
}
}
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 3285c19..0ec6605 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -216,7 +216,11 @@
for _, p := range ports {
var target string
if p.Cluster == "" {
- target = fmt.Sprintf("%s/%s", ns, p.Service.Name)
+ if p.Service.Namespace == "" {
+ target = fmt.Sprintf("%s/%s", ns, p.Service.Name)
+ } else {
+ target = fmt.Sprintf("%s/%s", p.Service.Namespace, p.Service.Name)
+ }
} else {
target = p.Service.Name
}
@@ -258,10 +262,16 @@
var retErr error
for _, p := range ports {
var buf bytes.Buffer
+ var fullName string
+ if p.Service.Namespace == "" {
+ fullName = fmt.Sprintf("%s/%s", ns, p.Service.Name)
+ } else {
+ fullName = fmt.Sprintf("%s/%s", p.Service.Namespace, p.Service.Name)
+ }
req := removePortReq{
Protocol: p.Protocol,
SourcePort: p.Port,
- TargetService: fmt.Sprintf("%s/%s", ns, p.Service.Name),
+ TargetService: fullName,
TargetPort: p.Service.Port,
}
if err := json.NewEncoder(&buf).Encode(req); err != nil {
diff --git a/core/installer/canvas-app.cue b/core/installer/canvas-app.cue
index 6843277..89546c0 100644
--- a/core/installer/canvas-app.cue
+++ b/core/installer/canvas-app.cue
@@ -28,8 +28,8 @@
"name": "pgg",
"size": "2Gi",
"expose": [{
- "network": "private",
- "subdomain": "pggp"
+ "network": "public",
+ "subdomain": "piopio"
}]
}],
"cluster": "asdc"
diff --git a/core/installer/dodo_app_test.go b/core/installer/dodo_app_test.go
index eaad590..6c4df1f 100644
--- a/core/installer/dodo_app_test.go
+++ b/core/installer/dodo_app_test.go
@@ -213,7 +213,7 @@
t.Log(string(r.Raw))
}
-const exposeRemoteCluster = `
+const exposeRemoteClusterPrivateNetwork = `
{
"cluster": "remote",
"postgresql": [{
@@ -227,9 +227,9 @@
}
`
-func TestExposeRemoteCluster(t *testing.T) {
+func TestExposeRemoteClusterPrivateNetwork(t *testing.T) {
var buf bytes.Buffer
- if _, err := buf.WriteString(exposeRemoteCluster); err != nil {
+ if _, err := buf.WriteString(exposeRemoteClusterPrivateNetwork); err != nil {
t.Fatal(err)
}
clusters := []Cluster{{
@@ -270,3 +270,62 @@
}
t.Log(string(r.Raw))
}
+
+const exposeRemoteClusterPublicNetwork = `
+{
+ "cluster": "remote",
+ "postgresql": [{
+ "name": "db",
+ "size": "1Gi",
+ "expose": [{
+ "network": "Public",
+ "subdomain": "pg"
+ }]
+ }],
+}
+`
+
+func TestExposeRemoteClusterPublicNetwork(t *testing.T) {
+ var buf bytes.Buffer
+ if _, err := buf.WriteString(exposeRemoteClusterPublicNetwork); err != nil {
+ t.Fatal(err)
+ }
+ clusters := []Cluster{{
+ Name: "remote",
+ Kubeconfig: "<KUBECONFIG>",
+ IngressClassName: "<INGRESS_CLASS_NAME>",
+ }}
+ if err := json.NewEncoder(&buf).Encode(struct {
+ Clusters []Cluster `json:"clusters"`
+ }{
+ clusters,
+ }); err != nil {
+ t.Fatal(err)
+ }
+ app, err := NewDodoApp(buf.Bytes())
+ if err != nil {
+ for _, e := range errors.Errors(err) {
+ t.Log(e)
+ }
+ t.Fatal(err)
+ }
+ release := Release{
+ Namespace: "foo",
+ AppInstanceId: "foo-bar",
+ RepoAddr: "ssh://192.168.100.210:22/config",
+ AppDir: "/foo/bar",
+ }
+ keyGen := testKeyGen{}
+ r, err := app.Render(release, env, networks, clusters, map[string]any{
+ "managerAddr": "",
+ "appId": "",
+ "sshPrivateKey": "",
+ "port_postgresql_db_0": 1,
+ "port_postgresql_db_0_cluster": 2,
+ "port_postgresql_db_0_private": 3,
+ }, nil, keyGen)
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Log(string(r.Raw))
+}