Installer: Make Private network optional
Change-Id: Ic7a2e5250a42dc03de2416b1e2a0d1bbca3f010c
diff --git a/core/installer/app.go b/core/installer/app.go
index d86c9f3..0c9cf6b 100644
--- a/core/installer/app.go
+++ b/core/installer/app.go
@@ -115,9 +115,18 @@
InfraAdminPublicKey []byte `json:"infraAdminPublicKey,omitempty"`
}
+type InfraNetwork struct {
+ Name string `json:"name,omitempty"`
+ IngressClass string `json:"ingressClass,omitempty"`
+ CertificateIssuer string `json:"certificateIssuer,omitempty"`
+ AllocatePortAddr string `json:"allocatePortAddr,omitempty"`
+ ReservePortAddr string `json:"reservePortAddr,omitempty"`
+ DeallocatePortAddr string `json:"deallocatePortAddr,omitempty"`
+}
+
type InfraApp interface {
App
- Render(release Release, infra InfraConfig, values map[string]any, charts map[string]helmv2.HelmChartTemplateSpec) (InfraAppRendered, error)
+ Render(release Release, infra InfraConfig, networks []InfraNetwork, values map[string]any, charts map[string]helmv2.HelmChartTemplateSpec) (InfraAppRendered, error)
}
type EnvNetwork struct {
@@ -492,7 +501,7 @@
return AppTypeInfra
}
-func (a cueInfraApp) Render(release Release, infra InfraConfig, values map[string]any, charts map[string]helmv2.HelmChartTemplateSpec) (InfraAppRendered, error) {
+func (a cueInfraApp) Render(release Release, infra InfraConfig, networks []InfraNetwork, values map[string]any, charts map[string]helmv2.HelmChartTemplateSpec) (InfraAppRendered, error) {
if charts == nil {
charts = make(map[string]helmv2.HelmChartTemplateSpec)
}
@@ -501,6 +510,7 @@
"release": release,
"input": values,
"localCharts": charts,
+ "networks": InfraNetworkMap(networks),
})
if err != nil {
return InfraAppRendered{}, err
@@ -538,3 +548,11 @@
}
return ret
}
+
+func InfraNetworkMap(networks []InfraNetwork) map[string]InfraNetwork {
+ ret := make(map[string]InfraNetwork)
+ for _, n := range networks {
+ ret[strings.ToLower(n.Name)] = n
+ }
+ return ret
+}
diff --git a/core/installer/app_configs/app_base.cue b/core/installer/app_configs/app_base.cue
index 34e0a72..6529054 100644
--- a/core/installer/app_configs/app_base.cue
+++ b/core/installer/app_configs/app_base.cue
@@ -26,16 +26,6 @@
groups: string | *"" // TODO(gio): []string
}
-#Network: {
- name: string
- ingressClass: string
- certificateIssuer: string | *""
- domain: string
- allocatePortAddr: string
- reservePortAddr: string
- deallocatePortAddr: string
-}
-
#Image: {
registry: string | *release.imageRegistry
repository: string
diff --git a/core/installer/app_configs/app_global_env.cue b/core/installer/app_configs/app_global_env.cue
index 9a306f5..f5858e4 100644
--- a/core/installer/app_configs/app_global_env.cue
+++ b/core/installer/app_configs/app_global_env.cue
@@ -11,13 +11,22 @@
network: #EnvNetwork
}
-networks: {}
+#Network: {
+ name: string
+ ingressClass: string
+ certificateIssuer: string | *""
+ domain: string
+ allocatePortAddr: string
+ reservePortAddr: string
+ deallocatePortAddr: string
+}
-// TODO(gio): remove
-ingressPrivate: "\(global.id)-ingress-private"
-ingressPublic: "\(global.pcloudEnvName)-ingress-public"
-issuerPrivate: "\(global.id)-private"
-issuerPublic: "\(global.id)-public"
+#Networks: {
+ public: #Network
+ ...
+}
+
+networks: #Networks
#Ingress: {
auth: #Auth
diff --git a/core/installer/app_configs/app_global_infra.cue b/core/installer/app_configs/app_global_infra.cue
index 578a30b..937d490 100644
--- a/core/installer/app_configs/app_global_infra.cue
+++ b/core/installer/app_configs/app_global_infra.cue
@@ -5,8 +5,20 @@
infraAdminPublicKey: string | *""
}
-// TODO(gio): remove
-ingressPublic: "\(global.pcloudEnvName)-ingress-public"
+#Network: {
+ name: string
+ ingressClass: string
+ certificateIssuer: string | *""
+ allocatePortAddr: string
+ reservePortAddr: string
+ deallocatePortAddr: string
+}
+
+#Networks: {
+ public: #Network
+}
+
+networks: #Networks
ingress: {}
_ingressValidate: {}
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 7274e03..6cf1da1 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -465,6 +465,7 @@
if err := setPortFields(values, portReservations); err != nil {
return ReleaseResources{}, err
}
+ // TODO(gio): env might not have private domain
imageRegistry := fmt.Sprintf("zot.%s", env.PrivateDomain)
if o.FetchContainerImages {
if err := pullContainerImages(instanceId, rendered.ContainerImages, imageRegistry, namespace, m.jc); err != nil {
@@ -612,7 +613,6 @@
return nil
}
-// TODO(gio): deduplicate with cue definition in app.go, this one should be removed.
func (m *AppManager) CreateNetworks(env EnvConfig) ([]Network, error) {
ret := []Network{
{
@@ -624,14 +624,16 @@
ReservePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/reserve", env.InfraName),
DeallocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/remove", env.InfraName),
},
- {
+ }
+ if env.PrivateDomain != "" {
+ ret = append(ret, Network{
Name: "Private",
IngressClass: fmt.Sprintf("%s-ingress-private", env.Id),
Domain: env.PrivateDomain,
AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-private.svc.cluster.local/api/allocate", env.Id),
ReservePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-private.svc.cluster.local/api/reserve", env.Id),
DeallocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-private.svc.cluster.local/api/remove", env.Id),
- },
+ })
}
n, err := m.FindAllAppInstances("network")
if err != nil {
@@ -799,7 +801,8 @@
RepoAddr: m.repoIO.FullAddress(),
AppDir: appDir,
}
- rendered, err := app.Render(release, infra, values, nil)
+ networks := m.CreateNetworks(infra)
+ rendered, err := app.Render(release, infra, networks, values, nil)
if err != nil {
return ReleaseResources{}, err
}
@@ -808,7 +811,7 @@
return ReleaseResources{}, err
}
localCharts := generateLocalCharts(m.lg, charts)
- rendered, err = app.Render(release, infra, values, localCharts)
+ rendered, err = app.Render(release, infra, networks, values, localCharts)
if err != nil {
return ReleaseResources{}, err
}
@@ -831,7 +834,7 @@
if err := m.repoIO.Pull(); err != nil {
return ReleaseResources{}, err
}
- env, err := m.Config()
+ infra, err := m.Config()
if err != nil {
return ReleaseResources{}, err
}
@@ -853,7 +856,8 @@
if err != nil {
return ReleaseResources{}, err
}
- rendered, err := app.Render(config.Release, env, values, renderedCfg.LocalCharts)
+ networks := m.CreateNetworks(infra)
+ rendered, err := app.Render(config.Release, infra, networks, values, renderedCfg.LocalCharts)
if err != nil {
return ReleaseResources{}, err
}
@@ -867,6 +871,19 @@
}, nil
}
+func (m *InfraAppManager) CreateNetworks(infra InfraConfig) []InfraNetwork {
+ return []InfraNetwork{
+ {
+ Name: "Public",
+ IngressClass: fmt.Sprintf("%s-ingress-public", infra.Name),
+ CertificateIssuer: fmt.Sprintf("%s-public", infra.Name),
+ AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/allocate", infra.Name),
+ ReservePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/reserve", infra.Name),
+ DeallocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/remove", infra.Name),
+ },
+ }
+}
+
func pullHelmCharts(hf HelmFetcher, charts HelmCharts, rfs soft.RepoFS, root string) (map[string]string, error) {
ret := make(map[string]string)
for name, chart := range charts.Git {
diff --git a/core/installer/app_test.go b/core/installer/app_test.go
index 5051cc9..53962fe 100644
--- a/core/installer/app_test.go
+++ b/core/installer/app_test.go
@@ -27,6 +27,17 @@
},
}
+ infraNetworks = []InfraNetwork{
+ {
+ Name: "Public",
+ IngressClass: fmt.Sprintf("%s-ingress-public", env.InfraName),
+ CertificateIssuer: fmt.Sprintf("%s-public", env.Id),
+ AllocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/allocate", env.InfraName),
+ ReservePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/reserve", env.InfraName),
+ DeallocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-public.svc.cluster.local/api/remove", env.InfraName),
+ },
+ }
+
networks = []Network{
{
Name: "Public",
@@ -122,6 +133,7 @@
Namespace: "foo",
}
values := map[string]any{
+ "network": "Public",
"authGroups": "foo,bar",
}
rendered, err := a.Render(release, env, networks, values, nil)
@@ -209,7 +221,7 @@
values := map[string]any{
"sshPrivateKey": "private",
}
- rendered, err := a.Render(release, infra, values, nil)
+ rendered, err := a.Render(release, infra, infraNetworks, values, nil)
if err != nil {
t.Fatal(err)
}
@@ -311,7 +323,7 @@
values := map[string]any{
"servers": []EnvDNS{EnvDNS{"v1.dodo.cloud", "10.0.1.2"}},
}
- rendered, err := app.Render(release, infra, values, nil)
+ rendered, err := app.Render(release, infra, infraNetworks, values, nil)
if err != nil {
t.Fatal(err)
}
diff --git a/core/installer/tasks/infra.go b/core/installer/tasks/infra.go
index 6f02fa3..130a89a 100644
--- a/core/installer/tasks/infra.go
+++ b/core/installer/tasks/infra.go
@@ -33,17 +33,22 @@
}
func SetupInfra(env installer.EnvConfig, st *state) Task {
- return newConcurrentParentTask(
- "Setup core services",
- true,
+ tasks := []Task{
SetupNetwork(env, st),
SetupCertificateIssuers(env, st),
SetupAuth(env, st),
SetupGroupMemberships(env, st),
- SetupHeadscale(env, st),
SetupWelcome(env, st),
SetupAppStore(env, st),
SetupLauncher(env, st),
+ }
+ if env.PrivateDomain != "" {
+ tasks = append(tasks, SetupHeadscale(env, st))
+ }
+ return newConcurrentParentTask(
+ "Setup core services",
+ true,
+ tasks...,
)
}
@@ -94,7 +99,7 @@
}
func SetupNetwork(env installer.EnvConfig, st *state) Task {
- t := newLeafTask("Setup private and public networks", func() error {
+ t := newLeafTask("Setup networks", func() error {
{
app, err := installer.FindEnvApp(st.appsRepo, "metallb-ipaddresspool")
if err != nil {
@@ -143,7 +148,7 @@
}
}
}
- {
+ if env.PrivateDomain != "" {
keys, err := installer.NewSSHKeyPair("port-allocator")
if err != nil {
return err
@@ -187,25 +192,31 @@
instanceId := app.Slug()
appDir := fmt.Sprintf("/apps/%s", instanceId)
namespace := fmt.Sprintf("%s%s", env.NamespacePrefix, app.Namespace())
- if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{}); err != nil {
+ if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{
+ "network": "Public",
+ }); err != nil {
return err
}
return nil
})
- priv := newLeafTask(fmt.Sprintf("Private p.%s", env.Domain), func() error {
- app, err := installer.FindEnvApp(st.appsRepo, "certificate-issuer-private")
- if err != nil {
- return err
- }
- instanceId := app.Slug()
- appDir := fmt.Sprintf("/apps/%s", instanceId)
- namespace := fmt.Sprintf("%s%s", env.NamespacePrefix, app.Namespace())
- if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{}); err != nil {
- return err
- }
- return nil
- })
- return newSequentialParentTask("Configure TLS certificate issuers", false, &pub, &priv)
+ tasks := []Task{&pub}
+ if env.PrivateDomain != "" {
+ priv := newLeafTask(fmt.Sprintf("Private p.%s", env.Domain), func() error {
+ app, err := installer.FindEnvApp(st.appsRepo, "certificate-issuer-private")
+ if err != nil {
+ return err
+ }
+ instanceId := app.Slug()
+ appDir := fmt.Sprintf("/apps/%s", instanceId)
+ namespace := fmt.Sprintf("%s%s", env.NamespacePrefix, app.Namespace())
+ if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{}); err != nil {
+ return err
+ }
+ return nil
+ })
+ tasks = append(tasks, &priv)
+ }
+ return newSequentialParentTask("Configure TLS certificate issuers", false, tasks...)
}
func SetupAuth(env installer.EnvConfig, st *state) Task {
@@ -218,6 +229,7 @@
appDir := fmt.Sprintf("/apps/%s", instanceId)
namespace := fmt.Sprintf("%s%s", env.NamespacePrefix, app.Namespace())
if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{
+ "network": "Public",
"subdomain": "test", // TODO(giolekva): make core-auth chart actually use this
}); err != nil {
return err
@@ -241,7 +253,12 @@
instanceId := app.Slug()
appDir := fmt.Sprintf("/apps/%s", instanceId)
namespace := fmt.Sprintf("%s%s", env.NamespacePrefix, app.Namespace())
+ network := "Public"
+ if env.PrivateDomain != "" {
+ network = "Private"
+ }
if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{
+ "network": network,
"authGroups": strings.Join(initGroups, ","),
}); err != nil {
return err
@@ -277,6 +294,7 @@
appDir := fmt.Sprintf("/apps/%s", instanceId)
namespace := fmt.Sprintf("%s%s", env.NamespacePrefix, app.Namespace())
if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{
+ "network": "Public",
"repoAddr": st.ssClient.GetRepoAddress("config"),
"sshPrivateKey": string(keys.RawPrivateKey()),
}); err != nil {
@@ -302,6 +320,7 @@
appDir := fmt.Sprintf("/apps/%s", instanceId)
namespace := fmt.Sprintf("%s%s", env.NamespacePrefix, app.Namespace())
if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{
+ "network": "Public",
"subdomain": "headscale",
"ipSubnet": fmt.Sprintf("%s/24", env.Network.DNS.String()),
}); err != nil {
@@ -338,6 +357,7 @@
appDir := fmt.Sprintf("/apps/%s", instanceId)
namespace := fmt.Sprintf("%s%s", env.NamespacePrefix, app.Namespace())
if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{
+ "network": "Public",
"repoAddr": st.ssClient.GetRepoAddress("config"),
"sshPrivateKey": string(keys.RawPrivateKey()),
}); err != nil {
@@ -373,7 +393,12 @@
instanceId := app.Slug()
appDir := fmt.Sprintf("/apps/%s", instanceId)
namespace := fmt.Sprintf("%s%s", env.NamespacePrefix, app.Namespace())
+ network := "Public"
+ if env.PrivateDomain != "" {
+ network = "Private"
+ }
if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{
+ "network": network,
"repoAddr": st.ssClient.GetRepoAddress("config"),
"sshPrivateKey": string(keys.RawPrivateKey()),
"authGroups": strings.Join(initGroups, ","),
diff --git a/core/installer/values-tmpl/appmanager.cue b/core/installer/values-tmpl/appmanager.cue
index 7ce72e2..fd162f1 100644
--- a/core/installer/values-tmpl/appmanager.cue
+++ b/core/installer/values-tmpl/appmanager.cue
@@ -3,9 +3,10 @@
)
input: {
- repoAddr: string
- sshPrivateKey: string
- authGroups: string
+ network: #Network @name(Network)
+ repoAddr: string @name(Repository Address)
+ sshPrivateKey: string @name(SSH Private Key)
+ authGroups: string @name(Allowed Groups)
}
name: "App Manager"
@@ -15,7 +16,7 @@
_subdomain: "apps"
_httpPortName: "http"
-_domain: "\(_subdomain).\(networks.private.domain)"
+_domain: "\(_subdomain).\(input.network.domain)"
url: "https://\(_domain)"
ingress: {
@@ -24,7 +25,7 @@
enabled: true
groups: input.authGroups
}
- network: networks.private
+ network: input.network
subdomain: _subdomain
service: {
name: "appmanager"
@@ -58,7 +59,7 @@
repoAddr: input.repoAddr
sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
ingress: {
- className: networks.private.ingressClass
+ className: input.network.ingressClass
domain: _domain
certificateIssuer: ""
}
diff --git a/core/installer/values-tmpl/cert-manager.cue b/core/installer/values-tmpl/cert-manager.cue
index 4b6154a..40f39c0 100644
--- a/core/installer/values-tmpl/cert-manager.cue
+++ b/core/installer/values-tmpl/cert-manager.cue
@@ -53,7 +53,7 @@
chart: charts.certManager
dependsOn: [{
name: "ingress-public"
- namespace: ingressPublic
+ namespace: "\(global.pcloudEnvName)-ingress-public"
}]
values: {
fullnameOverride: "\(global.pcloudEnvName)-cert-manager"
diff --git a/core/installer/values-tmpl/certificate-issuer-custom.cue b/core/installer/values-tmpl/certificate-issuer-custom.cue
index 382e8fa..2cc7ef7 100644
--- a/core/installer/values-tmpl/certificate-issuer-custom.cue
+++ b/core/installer/values-tmpl/certificate-issuer-custom.cue
@@ -12,7 +12,7 @@
icon: "<svg xmlns='http://www.w3.org/2000/svg' width='50' height='50' viewBox='0 0 48 48'><g fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='4'><path d='M4 34h8v8H4zM8 6h32v12H8zm16 28V18'/><path d='M8 34v-8h32v8m-4 0h8v8h-8zm-16 0h8v8h-8zm-6-22h2'/></g></svg>"
charts: {
- "certificate-issuer-public": {
+ "certificate-issuer": {
kind: "GitRepository"
address: "https://github.com/giolekva/pcloud.git"
branch: "main"
@@ -21,7 +21,7 @@
}
helm: {
- "certificate-issuer-public": {
+ "certificate-issuer": {
chart: charts["certificate-issuer-public"]
dependsOn: [{
name: "ingress-nginx"
@@ -31,10 +31,9 @@
issuer: {
name: input.name
server: "https://acme-v02.api.letsencrypt.org/directory"
- // server: "https://acme-staging-v02.api.letsencrypt.org/directory"
domain: input.domain
contactEmail: global.contactEmail
- ingressClass: ingressPublic
+ ingressClass: networks.public.ingressClass
}
}
}
diff --git a/core/installer/values-tmpl/certificate-issuer-private.cue b/core/installer/values-tmpl/certificate-issuer-private.cue
index eef76d3..4707fa1 100644
--- a/core/installer/values-tmpl/certificate-issuer-private.cue
+++ b/core/installer/values-tmpl/certificate-issuer-private.cue
@@ -23,9 +23,8 @@
}]
values: {
issuer: {
- name: issuerPrivate
+ name: "\(global.id)-private"
server: "https://acme-v02.api.letsencrypt.org/directory"
- // server: "https://acme-staging-v02.api.letsencrypt.org/directory"
domain: global.privateDomain
contactEmail: global.contactEmail
}
diff --git a/core/installer/values-tmpl/certificate-issuer-public.cue b/core/installer/values-tmpl/certificate-issuer-public.cue
index 35242bf..725c3b2 100644
--- a/core/installer/values-tmpl/certificate-issuer-public.cue
+++ b/core/installer/values-tmpl/certificate-issuer-public.cue
@@ -1,4 +1,6 @@
-input: {}
+input: {
+ network: #Network
+}
images: {}
@@ -23,12 +25,11 @@
}]
values: {
issuer: {
- name: issuerPublic
+ name: input.network.certificateIssuer
server: "https://acme-v02.api.letsencrypt.org/directory"
- // server: "https://acme-staging-v02.api.letsencrypt.org/directory"
- domain: global.domain
+ domain: input.network.domain
contactEmail: global.contactEmail
- ingressClass: ingressPublic
+ ingressClass: input.network.ingressClass
}
}
}
diff --git a/core/installer/values-tmpl/core-auth.cue b/core/installer/values-tmpl/core-auth.cue
index e2f05c4..9f6157a 100644
--- a/core/installer/values-tmpl/core-auth.cue
+++ b/core/installer/values-tmpl/core-auth.cue
@@ -1,4 +1,5 @@
input: {
+ network: #Network
subdomain: string
}
@@ -154,39 +155,24 @@
}
}
ingress: {
- admin: {
- enabled: true
- className: ingressPrivate
- hosts: [{
- host: "kratos.\(global.privateDomain)"
- paths: [{
- path: "/"
- pathType: "Prefix"
- }]
- }]
- tls: [{
- hosts: [
- "kratos.\(global.privateDomain)"
- ]
- }]
- }
+ admin: enabled: false
public: {
enabled: true
- className: ingressPublic
+ className: input.network.ingressClass
annotations: {
"acme.cert-manager.io/http01-edit-in-place": "true"
- "cert-manager.io/cluster-issuer": issuerPublic
+ "cert-manager.io/cluster-issuer": input.network.certificateIssuer
}
hosts: [{
- host: "accounts.\(global.domain)"
+ host: "accounts.\(input.network.domain)"
paths: [{
path: "/"
pathType: "Prefix"
}]
}]
tls: [{
- hosts: ["accounts.\(global.domain)"]
- secretName: "cert-accounts.\(global.domain)"
+ hosts: ["accounts.\(input.network.domain)"]
+ secretName: "cert-accounts.\(input.network.domain)"
}]
}
}
@@ -206,25 +192,26 @@
dsn: "postgres://kratos:kratos@postgres.\(global.namespacePrefix)core-auth.svc:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4"
serve: {
public: {
- base_url: "https://accounts.\(global.domain)"
+ base_url: "https://accounts.\(input.network.domain)"
cors: {
enabled: true
debug: false
allow_credentials: true
allowed_origins: [
- "https://\(global.domain)",
- "https://*.\(global.domain)",
+ "https://\(input.network.domain)",
+ "https://*.\(input.network.domain)",
]
}
}
admin: {
- base_url: "https://kratos.\(global.privateDomain)/"
+ base_url: "https://kratos-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
}
}
selfservice: {
- default_browser_return_url: "https://accounts-ui.\(global.domain)"
+ default_browser_return_url: "https://accounts-ui.\(input.network.domain)"
allowed_return_urls: [
- "https://*.\(global.domain)/",
+ "https://*.\(input.network.domain)/",
+ // TODO(gio): replace with input.network.privateSubdomain
"https://*.\(global.privateDomain)",
]
methods: {
@@ -234,10 +221,10 @@
}
flows: {
error: {
- ui_url: "https://accounts-ui.\(global.domain)/error"
+ ui_url: "https://accounts-ui.\(input.network.domain)/error"
}
settings: {
- ui_url: "https://accounts-ui.\(global.domain)/settings"
+ ui_url: "https://accounts-ui.\(input.network.domain)/settings"
privileged_session_max_age: "15m"
}
recovery: {
@@ -248,27 +235,27 @@
}
logout: {
after: {
- default_browser_return_url: "https://accounts-ui.\(global.domain)/login"
+ default_browser_return_url: "https://accounts-ui.\(input.network.domain)/login"
}
}
login: {
- ui_url: "https://accounts-ui.\(global.domain)/login"
+ ui_url: "https://accounts-ui.\(input.network.domain)/login"
lifespan: "10m"
after: {
password: {
- default_browser_return_url: "https://accounts-ui.\(global.domain)/"
+ default_browser_return_url: "https://accounts-ui.\(input.network.domain)/"
}
}
}
registration: {
lifespan: "10m"
- ui_url: "https://accounts-ui.\(global.domain)/register"
+ ui_url: "https://accounts-ui.\(input.network.domain)/register"
after: {
password: {
hooks: [{
hook: "session"
}]
- default_browser_return_url: "https://accounts-ui.\(global.domain)/"
+ default_browser_return_url: "https://accounts-ui.\(input.network.domain)/"
}
}
}
@@ -282,7 +269,7 @@
cookies: {
path: "/"
same_site: "None"
- domain: global.domain
+ domain: input.network.domain
}
secrets: {
cookie: ["PLEASE-CHANGE-ME-I-AM-VERY-INSECURE"]
@@ -305,7 +292,7 @@
}
courier: {
smtp: {
- connection_uri: "smtps://test-z1VmkYfYPjgdPRgPFgmeZ31esT9rUgS%40\(global.domain):iW%213Kk%5EPPLFrZa%24%21bbpTPN9Wv3b8mvwS6ZJvMLtce%23A2%2A4MotD@mx1.\(global.domain)"
+ connection_uri: "smtps://test-z1VmkYfYPjgdPRgPFgmeZ31esT9rUgS%40\(input.network.domain):iW%213Kk%5EPPLFrZa%24%21bbpTPN9Wv3b8mvwS6ZJvMLtce%23A2%2A4MotD@mx1.\(input.network.domain)"
}
}
}
@@ -336,37 +323,24 @@
}
}
ingress: {
- admin: {
- enabled: true
- className: ingressPrivate
- hosts: [{
- host: "hydra.\(global.privateDomain)"
- paths: [{
- path: "/"
- pathType: "Prefix"
- }]
- }]
- tls: [{
- hosts: ["hydra.\(global.privateDomain)"]
- }]
- }
+ admin: enabled: false
public: {
enabled: true
- className: ingressPublic
+ className: input.network.ingressClass
annotations: {
"acme.cert-manager.io/http01-edit-in-place": "true"
- "cert-manager.io/cluster-issuer": issuerPublic
+ "cert-manager.io/cluster-issuer": input.network.certificateIssuer
}
hosts: [{
- host: "hydra.\(global.domain)"
+ host: "hydra.\(input.network.domain)"
paths: [{
path: "/"
pathType: "Prefix"
}]
}]
tls: [{
- hosts: ["hydra.\(global.domain)"]
- secretName: "cert-hydra.\(global.domain)"
+ hosts: ["hydra.\(input.network.domain)"]
+ secretName: "cert-hydra.\(input.network.domain)"
}]
}
}
@@ -393,15 +367,15 @@
debug: false
allow_credentials: true
allowed_origins: [
- "https://\(global.domain)",
- "https://*.\(global.domain)"
+ "https://\(input.network.domain)",
+ "https://*.\(input.network.domain)"
]
}
}
admin: {
cors: {
allowed_origins: [
- "https://hydra.\(global.privateDomain)"
+ "https://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
]
}
tls: {
@@ -422,12 +396,12 @@
}
urls: {
self: {
- public: "https://hydra.\(global.domain)"
- issuer: "https://hydra.\(global.domain)"
+ public: "https://hydra.\(input.network.domain)"
+ issuer: "https://hydra.\(input.network.domain)"
}
- consent: "https://accounts-ui.\(global.domain)/consent"
- login: "https://accounts-ui.\(global.domain)/login"
- logout: "https://accounts-ui.\(global.domain)/logout"
+ consent: "https://accounts-ui.\(input.network.domain)/consent"
+ login: "https://accounts-ui.\(input.network.domain)/login"
+ logout: "https://accounts-ui.\(input.network.domain)/logout"
}
secrets: {
system: ["youReallyNeedToChangeThis"]
@@ -451,10 +425,9 @@
}
}
ui: {
- certificateIssuer: issuerPublic
- ingressClassName: ingressPublic
- domain: global.domain
- internalDomain: global.privateDomain
+ certificateIssuer: input.network.certificateIssuer
+ ingressClassName: input.network.ingressClass
+ domain: input.network.domain
hydra: "hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
enableRegistration: false
image: {
diff --git a/core/installer/values-tmpl/env-dns.cue b/core/installer/values-tmpl/env-dns.cue
index 99941be..13cc217 100644
--- a/core/installer/values-tmpl/env-dns.cue
+++ b/core/installer/values-tmpl/env-dns.cue
@@ -154,7 +154,7 @@
}
config: "coredns.conf"
db: "records.db"
- zone: global.domain
+ zone: networks.public.domain
publicIP: strings.Join(global.publicIP, ",")
privateIP: global.network.ingress
nameserverIP: strings.Join(global.nameserverIP, ",")
diff --git a/core/installer/values-tmpl/gerrit.cue b/core/installer/values-tmpl/gerrit.cue
index a18cc10..e7925a8 100644
--- a/core/installer/values-tmpl/gerrit.cue
+++ b/core/installer/values-tmpl/gerrit.cue
@@ -157,7 +157,7 @@
userNameToLowerCase = true
userNameCaseInsensitive = true
[plugin "gerrit-oauth-provider-pcloud-oauth"]
- root-url = https://hydra.\(global.domain)
+ root-url = https://hydra.\(networks.public.domain)
client-id = "{{ .client_id }}"
client-secret = "{{ .client_secret }}"
link-to-existing-openid-accounts = true
@@ -182,7 +182,7 @@
timeout = 120 s
[user]
name = Gerrit Code Review
- email = gerrit@\(global.domain)
+ email = gerrit@\(networks.public.domain)
anonymousCoward = Unnamed User
[cache]
directory = cache
diff --git a/core/installer/values-tmpl/headscale.cue b/core/installer/values-tmpl/headscale.cue
index 726acd8..6dd5609 100644
--- a/core/installer/values-tmpl/headscale.cue
+++ b/core/installer/values-tmpl/headscale.cue
@@ -1,4 +1,5 @@
input: {
+ network: #Network
subdomain: string
ipSubnet: string
}
@@ -37,7 +38,7 @@
}
}
-_domain: "\(input.subdomain).\(global.domain)"
+_domain: "\(input.subdomain).\(input.network.domain)"
_oauth2ClientSecretName: "oauth2-client"
helm: {
@@ -71,14 +72,14 @@
pullPolicy: images.headscale.pullPolicy
}
storage: size: "5Gi"
- ingressClassName: ingressPublic
- certificateIssuer: issuerPublic
+ ingressClassName: input.network.ingressClass
+ certificateIssuer: input.network.certificateIssuer
domain: _domain
- publicBaseDomain: global.domain
+ publicBaseDomain: input.network.domain
ipAddressPool: "\(global.id)-headscale"
oauth2: {
secretName: _oauth2ClientSecretName
- issuer: "https://hydra.\(global.domain)"
+ issuer: "https://hydra.\(input.network.domain)"
}
api: {
port: 8585
@@ -108,10 +109,10 @@
contents: "After installing the client application you need to configure it to use https://\(_domain) as a login URL, so you can login to the VPN network with your dodo: account"
children: [{
title: "macOS"
- contents: "[https://headscale.\(global.domain)/apple](https://headscale.\(global.domain)/apple)"
+ contents: "[https://headscale.\(input.network.domain)/apple](https://headscale.\(input.network.domain)/apple)"
}, {
title: "iOS"
- contents: "[https://headscale.\(global.domain)/apple](https://headscale.\(global.domain)/apple)"
+ contents: "[https://headscale.\(input.network.domain)/apple](https://headscale.\(input.network.domain)/apple)"
}, {
title: "Windows"
contents: "[https://tailscale.com/kb/1318/windows-mdm](https://tailscale.com/kb/1318/windows-mdm)"
diff --git a/core/installer/values-tmpl/ingress-public.cue b/core/installer/values-tmpl/ingress-public.cue
index f0827e5..619f15a 100644
--- a/core/installer/values-tmpl/ingress-public.cue
+++ b/core/installer/values-tmpl/ingress-public.cue
@@ -44,7 +44,7 @@
"ingress-public": {
chart: charts.ingressNginx
values: {
- fullnameOverride: ingressPublic
+ fullnameOverride: "\(global.pcloudEnvName)-ingress-public"
controller: {
kind: "DaemonSet"
hostNetwork: true
@@ -52,10 +52,10 @@
service: enabled: false
ingressClassByName: true
ingressClassResource: {
- name: ingressPublic
+ name: networks.public.ingressClass
enabled: true
default: false
- controllerValue: "k8s.io/\(ingressPublic)"
+ controllerValue: "k8s.io/\(networks.public.ingressClass)"
}
config: {
"proxy-body-size": "200M" // TODO(giolekva): configurable
diff --git a/core/installer/values-tmpl/jenkins.cue b/core/installer/values-tmpl/jenkins.cue
index 0202f4e..74f3ebf 100644
--- a/core/installer/values-tmpl/jenkins.cue
+++ b/core/installer/values-tmpl/jenkins.cue
@@ -17,7 +17,7 @@
ingress: {
jenkins: {
auth: enabled: false
- network: networks.private
+ network: input.network
subdomain: input.subdomain
service: {
name: "jenkins"
@@ -108,7 +108,7 @@
oic:
clientId: "${\(_oauth2ClientCredentials)-\(_oauth2ClientId)}"
clientSecret: "${\(_oauth2ClientCredentials)-\(_oauth2ClientSecret)}"
- wellKnownOpenIDConfigurationUrl: "https://hydra.\(global.domain)/.well-known/openid-configuration"
+ wellKnownOpenIDConfigurationUrl: "https://hydra.\(networks.public.domain)/.well-known/openid-configuration"
userNameField: "email"
"""
}
diff --git a/core/installer/values-tmpl/launcher.cue b/core/installer/values-tmpl/launcher.cue
index 12e2246..bbd5f1a 100644
--- a/core/installer/values-tmpl/launcher.cue
+++ b/core/installer/values-tmpl/launcher.cue
@@ -3,12 +3,13 @@
)
input: {
+ network: #Network
repoAddr: string
sshPrivateKey: string
}
_subdomain: "launcher"
-_domain: "\(_subdomain).\(networks.public.domain)"
+_domain: "\(_subdomain).\(input.network.domain)"
name: "Launcher"
namespace: "launcher"
@@ -21,7 +22,7 @@
ingress: {
launcher: {
auth: enabled: true
- network: networks.public
+ network: input.network
subdomain: _subdomain
service: {
name: "launcher"
@@ -60,7 +61,7 @@
portName: _httpPortName
repoAddr: input.repoAddr
sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
- logoutUrl: "https://accounts-ui.\(global.domain)/logout"
+ logoutUrl: "https://accounts-ui.\(networks.public.domain)/logout"
repoAddr: input.repoAddr
sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
}
diff --git a/core/installer/values-tmpl/matrix.cue b/core/installer/values-tmpl/matrix.cue
index 348d190..36971b3 100644
--- a/core/installer/values-tmpl/matrix.cue
+++ b/core/installer/values-tmpl/matrix.cue
@@ -71,11 +71,11 @@
chart: charts.matrix
info: "Installing Synapse server"
values: {
- domain: global.domain
+ domain: input.network.domain
subdomain: input.subdomain
oauth2: {
secretName: "oauth2-client"
- issuer: "https://hydra.\(global.domain)"
+ issuer: "https://hydra.\(input.network.domain)"
}
postgresql: {
host: "postgres"
@@ -84,8 +84,8 @@
user: "matrix"
password: "matrix"
}
- certificateIssuer: issuerPublic
- ingressClassName: ingressPublic
+ certificateIssuer: input.network.certificateIssuer
+ ingressClassName: input.network.ingressClass
configMerge: {
configName: "config-to-merge"
fileName: "to-merge.yaml"
diff --git a/core/installer/values-tmpl/memberships.cue b/core/installer/values-tmpl/memberships.cue
index 9bf9b57..0f2a039 100644
--- a/core/installer/values-tmpl/memberships.cue
+++ b/core/installer/values-tmpl/memberships.cue
@@ -1,9 +1,10 @@
input: {
- authGroups: string
+ network: #Network @name(Network)
+ authGroups: string @name(Allowed Groups)
}
_subdomain: "memberships"
-_domain: "\(_subdomain).\(global.privateDomain)"
+_domain: "\(_subdomain).\(input.network.domain)"
url: "https://\(_domain)"
name: "Memberships"
@@ -20,7 +21,7 @@
enabled: true
groups: input.authGroups
}
- network: networks.private
+ network: input.network
subdomain: _subdomain
service: {
name: "memberships"
diff --git a/core/installer/values-tmpl/open-project.cue b/core/installer/values-tmpl/open-project.cue
index 8c2da74..1badd08 100644
--- a/core/installer/values-tmpl/open-project.cue
+++ b/core/installer/values-tmpl/open-project.cue
@@ -92,7 +92,7 @@
password: "admin"
password_reset: false
name: "admin"
- mail: "op-admin@\(global.domain)"
+ mail: "op-admin@\(networks.public.domain)"
}
}
persistence: {
diff --git a/core/installer/values-tmpl/penpot.cue b/core/installer/values-tmpl/penpot.cue
index cad8227..82caba7 100644
--- a/core/installer/values-tmpl/penpot.cue
+++ b/core/installer/values-tmpl/penpot.cue
@@ -144,7 +144,7 @@
providers: {
oidc: {
enabled: true
- baseURI: "https://hydra.\(global.domain)"
+ baseURI: "https://hydra.\(networks.public.domain)"
clientID: ""
clientSecret: ""
authURI: ""
diff --git a/core/installer/values-tmpl/private-network.cue b/core/installer/values-tmpl/private-network.cue
index fe78f32..0536b50 100644
--- a/core/installer/values-tmpl/private-network.cue
+++ b/core/installer/values-tmpl/private-network.cue
@@ -57,6 +57,8 @@
}
}
+_ingressPrivate: "\(global.id)-ingress-private"
+
helm: {
"ingress-nginx": {
chart: charts["ingress-nginx"]
@@ -67,15 +69,15 @@
enabled: true
type: "LoadBalancer"
annotations: {
- "metallb.universe.tf/address-pool": ingressPrivate
+ "metallb.universe.tf/address-pool": _ingressPrivate
}
}
ingressClassByName: true
ingressClassResource: {
- name: ingressPrivate
+ name: _ingressPrivate
enabled: true
default: false
- controllerValue: "k8s.io/\(ingressPrivate)"
+ controllerValue: "k8s.io/\(_ingressPrivate)"
}
config: {
"proxy-body-size": "200M" // TODO(giolekva): configurable
@@ -85,7 +87,7 @@
"""
}
extraArgs: {
- "default-ssl-certificate": "\(ingressPrivate)/cert-wildcard.\(global.privateDomain)"
+ "default-ssl-certificate": "\(_ingressPrivate)/cert-wildcard.\(global.privateDomain)"
}
admissionWebhooks: {
enabled: false
@@ -104,7 +106,7 @@
values: {
hostname: input.privateNetwork.hostname
apiServer: "http://headscale-api.\(global.namespacePrefix)app-headscale.svc.cluster.local"
- loginServer: "https://headscale.\(global.domain)" // TODO(gio): take headscale subdomain from configuration
+ loginServer: "https://headscale.\(networks.public.domain)" // TODO(gio): take headscale subdomain from configuration
ipSubnet: input.privateNetwork.ipSubnet
username: input.privateNetwork.username // TODO(gio): maybe install headscale-user chart separately?
preAuthKeySecret: "headscale-preauth-key"
diff --git a/core/installer/values-tmpl/welcome.cue b/core/installer/values-tmpl/welcome.cue
index 2abd8b2..55f4e14 100644
--- a/core/installer/values-tmpl/welcome.cue
+++ b/core/installer/values-tmpl/welcome.cue
@@ -3,6 +3,7 @@
)
input: {
+ network: #Network
repoAddr: string
sshPrivateKey: string
}
@@ -35,12 +36,12 @@
repoAddr: input.repoAddr
sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
createAccountAddr: "http://api.\(global.namespacePrefix)core-auth.svc.cluster.local/identities"
- loginAddr: "https://launcher.\(global.domain)"
+ loginAddr: "https://launcher.\(networks.public.domain)"
membershipsInitAddr: "http://memberships-api.\(global.namespacePrefix)core-auth-memberships.svc.cluster.local/api/init"
ingress: {
- className: ingressPublic
- domain: "welcome.\(global.domain)"
- certificateIssuer: issuerPublic
+ className: input.network.ingressClass
+ domain: "welcome.\(input.network.domain)"
+ certificateIssuer: input.network.certificateIssuer
}
clusterRoleName: "\(global.id)-welcome"
image: {
diff --git a/core/installer/welcome/env-manager-tmpl/form.html b/core/installer/welcome/env-manager-tmpl/form.html
index c0f0d4a..297a426 100644
--- a/core/installer/welcome/env-manager-tmpl/form.html
+++ b/core/installer/welcome/env-manager-tmpl/form.html
@@ -11,7 +11,7 @@
<div style="border-width: 1px; border-right-style: solid;">
As part of provisioning new dodo instance you will have to update DNS records at your domain registrar, so that it points to the nameservers running on your newly created dodo. Please first get familiar with your domain registrar documentation, and only then proceed with provisioning.
<label for="accept" style="padding-top: 1rem;">
- <input type="checkbox" name="accept" id="accept" form="create-form" required tabindex="5">
+ <input type="checkbox" name="accept" id="accept" form="create-form" required tabindex="6">
<strong>I understand</strong>
</label>
</div>
@@ -28,6 +28,16 @@
tabindex="1"
/>
</label>
+ <label for="private-network">
+ private network subdomain (optional)
+ <input
+ type="text"
+ id="private-network-subdomain"
+ name="private-network-subdomain"
+ placeholder="configure to create private network"
+ tabindex="2"
+ />
+ </label>
<label for="contact-email">
contact email
<input
@@ -35,7 +45,7 @@
id="contact-email"
name="contact-email"
required
- tabindex="2"
+ tabindex="3"
/>
</label>
<label for="admin-public-key">
@@ -45,7 +55,7 @@
id="admin-public-key"
name="admin-public-key"
required
- tabindex="3"
+ tabindex="4"
/> <!-- TODO(gio): remove-->
</label>
<label for="secret-token">
@@ -54,7 +64,7 @@
id="secret-token"
name="secret-token"
required
- tabindex="4"
+ tabindex="5"
></textarea>
</label>
<button type="submit" tabindex="6">provision</button>
diff --git a/core/installer/welcome/env.go b/core/installer/welcome/env.go
index 949cbe0..4c084cd 100644
--- a/core/installer/welcome/env.go
+++ b/core/installer/welcome/env.go
@@ -239,11 +239,12 @@
}
type createEnvReq struct {
- Name string
- ContactEmail string `json:"contactEmail"`
- Domain string `json:"domain"`
- AdminPublicKey string `json:"adminPublicKey"`
- SecretToken string `json:"secretToken"`
+ Name string
+ ContactEmail string `json:"contactEmail"`
+ Domain string `json:"domain"`
+ PrivateNetworkSubdomain string `json:"privateNetworkSubdomain"`
+ AdminPublicKey string `json:"adminPublicKey"`
+ SecretToken string `json:"secretToken"`
}
func (s *EnvServer) readInvitations() ([]invitation, error) {
@@ -295,6 +296,9 @@
if req.Domain, err = getFormValue(r.PostForm, "domain"); err != nil {
return err
}
+ if req.PrivateNetworkSubdomain, err = getFormValue(r.PostForm, "private-network-subdomain"); err != nil {
+ return err
+ }
if req.ContactEmail, err = getFormValue(r.PostForm, "contact-email"); err != nil {
return err
}
@@ -385,11 +389,15 @@
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
+ privateDomain := ""
+ if req.PrivateNetworkSubdomain != "" {
+ privateDomain = fmt.Sprintf("%s.%s", req.PrivateNetworkSubdomain, req.Domain)
+ }
env := installer.EnvConfig{
Id: req.Name,
InfraName: infra.Name,
Domain: req.Domain,
- PrivateDomain: fmt.Sprintf("p.%s", req.Domain),
+ PrivateDomain: privateDomain,
ContactEmail: req.ContactEmail,
AdminPublicKey: req.AdminPublicKey,
PublicIP: infra.PublicIP,
diff --git a/core/installer/welcome/env_test.go b/core/installer/welcome/env_test.go
index 4acc576..1c18470 100644
--- a/core/installer/welcome/env_test.go
+++ b/core/installer/welcome/env_test.go
@@ -297,11 +297,12 @@
go s.Start()
time.Sleep(1 * time.Second) // Let server start
req := createEnvReq{
- Name: "test",
- ContactEmail: "test@test.t",
- Domain: "test.t",
- AdminPublicKey: "test",
- SecretToken: "test",
+ Name: "test",
+ ContactEmail: "test@test.t",
+ Domain: "test.t",
+ PrivateNetworkSubdomain: "p",
+ AdminPublicKey: "test",
+ SecretToken: "test",
}
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(req); err != nil {