port-allocator: allocates ports on preconfigured ingress-nginx
Replacement of /core/installer/tcp-udp-transport
Change-Id: I3d116b0f4508b462398f69e980ad55771dc88b7c
diff --git a/core/installer/repoio.go b/core/installer/repoio.go
index ffbdcb0..59d614b 100644
--- a/core/installer/repoio.go
+++ b/core/installer/repoio.go
@@ -1,12 +1,16 @@
package installer
import (
+ "bytes"
+ "encoding/json"
"errors"
"fmt"
"io"
"io/fs"
"io/ioutil"
"net"
+ "net/http"
+ "os"
"path"
"path/filepath"
"sync"
@@ -29,7 +33,7 @@
ReadAppConfig(path string) (AppConfig, error)
ReadKustomization(path string) (*Kustomization, error)
WriteKustomization(path string, kust Kustomization) error
- ReadYaml(path string) (any, error)
+ ReadYaml(path string) (map[string]any, error)
WriteYaml(path string, data any) error
CommitAndPush(message string) error
WriteCommitAndPush(path, contents, message string) error
@@ -163,7 +167,7 @@
return nil
}
-func (r *repoIO) ReadYaml(path string) (any, error) {
+func (r *repoIO) ReadYaml(path string) (map[string]any, error) {
inp, err := r.Reader(path)
if err != nil {
return nil, err
@@ -231,6 +235,8 @@
type Release struct {
Namespace string `json:"namespace"`
+ RepoAddr string `json:"repoAddr"`
+ AppDir string `json:"appDir"`
}
type Derived struct {
@@ -246,6 +252,14 @@
Derived Derived `json:"derived"`
}
+type allocatePortReq struct {
+ Protocol string `json:"protocol"`
+ SourcePort int `json:"sourcePort"`
+ TargetService string `json:"targetService"`
+ TargetPort int `json:"targetPort"`
+}
+
+// TODO(gio): most of this logic should move to AppManager
func (r *repoIO) InstallApp(app App, appRootDir string, values map[string]any, derived Derived) error {
r.l.Lock()
defer r.l.Unlock()
@@ -255,6 +269,37 @@
if !filepath.IsAbs(appRootDir) {
return fmt.Errorf("Expected absolute path: %s", appRootDir)
}
+ derived.Release.RepoAddr = r.repo.Addr.FullAddress()
+ // TODO(gio): maybe client should populate this?
+ derived.Release.AppDir = appRootDir
+ rendered, err := app.Render(derived)
+ if err != nil {
+ return err
+ }
+ for _, p := range rendered.Ports {
+ var buf bytes.Buffer
+ req := allocatePortReq{
+ Protocol: p.Protocol,
+ SourcePort: p.SourcePort,
+ TargetService: p.TargetService,
+ TargetPort: p.TargetPort,
+ }
+ fmt.Printf("%+v\n", req)
+ if err := json.NewEncoder(&buf).Encode(req); err != nil {
+ return err
+ }
+ resp, err := http.Post(p.Allocator, "application/json", &buf)
+ if err != nil {
+ return err
+ }
+ if resp.StatusCode != http.StatusOK {
+ io.Copy(os.Stdout, resp.Body)
+ return fmt.Errorf("Could not allocate port %d, status code: %d", p.SourcePort, resp.StatusCode)
+ }
+ }
+ if err := r.pullWithoutLock(); err != nil {
+ return err
+ }
appRootDir = filepath.Clean(appRootDir)
for p := appRootDir; p != "/"; {
parent, child := filepath.Split(p)
@@ -292,10 +337,6 @@
}
{
appKust := NewKustomization()
- rendered, err := app.Render(derived)
- if err != nil {
- return err
- }
for name, contents := range rendered.Resources {
appKust.AddResources(name)
out, err := r.Writer(path.Join(appRootDir, name))
@@ -417,6 +458,8 @@
ret[k] = v
case KindString:
ret[k] = v
+ case KindInt:
+ ret[k] = v
case KindNetwork:
n, err := findNetwork(networks, v.(string)) // TODO(giolekva): validate
if err != nil {
@@ -462,4 +505,5 @@
IngressClass string `json:"ingressClass,omitempty"`
CertificateIssuer string `json:"certificateIssuer,omitempty"`
Domain string `json:"domain,omitempty"`
+ AllocatePortAddr string `json:"allocatePortAddr,omitempty"`
}