DodoApp: Support dev virtual machines
Change-Id: Ib7641adb5be477bdde7cd9a06df4b45aa65a1c01
diff --git a/core/auth/memberships/main.go b/core/auth/memberships/main.go
index ba5db7c..e72a163 100644
--- a/core/auth/memberships/main.go
+++ b/core/auth/memberships/main.go
@@ -691,6 +691,8 @@
go func() {
r := mux.NewRouter()
r.HandleFunc("/api/init", s.apiInitHandler)
+ // TODO(gio): change to /api/users/{username}
+ r.HandleFunc("/api/users/{username}/keys", s.apiAddUserKey).Methods(http.MethodPost)
r.HandleFunc("/api/user/{username}", s.apiMemberOfHandler)
r.HandleFunc("/api/users", s.apiGetAllUsers).Methods(http.MethodGet)
r.HandleFunc("/api/users", s.apiCreateUser).Methods(http.MethodPost)
@@ -1153,7 +1155,7 @@
http.Error(w, "SSH key not present", http.StatusBadRequest)
return
}
- if err := s.store.AddSSHKeyForUser(username, sshKey); err != nil {
+ if err := s.store.AddSSHKeyForUser(strings.ToLower(username), sshKey); err != nil {
redirectURL := fmt.Sprintf("/user/%s?errorMessage=%s", loggedInUser, url.QueryEscape(err.Error()))
http.Redirect(w, r, redirectURL, http.StatusFound)
return
@@ -1238,11 +1240,7 @@
}
func (s *Server) apiGetAllUsers(w http.ResponseWriter, r *http.Request) {
- defer s.pingAllSyncAddresses()
- selfAddress := r.FormValue("selfAddress")
- if selfAddress != "" {
- s.addSyncAddress(selfAddress)
- }
+ s.addSyncAddress(r.FormValue("selfAddress"))
var users []User
var err error
groups := r.FormValue("groups")
@@ -1316,23 +1314,58 @@
}
}
+type addUserKeyRequest struct {
+ User string `json:"user"`
+ PublicKey string `json:"publicKey"`
+}
+
+func (s *Server) apiAddUserKey(w http.ResponseWriter, r *http.Request) {
+ var req addUserKeyRequest
+ if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+ http.Error(w, "Invalid request body", http.StatusBadRequest)
+ return
+ }
+ if req.User == "" {
+ http.Error(w, "Username cannot be empty", http.StatusBadRequest)
+ return
+ }
+ if req.PublicKey == "" {
+ http.Error(w, "PublicKey cannot be empty", http.StatusBadRequest)
+ return
+ }
+ if err := s.store.AddSSHKeyForUser(strings.ToLower(req.User), req.PublicKey); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+}
+
+// TODO(gio): enque sync event instead of directly reaching out to clients.
+// This will allow to deduplicate sync events and save resources.
func (s *Server) pingAllSyncAddresses() {
s.mu.Lock()
defer s.mu.Unlock()
for address := range s.syncAddresses {
- resp, err := http.Get(address)
- if err != nil {
- log.Printf("Failed to ping %s: %v", address, err)
- continue
- }
- resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- log.Printf("Ping to %s returned status %d", address, resp.StatusCode)
- }
+ go func(address string) {
+ log.Printf("Pinging %s", address)
+ resp, err := http.Get(address)
+ if err != nil {
+ // TODO(gio): remove sync address after N number of failures.
+ log.Printf("Failed to ping %s: %v", address, err)
+ return
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ log.Printf("Ping to %s returned status %d", address, resp.StatusCode)
+ }
+ }(address)
}
}
func (s *Server) addSyncAddress(address string) {
+ if address == "" {
+ return
+ }
+ fmt.Printf("Adding sync address: %s\n", address)
s.mu.Lock()
defer s.mu.Unlock()
s.syncAddresses[address] = struct{}{}
diff --git a/core/installer/app.go b/core/installer/app.go
index cee8a5f..3a16abe 100644
--- a/core/installer/app.go
+++ b/core/installer/app.go
@@ -346,7 +346,7 @@
return rendered{}, err
}
{
- charts := res.LookupPath(cue.ParsePath("charts"))
+ charts := res.LookupPath(cue.ParsePath("output.charts"))
i, err := charts.Fields()
if err != nil {
return rendered{}, err
@@ -366,7 +366,7 @@
}
}
{
- images := res.LookupPath(cue.ParsePath("images"))
+ images := res.LookupPath(cue.ParsePath("output.images"))
i, err := images.Fields()
if err != nil {
return rendered{}, err
@@ -380,8 +380,8 @@
}
}
{
- output := res.LookupPath(cue.ParsePath("output"))
- i, err := output.Fields()
+ helm := res.LookupPath(cue.ParsePath("output.helm"))
+ i, err := helm.Fields()
if err != nil {
return rendered{}, err
}
diff --git a/core/installer/app_configs/app_base.cue b/core/installer/app_configs/app_base.cue
index 9ca1eec..f058c96 100644
--- a/core/installer/app_configs/app_base.cue
+++ b/core/installer/app_configs/app_base.cue
@@ -1,5 +1,8 @@
import (
- "net"
+ "encoding/base64"
+ "encoding/yaml"
+ "list"
+ "net"
)
name: string | *""
@@ -47,22 +50,6 @@
name: string
}
-volumes: {}
-volumes: {
- for _, p in _postgresql {
- for k, v in p.out.volumes {
- "\(k)": v
- }
- }
-}
-volumes: {
- for key, value in volumes {
- "\(key)": #volume & value & {
- name: key
- }
- }
-}
-
#Chart: #GitRepositoryRef | #HelmRepositoryRef
#GitRepositoryRef: {
@@ -114,56 +101,177 @@
global: #Global
release: #Release
-images: {}
-
-images: {
- for key, value in images {
- "\(key)": #Image & value
- }
- for _, value in _ingressValidate {
- for name, image in value.out.images {
- "\(name)": #Image & image
- }
- }
- for _, value in _postgresql {
- for name, image in value.out.images {
- "\(name)": #Image & image
- }
- }
+#WriteFile: {
+ path: string
+ content: string
+ owner: string
+ permissions: string
}
-charts: {}
-charts: {
- for key, value in charts {
- "\(key)": #Chart & value & {
- name: key
- }
- }
- for _, value in _ingressValidate {
- for name, chart in value.out.charts {
- "\(name)": #Chart & chart & {
- name: name
- }
- }
- }
- for _, value in _postgresql {
- for name, chart in value.out.charts {
- "\(name)": #Chart & chart & {
- name: name
- }
- }
- }
+#CloudInit: {
+ runCmd: [...[...string]] | *[]
+ writeFiles: [...#WriteFile] | *[]
}
-charts: {
- volume: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/volumes"
+
+#VPNDisabled: {
+ enabled: false
+}
+
+#VPNEnabled: {
+ enabled: true
+ loginServer: string
+ authKey: string
+}
+
+#VPN: #VPNEnabled | #VPNDisabled
+
+#VirtualMachine: #WithOut & {
+ name: string
+ username: string
+ domain: string
+ vpn: #VPN | *{ enabled: false }
+ cpuCores: int
+ memory: string
+ sshKnownHosts: [...string] | *[]
+ sshAuthorizedKeys: [...string] | *[]
+ cloudInit: #CloudInit
+
+ _name: name
+ _cpuCores: cpuCores
+ _memory: memory
+
+ _codeServerPort: 9090
+
+ images: {}
+ charts: {
+ virtualMachine: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/virtual-machine"
+ }
+ }
+ charts: {
+ for key, value in charts {
+ "\(key)": value & {
+ name: key
+ }
+ }
+ }
+ helm: {
+ "\(_name)-virtual-machine": {
+ chart: charts.virtualMachine
+ info: "Creating \(_name) virtual machine"
+ annotations: {
+ "dodo.cloud/resource-type": "virtual-machine"
+ "dodo.cloud/resource.virtual-machine.name": _name
+ "dodo.cloud/resource.virtual-machine.user": username
+ "dodo.cloud/resource.virtual-machine.cpu-cores": "\(_cpuCores)"
+ "dodo.cloud/resource.virtual-machine.memory": _memory
+ }
+ values: {
+ name: _name
+ cpuCores: _cpuCores
+ memory: _memory
+ disk: {
+ source: "https://cloud.debian.org/images/cloud/bookworm-backports/latest/debian-12-backports-generic-amd64.qcow2"
+ size: "64Gi"
+ }
+ ports: [22, 8080, _codeServerPort]
+ servicePorts: [{
+ name: "ssh"
+ port: 22
+ targetPort: 22
+ protocol: "TCP"
+ }, {
+ name: "web"
+ port: 80
+ targetPort: 8080
+ protocol: "TCP"
+ }, {
+ name: _codeServerPortName
+ port: _codeServerPort
+ targetPort: _codeServerPort
+ protocol: "TCP"
+ }]
+ cloudInit: {
+ userData: base64.Encode(null, "#cloud-config\n\(yaml.Marshal(_cloudInitUserData))")
+ networkData: base64.Encode(null, yaml.Marshal({
+ version: 2
+ ethernets: {
+ enp1s0: {
+ dhcp4: true
+ }
+ }
+ }))
+ }
+ }
+ _cloudInitUserData: {
+ system_info: {
+ default_user: {
+ name: username
+ home: "/home/\(username)"
+ }
+ }
+ password: "dodo" // TODO(gio): remove if possible
+ chpasswd: {
+ expire: false
+ }
+ hostname: _name
+ ssh_pwauth: true
+ disable_root: false
+ ssh_authorized_keys: list.Concat([[
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOa7FUrmXzdY3no8qNGUk7OPaRcIUi8G7MVbLlff9eB/ lekva@gl-mbp-m1-max.local"
+ ], sshAuthorizedKeys])
+ packages: [
+ "curl",
+ // "emacs",
+ "git",
+ "openssh-client",
+ ]
+ write_files: list.Concat([[{
+ path: "/home/\(username)/.gitconfig"
+ content: """
+ [user]
+ name = \(username)
+ email = \(username)@.\(domain)
+
+ """
+ owner: "\(username):\(username)"
+ permissions: "0644"
+ }], cloudInit.writeFiles])
+ runcmd: list.Concat([[
+ ["sh", "-c", "chown -R \(username):\(username) /home/\(username)"],
+ ["sh", "-c", "ssh-keygen -t ed25519 -f /home/\(username)/.ssh/id_ed25519 -q -N ''"],
+ ["sh", "-c", "chown \(username):\(username) /home/\(username)/.ssh/id_ed25519*"],
+ ["sh", "-c", "chmod 0600 /home/\(username)/.ssh/id_ed25519*"],
+ // TODO(gio): implement post app delete webhook to remove ssh key from memberships
+ // TODO(gio): make memberships-api addr configurable
+ ["sh", "-c", "PUBKEY=$(cat /home/\(username)/.ssh/id_ed25519.pub) && curl --request POST --data \"{\\\"user\\\":\\\"\(username)\\\",\\\"publicKey\\\":\\\"${PUBKEY}\\\"}\" http://memberships-api.\(global.namespacePrefix)core-auth-memberships.svc.cluster.local/api/users/\(username)/keys"],
+ // TODO(gio): this waits for user keys are synced from memberships service back to the dodo-app.
+ // We should inject this key into the dodo-app directly as well.
+ ["sh", "-c", "sleep 20"],
+ if vpn.enabled {
+ ["sh", "-c", "curl -fsSL https://tailscale.com/install.sh | sh"],
+ }
+ if vpn.enabled {
+ // TODO(gio): (maybe) enable tailscale ssh
+ ["sh", "-c", "tailscale up --login-server=\(vpn.loginServer) --auth-key=\(vpn.authKey)"],
+ }
+ ["sh", "-c", "curl -fsSL https://code-server.dev/install.sh | HOME=/home/\(username) sh"],
+ ["sh", "-c", "systemctl enable --now code-server@\(username)"],
+ ["sh", "-c", "sleep 10"],
+ // TODO(gio): (maybe) listen only on tailscale interface
+ ["sh", "-c", "sed -i -e 's/127.0.0.1:8080/0.0.0.0:\(_codeServerPort)/g' /home/\(username)/.config/code-server/config.yaml"],
+ ["sh", "-c", "sed -i -e 's/auth: password/auth: none/g' /home/\(username)/.config/code-server/config.yaml"],
+ ["sh", "-c", "systemctl restart --now code-server@\(username)"],
+ ], cloudInit.runCmd])
+ }
+ }
}
}
-#PostgreSQL: {
+#PostgreSQL: #WithOut & {
name: string
version: "15.3"
initSQL: string | *""
@@ -172,108 +280,84 @@
_size: size
_volumeClaimName: "\(name)-postgresql"
- out: {
- images: {
- postgres: #Image & {
- repository: "library"
- name: "postgres"
- tag: version
- pullPolicy: "IfNotPresent"
+ images: {
+ postgres: {
+ repository: "library"
+ name: "postgres"
+ tag: version
+ pullPolicy: "IfNotPresent"
+ }
+ }
+ charts: {
+ postgres: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/postgresql"
+ }
+ }
+ volumes: {
+ "\(_volumeClaimName)": size: _size
+ }
+ helm: {
+ postgres: {
+ chart: charts.postgres
+ annotations: {
+ "dodo.cloud/resource-type": "postgresql"
+ "dodo.cloud/resource.postgresql.name": name
+ "dodo.cloud/resource.postgresql.version": version
+ "dodo.cloud/resource.postgresql.volume": _volumeClaimName
}
- }
- charts: {
- postgres: #Chart & {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/postgresql"
- }
- }
- volumes: {
- "\(_volumeClaimName)": size: _size
- }
- charts: {
- for key, value in charts {
- "\(key)": #Chart & value & {
- name: key
+ values: {
+ fullnameOverride: "postgres-\(name)"
+ image: {
+ registry: images.postgres.registry
+ repository: images.postgres.imageName
+ tag: images.postgres.tag
+ pullPolicy: images.postgres.pullPolicy
}
- }
- }
- helm: {
- postgres: {
- chart: charts.postgres
- annotations: {
- "dodo.cloud/resource-type": "postgresql"
- "dodo.cloud/resource.postgresql.name": name
- "dodo.cloud/resource.postgresql.version": version
- "dodo.cloud/resource.postgresql.volume": _volumeClaimName
+ auth: {
+ postgresPassword: "postgres"
+ username: "postgres"
+ password: "postgres"
+ database: "postgres"
}
- values: {
- fullnameOverride: "postgres-\(name)"
- image: {
- registry: images.postgres.registry
- repository: images.postgres.imageName
- tag: images.postgres.tag
- pullPolicy: images.postgres.pullPolicy
- }
- auth: {
- postgresPassword: "postgres"
- username: "postgres"
- password: "postgres"
- database: "postgres"
- }
- service: {
- type: "ClusterIP"
- port: 5432
- }
- global: {
- postgresql: {
- auth: {
- postgresPassword: "postgres"
- username: "postgres"
- password: "postgres"
- database: "postgres"
- }
- }
- }
- primary: {
- persistence: existingClaim: _volumeClaimName
- if initSQL != "" {
- initdb: scripts: "init.sql": initSQL
- }
- securityContext: {
- enabled: true
- fsGroup: 0
- }
- containerSecurityContext: {
- enabled: true
- runAsUser: 0
- }
- }
- volumePermissions: securityContext: runAsUser: 0
+ service: {
+ type: "ClusterIP"
+ port: 5432
}
+ global: {
+ postgresql: {
+ auth: {
+ postgresPassword: "postgres"
+ username: "postgres"
+ password: "postgres"
+ database: "postgres"
+ }
+ }
+ }
+ primary: {
+ persistence: existingClaim: _volumeClaimName
+ if initSQL != "" {
+ initdb: scripts: "init.sql": initSQL
+ }
+ securityContext: {
+ enabled: true
+ fsGroup: 0
+ }
+ containerSecurityContext: {
+ enabled: true
+ runAsUser: 0
+ }
+ }
+ volumePermissions: securityContext: runAsUser: 0
}
}
}
}
-_ingressValidate: {}
-
-postgresql: {}
-_postgresql: {
- for key, value in postgresql {
- "\(key)": #PostgreSQL & value & {
- name: key
- }
- }
-}
-
-localCharts: {
- for key, _ in charts {
- "\(key)": {
- }
- }
-}
+localCharts: {}
+_localCharts: localCharts
#ResourceReference: {
name: string
@@ -288,41 +372,6 @@
...
}
-helm: {}
-_helmValidate: {
- for key, value in helm {
- "\(key)": #Helm & value & {
- name: key
- }
- }
- for key, value in volumes {
- "\(key)-volume": #Helm & {
- chart: charts.volume
- info: "Creating disk for \(key)"
- annotations: {
- "dodo.cloud/resource-type": "volume"
- "dodo.cloud/resource.volume.name": value.name
- "dodo.cloud/resource.volume.size": value.size
- }
- values: value
- }
- }
- for key, value in _ingressValidate {
- for ing, ingValue in value.out.helm {
- "\(key)-\(ing)": #Helm & ingValue & {
- name: "\(key)-\(ing)"
- }
- }
- }
- for key, value in _postgresql {
- for post, postValue in value.out.helm {
- "\(key)-\(post)": #Helm & postValue & {
- name: "\(key)-\(post)"
- }
- }
- }
-}
-
#HelmRelease: {
_name: string
_chart: _
@@ -349,14 +398,25 @@
}
output: {
- for name, r in _helmValidate {
- "\(name)": #HelmRelease & {
- _name: name
- _chart: localCharts[r.chart.name]
- _values: r.values
- _dependencies: r.dependsOn
- _info: r.info
- _annotations: r.annotations
+ images: out.images
+ charts: out.charts
+ _lc: _localCharts & {
+ for k, v in out.charts {
+ "\(k)": {
+ ...
+ }
+ }
+ }
+ helm: {
+ for name, r in out.helmR {
+ "\(name)": #HelmRelease & {
+ _name: name
+ _chart: _lc[r.chart.name]
+ _values: r.values
+ _dependencies: r.dependsOn
+ _info: r.info
+ _annotations: r.annotations
+ }
}
}
}
@@ -375,3 +435,138 @@
help: [...#HelpDocument] | *[]
url: string | *""
+
+#WithOut: {
+ images: {...}
+ charts: {...}
+ helm: {...}
+ images: {
+ for key, value in images {
+ "\(key)": #Image & value
+ }
+ }
+ charts: {
+ for k, v in charts {
+ "\(k)": #Chart & v & {
+ name: k
+ }
+ }
+ }
+ helmR: {
+ for key, value in helm {
+ "\(key)": #Helm & value & {
+ name: key
+ }
+ }
+ ...
+ }
+ ...
+}
+
+#WithOut: {
+ charts: {
+ volume: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/volumes"
+ }
+ ...
+ }
+ volumes: {...}
+ volumes: {
+ for k, v in volumes {
+ "\(k)": #volume & v & {
+ name: k
+ }
+ }
+ }
+ helmR: {
+ for key, value in volumes {
+ "\(key)-volume": #Helm & {
+ name: key
+ chart: charts.volume
+ info: "Creating disk for \(key)"
+ annotations: {
+ "dodo.cloud/resource-type": "volume"
+ "dodo.cloud/resource.volume.name": value.name
+ "dodo.cloud/resource.volume.size": value.size
+ }
+ values: value
+ }
+ }
+ }
+}
+
+#WithOut: {
+ postgresql: {...}
+ postgresql: {
+ for k, v in postgresql {
+ "\(k)": #PostgreSQL & v
+ }
+ ...
+ }
+ images: {
+ for k, v in postgresql {
+ for x, y in v.images {
+ "\(x)": y
+ }
+ }
+ }
+ charts: {
+ for k, v in postgresql {
+ for x, y in v.charts {
+ "\(x)": y
+ }
+ }
+ }
+ helmR: {
+ for k, v in postgresql {
+ for x, y in v.helmR {
+ "\(x)": y
+ }
+ }
+ ...
+ }
+ ...
+}
+
+#WithOut: {
+ vm: {...}
+ _vm: {...}
+ _vm: {
+ for k, v in vm if len(v) > 0 {
+ "\(k)": #VirtualMachine & v & {
+ name: k
+ }
+ }
+ }
+ images: {
+ for k, v in _vm {
+ for x, y in v.images {
+ "\(x)": y
+ }
+ }
+ }
+ charts: {
+ for k, v in _vm {
+ for x, y in v.charts {
+ "\(x)": y
+ }
+ }
+ }
+ helmR: {
+ for k, v in _vm {
+ for x, y in v.helmR {
+ "\(x)": y
+ }
+ }
+ ...
+ }
+ ...
+}
+
+out: #WithOut
+out: {}
+
+_codeServerPortName: "code-server"
diff --git a/core/installer/app_configs/app_global_env.cue b/core/installer/app_configs/app_global_env.cue
index 1681a1b..e8c8f57 100644
--- a/core/installer/app_configs/app_global_env.cue
+++ b/core/installer/app_configs/app_global_env.cue
@@ -27,7 +27,8 @@
networks: #Networks
-#Ingress: {
+#Ingress: #WithOut & {
+ name: string
auth: #Auth
network: #Network
subdomain: string
@@ -36,93 +37,88 @@
name: string
port: close({ name: string }) | close({ number: int & > 0 })
})
+ g?: #Global
_domain: "\(subdomain).\(network.domain)"
_appRoot: appRoot
+ _authProxyName: "\(name)-auth-proxy"
_authProxyHTTPPortName: "http"
- out: {
- images: {
- authProxy: #Image & {
- repository: "giolekva"
- name: "auth-proxy"
- tag: "latest"
- pullPolicy: "Always"
- }
+ images: {
+ authProxy: {
+ repository: "giolekva"
+ name: "auth-proxy"
+ tag: "latest"
+ pullPolicy: "Always"
}
- charts: {
- ingress: #Chart & {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/ingress"
- }
- authProxy: #Chart & {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/auth-proxy"
- }
+ }
+ charts: {
+ ingress: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/ingress"
}
- charts: {
- for key, value in charts {
- "\(key)": #Chart & value & {
- name: key
- }
- }
+ authProxy: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/auth-proxy"
}
- helm: {
- if auth.enabled {
- "auth-proxy": {
- chart: charts.authProxy
- info: "Installing authentication proxy"
- values: {
- image: {
- repository: images.authProxy.fullName
- tag: images.authProxy.tag
- pullPolicy: images.authProxy.pullPolicy
- }
- upstream: "\(service.name).\(release.namespace).svc.cluster.local"
- whoAmIAddr: "https://accounts.\(global.domain)/sessions/whoami"
- loginAddr: "https://accounts-ui.\(global.domain)/login"
- membershipAddr: "http://memberships-api.\(global.id)-core-auth-memberships.svc.cluster.local/api/user"
- if global.privateDomain == "" {
- membershipPublicAddr: "https://memberships.\(global.domain)"
- }
- if global.privateDomain != "" {
- membershipPublicAddr: "https://memberships.\(global.privateDomain)"
- }
- groups: auth.groups
- portName: _authProxyHTTPPortName
- }
- }
- }
- "\(_domain)": {
- chart: charts.ingress
- _service: service
- info: "Generating TLS certificate for https://\(_domain)"
- annotations: {
- "dodo.cloud/resource-type": "ingress"
- "dodo.cloud/resource.ingress.host": "https://\(_domain)"
- }
+ }
+ helm: {
+ if auth.enabled {
+ "\(name)-auth-proxy": {
+ chart: charts.authProxy
+ info: "Installing authentication proxy"
+ _name: name
values: {
- domain: _domain
- appRoot: _appRoot
- ingressClassName: network.ingressClass
- certificateIssuer: network.certificateIssuer
- service: {
- if auth.enabled {
- name: "auth-proxy"
- port: name: _authProxyHTTPPortName
+ name: _authProxyName
+ image: {
+ repository: images.authProxy.fullName
+ tag: images.authProxy.tag
+ pullPolicy: images.authProxy.pullPolicy
+ }
+ upstream: "\(service.name).\(release.namespace).svc.cluster.local"
+ whoAmIAddr: "https://accounts.\(g.domain)/sessions/whoami"
+ loginAddr: "https://accounts-ui.\(g.domain)/login"
+ membershipAddr: "http://memberships-api.\(g.namespacePrefix)core-auth-memberships.svc.cluster.local/api/user"
+ if g.privateDomain == "" {
+ membershipPublicAddr: "https://memberships.\(g.domain)"
+ }
+ if g.privateDomain != "" {
+ membershipPublicAddr: "https://memberships.\(g.privateDomain)"
+ }
+ groups: auth.groups
+ portName: _authProxyHTTPPortName
+ }
+ }
+ }
+ "\(name)-ingress": {
+ chart: charts.ingress
+ _service: service
+ info: "Generating TLS certificate for https://\(_domain)"
+ annotations: {
+ "dodo.cloud/resource-type": "ingress"
+ "dodo.cloud/resource.ingress.host": "https://\(_domain)"
+ }
+ values: {
+ domain: _domain
+ appRoot: _appRoot
+ ingressClassName: network.ingressClass
+ certificateIssuer: network.certificateIssuer
+ service: {
+ if auth.enabled {
+ name: _authProxyName
+ port: name: _authProxyHTTPPortName
+ }
+ if !auth.enabled {
+ name: _service.name
+ if _service.port.name != _|_ {
+ port: name: _service.port.name
}
- if !auth.enabled {
- name: _service.name
- if _service.port.name != _|_ {
- port: name: _service.port.name
- }
- if _service.port.number != _|_ {
- port: number: _service.port.number
- }
+ if _service.port.number != _|_ {
+ port: number: _service.port.number
}
}
}
@@ -131,9 +127,38 @@
}
}
-ingress: {}
-_ingressValidate: {
- for key, value in ingress {
- "\(key)": #Ingress & value
+#WithOut: {
+ ingress: {...}
+ ingress: {
+ for k, v in ingress {
+ "\(k)": #Ingress & v & {
+ name: k
+ g: global
+ }
+ }
+ ...
}
+ images: {
+ for k, v in ingress {
+ for x, y in v.images {
+ "\(x)": y
+ }
+ }
+ }
+ charts: {
+ for k, v in ingress {
+ for x, y in v.charts {
+ "\(x)": y
+ }
+ }
+ }
+ helmR: {
+ for k, v in ingress {
+ for x, y in v.helmR {
+ "\(x)": y
+ }
+ }
+ ...
+ }
+ ...
}
diff --git a/core/installer/app_configs/dodo_app.cue b/core/installer/app_configs/dodo_app.cue
index a6fc803..84f236b 100644
--- a/core/installer/app_configs/dodo_app.cue
+++ b/core/installer/app_configs/dodo_app.cue
@@ -1,14 +1,56 @@
import (
"encoding/base64"
"encoding/json"
+ "list"
"strings"
)
input: {
repoAddr: string
+ repoPublicAddr: string
managerAddr: string
appId: string
+ branch: string
sshPrivateKey: string
+ // TODO(gio): this should not be necessary as app.dev.username is autogenerated
+ username?: string
+}
+
+_devVM: {}
+
+if app.dev.enabled {
+ input: {
+ username?: string | *app.dev.username
+ vpnAuthKey: string @role(VPNAuthKey) @usernameField(username)
+ }
+
+ _devVM: {
+ username: app.dev.username
+ domain: global.domain
+ vpn: {
+ enabled: true
+ loginServer: "https://headscale.\(global.domain)"
+ authKey: input.vpnAuthKey
+ }
+ cpuCores: 1
+ memory: "1Gi"
+ cloudInit: {
+ runCmd: list.Concat([[
+ ["sh", "-c", "chown \(username):\(username) /home/\(username)/.cache"],
+ ["sh", "-c", "GIT_SSH_COMMAND='ssh -i /home/\(username)/.ssh/id_ed25519 -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new' git clone --branch \(input.branch) \(input.repoPublicAddr)/\(input.appId) /home/\(username)/code"],
+ ["sh", "-c", "chown -R \(username):\(username) /home/\(username)/code"],
+ ["sh", "-c", "chown \(username):\(username) /home/\(username)/.gitconfig"],
+ ], app.vm.cloudInit.runCmd])
+ }
+ }
+}
+
+_vmName: "\(input.appId)-\(input.branch)"
+
+out: {
+ vm: {
+ "\(_vmName)": _devVM
+ }
}
#AppIngress: {
@@ -51,12 +93,39 @@
env: [...string] | *[]
}
+#DevDisabled: {
+ enabled: false
+}
+
+#DevEnabled: {
+ enabled: true
+ username: string
+}
+
+#Dev: #DevEnabled | #DevDisabled
+
+#VMCustomization: {
+ cloudInit: #CloudInit
+}
+
+#AppTmpl: {
+ type: string
+ ingress: #AppIngress
+ volumes: #Volumes
+ postgresql: #PostgreSQLs
+ rootDir: string
+ runConfiguration: [...#Command]
+ dev: #Dev | *{ enabled: false }
+ vm: #VMCustomization
+ ...
+}
+
// Go app
_goVer1220: "golang:1.22.0"
_goVer1200: "golang:1.20.0"
-#GoAppTmpl: {
+#GoAppTmpl: #AppTmpl & {
type: _goVer1220 | _goVer1200
run: string | *"main.go"
ingress: #AppIngress
@@ -73,7 +142,6 @@
args: ["build", "-o", ".app", run]
}, {
bin: ".app",
- args: [],
env: [
for k, v in volumes {
"DODO_VOLUME_\(strings.ToUpper(k))=/dodo-volume/\(v.name)"
@@ -96,6 +164,12 @@
#GoApp1200: #GoAppTmpl & {
type: _goVer1200
+ vm: cloudInit: runCmd: [
+ ["sh", "-c", "wget https://go.dev/dl/go1.20.linux-amd64.tar.gz -O /tmp/go.tar.gz"],
+ ["sh", "-c", "rm -rf /usr/local/go && tar -C /usr/local -xzf /tmp/go.tar.gz"],
+ ["sh", "-c", "echo \"export PATH=$PATH:/usr/local/go/bin\\n\" > /etc/environment"],
+ ["sh", "-c", "rm /tmp/go.tar.gz"],
+ ]
}
#GoApp1220: #GoAppTmpl & {
@@ -108,7 +182,7 @@
_hugoLatest: "hugo:latest"
-#HugoAppTmpl: {
+#HugoAppTmpl: #AppTmpl & {
type: _hugoLatest
ingress: #AppIngress
volumes: {}
@@ -118,7 +192,6 @@
runConfiguration: [{
bin: "/usr/bin/hugo",
- args: []
}, {
bin: "/usr/bin/hugo",
args: [
@@ -136,7 +209,7 @@
// PHP app
-#PHPAppTmpl: {
+#PHPAppTmpl: #AppTmpl & {
type: "php:8.2-apache"
ingress: #AppIngress
volumes: {}
@@ -160,65 +233,91 @@
app: #App
-// output
-
_app: app
-ingress: {
- app: {
- network: networks[strings.ToLower(_app.ingress.network)]
- subdomain: _app.ingress.subdomain
- auth: _app.ingress.auth
- service: {
- name: "app-app"
- port: name: "app"
+
+if !_app.dev.enabled {
+ {
+ out: {
+ ingress: {
+ app: {
+ network: networks[strings.ToLower(_app.ingress.network)]
+ subdomain: _app.ingress.subdomain
+ auth: _app.ingress.auth
+ service: {
+ name: "app-app"
+ port: name: "app"
+ }
+ }
+ }
+ images: {
+ app: {
+ repository: "giolekva"
+ name: "app-runner"
+ tag: strings.Replace(_app.type, ":", "-", -1)
+ pullPolicy: "Always"
+ }
+ }
+ charts: {
+ app: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/app-runner"
+ }
+ }
+ helm: {
+ app: {
+ chart: charts.app
+ values: {
+ image: {
+ repository: images.app.fullName
+ tag: images.app.tag
+ pullPolicy: images.app.pullPolicy
+ }
+ runtimeClassName: "untrusted-external" // TODO(gio): make this part of the infra config
+ appPort: _app.port
+ appDir: _app.rootDir
+ appId: input.appId
+ repoAddr: input.repoAddr
+ sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
+ runCfg: base64.Encode(null, json.Marshal(_app.runConfiguration))
+ managerAddr: input.managerAddr
+ volumes: [
+ for key, value in _app.volumes {
+ name: value.name
+ mountPath: "/dodo-volume/\(key)"
+ }
+ ]
+ }
+ }
}
}
+ }
}
-images: {
- app: {
- repository: "giolekva"
- name: "app-runner"
- tag: strings.Replace(_app.type, ":", "-", -1)
- pullPolicy: "Always"
- }
-}
-
-charts: {
- app: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/app-runner"
- }
-}
-
-volumes: app.volumes
-postgresql: app.postgresql
-
-helm: {
- app: {
- chart: charts.app
- values: {
- image: {
- repository: images.app.fullName
- tag: images.app.tag
- pullPolicy: images.app.pullPolicy
- }
- runtimeClassName: "untrusted-external" // TODO(gio): make this part of the infra config
- appPort: _app.port
- appDir: _app.rootDir
- appId: input.appId
- repoAddr: input.repoAddr
- sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
- runCfg: base64.Encode(null, json.Marshal(_app.runConfiguration))
- managerAddr: input.managerAddr
- volumes: [
- for key, value in _app.volumes {
- name: value.name
- mountPath: "/dodo-volume/\(key)"
+if _app.dev.enabled {
+ {
+ out: {
+ ingress: {
+ app: {
+ network: networks[strings.ToLower(_app.ingress.network)]
+ subdomain: _app.ingress.subdomain
+ auth: _app.ingress.auth
+ service: {
+ name: _vmName
+ port: name: "web"
+ }
}
- ]
+ code: {
+ network: networks[strings.ToLower(_app.ingress.network)]
+ subdomain: "code-\(_app.ingress.subdomain)"
+ auth: enabled: false
+ service: {
+ name: _vmName
+ port: name: _codeServerPortName
+ }
+ }
+ }
}
}
}
diff --git a/core/installer/app_configs/testapp.cue b/core/installer/app_configs/testapp.cue
deleted file mode 100644
index 7ab6829..0000000
--- a/core/installer/app_configs/testapp.cue
+++ /dev/null
@@ -1,22 +0,0 @@
-app: {
- type: "golang:1.22.0"
- run: "main.go"
- ingress: {
- network: "private"
- subdomain: "testapp"
- auth: enabled: false
- }
- volumes: {
- data: {
- size: "1Gi"
- }
- }
- postgresql: {
- foo: {
- size: "2Gi"
- }
- }
-}
-
-// do create app --type=go[1.22.0] [--run-cmd=(*default main.go)]
-// do create ingress --subdomain=testapp [--network=public (*default private)] [--auth] [--auth-groups="admin" (*default empty)] TODO(gio): port
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 3157a45..013c05d 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -76,7 +76,7 @@
}
}
-func (m *AppManager) FindAllInstances() ([]AppInstanceConfig, error) {
+func (m *AppManager) GetAllInstances() ([]AppInstanceConfig, error) {
m.repoIO.Pull()
kust, err := soft.ReadKustomization(m.repoIO, filepath.Join(m.appDirRoot, "kustomization.yaml"))
if err != nil {
@@ -94,7 +94,7 @@
return ret, nil
}
-func (m *AppManager) FindAllAppInstances(name string) ([]AppInstanceConfig, error) {
+func (m *AppManager) GetAllAppInstances(name string) ([]AppInstanceConfig, error) {
kust, err := soft.ReadKustomization(m.repoIO, filepath.Join(m.appDirRoot, "kustomization.yaml"))
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
@@ -117,22 +117,30 @@
return ret, nil
}
-func (m *AppManager) FindInstance(id string) (*AppInstanceConfig, error) {
- kust, err := soft.ReadKustomization(m.repoIO, filepath.Join(m.appDirRoot, "kustomization.yaml"))
+func (m *AppManager) GetInstance(id string) (*AppInstanceConfig, error) {
+ appDir := filepath.Clean(filepath.Join(m.appDirRoot, id))
+ cfgPath := filepath.Join(appDir, "config.json")
+ // kust, err := soft.ReadKustomization(m.repoIO, filepath.Join(m.appDirRoot, "kustomization.yaml"))
+ // if err != nil {
+ // return nil, err
+ // }
+ // for _, app := range kust.Resources {
+ // if app == id {
+ // cfg, err := m.appConfig(filepath.Join(m.appDirRoot, app, "config.json"))
+ cfg, err := m.appConfig(cfgPath)
if err != nil {
return nil, err
}
- for _, app := range kust.Resources {
- if app == id {
- cfg, err := m.appConfig(filepath.Join(m.appDirRoot, app, "config.json"))
- if err != nil {
- return nil, err
- }
- cfg.Id = id
- return &cfg, nil
- }
- }
- return nil, ErrorNotFound
+ cfg.Id = id
+ return &cfg, err
+ // if err != nil {
+ // return nil, err
+ // }
+ // cfg.Id = id
+ // return &cfg, nil
+ // }
+ // }
+ // return nil, ErrorNotFound
}
func GetCueAppData(fs soft.RepoFS, dir string) (CueAppData, error) {
@@ -653,7 +661,7 @@
DeallocatePortAddr: fmt.Sprintf("http://port-allocator.%s-ingress-private.svc.cluster.local/api/remove", env.Id),
})
}
- n, err := m.FindAllAppInstances("network")
+ n, err := m.GetAllAppInstances("network")
if err != nil {
return nil, err
}
diff --git a/core/installer/app_test.go b/core/installer/app_test.go
index f0f0e64..2987c80 100644
--- a/core/installer/app_test.go
+++ b/core/installer/app_test.go
@@ -63,7 +63,7 @@
func TestAuthProxyEnabled(t *testing.T) {
r := NewInMemoryAppRepository(CreateAllApps())
- for _, app := range []string{"rpuppy", "pi-hole", "url-shortener"} {
+ for _, app := range []string{"rpuppy"} {
a, err := FindEnvApp(r, app)
if err != nil {
t.Fatal(err)
@@ -94,7 +94,7 @@
func TestAuthProxyDisabled(t *testing.T) {
r := NewInMemoryAppRepository(CreateAllApps())
- for _, app := range []string{"rpuppy", "pi-hole", "url-shortener"} {
+ for _, app := range []string{"rpuppy"} {
a, err := FindEnvApp(r, app)
if err != nil {
t.Fatal(err)
@@ -337,11 +337,37 @@
}
}
-//go:embed app_configs/testapp.cue
-var testAppCue []byte
+var dodoAppDevDisabledCue = `
+app: {
+ type: "golang:1.22.0"
+ run: "main.go"
+ ingress: {
+ network: "private"
+ subdomain: "testapp"
+ auth: enabled: false
+ }
+ dev: {
+ enabled: false
+ }
+}`
-func TestPCloudApp(t *testing.T) {
- app, err := NewDodoApp(testAppCue)
+var dodoAppDevEnabledCue = `
+app: {
+ type: "golang:1.22.0"
+ run: "main.go"
+ ingress: {
+ network: "private"
+ subdomain: "testapp"
+ auth: enabled: false
+ }
+ dev: {
+ enabled: true
+ username: "gio"
+ }
+}`
+
+func TestDodoAppDevDisabled(t *testing.T) {
+ app, err := NewDodoApp([]byte(dodoAppDevDisabledCue))
if err != nil {
for _, e := range errors.Errors(err) {
t.Log(e)
@@ -355,15 +381,60 @@
RepoAddr: "ssh://192.168.100.210:22/config",
AppDir: "/foo/bar",
}
- _, err = app.Render(release, env, networks, map[string]any{
- "repoAddr": "",
- "managerAddr": "",
- "appId": "",
- "sshPrivateKey": "",
- }, nil, nil)
+ keyGen := testKeyGen{}
+ r, err := app.Render(release, env, networks, map[string]any{
+ "repoAddr": "",
+ "repoPublicAddr": "",
+ "managerAddr": "",
+ "appId": "",
+ "branch": "",
+ "sshPrivateKey": "",
+ }, nil, keyGen)
if err != nil {
+ for _, e := range errors.Errors(err) {
+ for _, f := range errors.Errors(e) {
+ for _, g := range errors.Errors(f) {
+ t.Log(g)
+ }
+ }
+ }
t.Fatal(err)
}
+ t.Log(string(r.Raw))
+}
+
+func TestDodoAppDevEnabled(t *testing.T) {
+ app, err := NewDodoApp([]byte(dodoAppDevEnabledCue))
+ 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, map[string]any{
+ "repoAddr": "",
+ "repoPublicAddr": "",
+ "managerAddr": "",
+ "appId": "",
+ "branch": "",
+ "sshPrivateKey": "",
+ "username": "",
+ }, nil, keyGen)
+ if err != nil {
+ for _, e := range errors.Errors(err) {
+ t.Log(e)
+ }
+ t.Fatal(err)
+ }
+ t.Log(string(r.Raw))
}
func TestDodoAppInstance(t *testing.T) {
@@ -380,8 +451,11 @@
}
values := map[string]any{
"repoAddr": "",
+ "repoPublicAddr": "",
"repoHost": "",
+ "branch": "",
"gitRepoPublicKey": "",
+ "username": "",
}
rendered, err := a.Render(release, env, networks, values, nil, nil)
if err != nil {
diff --git a/core/installer/cmd/rewrite.go b/core/installer/cmd/rewrite.go
index 0562c0e..3e2961b 100644
--- a/core/installer/cmd/rewrite.go
+++ b/core/installer/cmd/rewrite.go
@@ -75,7 +75,7 @@
if err != nil {
return err
}
- all, err := mgr.FindAllInstances()
+ all, err := mgr.GetAllInstances()
if err != nil {
return err
}
diff --git a/core/installer/derived.go b/core/installer/derived.go
index aabda98..508cd3e 100644
--- a/core/installer/derived.go
+++ b/core/installer/derived.go
@@ -90,10 +90,17 @@
}
}
if def.Kind() == KindVPNAuthKey {
- usernameField := def.Meta()["usernameField"]
- // TODO(gio): Improve getField
- username := getField(root, usernameField)
- authKey, err := vpnKeyGen.Generate(username.(string))
+ var username string
+ if v, ok := def.Meta()["username"]; ok {
+ username = v
+ } else if v, ok := def.Meta()["usernameField"]; ok {
+ // TODO(gio): Improve getField
+ username, ok = getField(root, v).(string)
+ if !ok {
+ return nil, fmt.Errorf("could not resolve username: %+v %s %+v", def.Meta(), v, root)
+ }
+ }
+ authKey, err := vpnKeyGen.Generate(username)
if err != nil {
return nil, err
}
@@ -147,19 +154,19 @@
}
ret[k] = picked
case KindAuth:
- r, err := deriveValues(v, v, AuthSchema, networks, vpnKeyGen)
+ r, err := deriveValues(root, v, AuthSchema, networks, vpnKeyGen)
if err != nil {
return nil, err
}
ret[k] = r
case KindSSHKey:
- r, err := deriveValues(v, v, SSHKeySchema, networks, vpnKeyGen)
+ r, err := deriveValues(root, v, SSHKeySchema, networks, vpnKeyGen)
if err != nil {
return nil, err
}
ret[k] = r
case KindStruct:
- r, err := deriveValues(v, v, def, networks, vpnKeyGen)
+ r, err := deriveValues(root, v, def, networks, vpnKeyGen)
if err != nil {
return nil, err
}
diff --git a/core/installer/helm.go b/core/installer/helm.go
index 8370b4e..7d3c334 100644
--- a/core/installer/helm.go
+++ b/core/installer/helm.go
@@ -42,6 +42,7 @@
}
type HelmFetcher interface {
+ // TODO(gio): implement integrity check
Pull(chart HelmChartGitRepo, rfs soft.RepoFS, root string) error
}
@@ -99,6 +100,9 @@
if err != nil {
return err
}
+ if err := rfs.RemoveDir(root); err != nil {
+ return err
+ }
return util.Walk(wtFS, "/", func(path string, info fs.FileInfo, err error) error {
if info.IsDir() {
return nil
diff --git a/core/installer/schema.go b/core/installer/schema.go
index b02f3b7..04955b1 100644
--- a/core/installer/schema.go
+++ b/core/installer/schema.go
@@ -231,8 +231,17 @@
case cue.StringKind:
if role == "vpnauthkey" {
meta := map[string]string{}
- usernameAttr := v.Attribute("usernameField")
- meta["usernameField"] = strings.ToLower(usernameAttr.Contents())
+ usernameFieldAttr := v.Attribute("usernameField")
+ if usernameFieldAttr.Err() == nil {
+ meta["usernameField"] = strings.ToLower(usernameFieldAttr.Contents())
+ }
+ usernameAttr := v.Attribute("username")
+ if usernameAttr.Err() == nil {
+ meta["username"] = strings.ToLower(usernameAttr.Contents())
+ }
+ if len(meta) != 1 {
+ return nil, fmt.Errorf("invalid vpn auth key field meta: %+v", meta)
+ }
return basicSchema{name, KindVPNAuthKey, true, meta}, nil
} else {
return basicSchema{name, KindString, false, nil}, nil
diff --git a/core/installer/soft/client.go b/core/installer/soft/client.go
index dd5bbfe..5163f23 100644
--- a/core/installer/soft/client.go
+++ b/core/installer/soft/client.go
@@ -16,6 +16,7 @@
"github.com/cenkalti/backoff/v4"
"github.com/go-git/go-billy/v5/memfs"
"github.com/go-git/go-git/v5"
+ "github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/transport"
gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
"github.com/go-git/go-git/v5/storage/memory"
@@ -29,6 +30,7 @@
GetPublicKeys() ([]string, error)
RepoExists(name string) (bool, error)
GetRepo(name string) (RepoIO, error)
+ GetRepoBranch(name, branch string) (RepoIO, error)
GetAllRepos() ([]string, error)
GetRepoAddress(name string) string
AddRepository(name string) error
@@ -44,6 +46,8 @@
AddReadWriteCollaborator(repo, user string) error
AddReadOnlyCollaborator(repo, user string) error
AddWebhook(repo, url string, opts ...string) error
+ DisableAnonAccess() error
+ DisableKeyless() error
}
type realClient struct {
@@ -265,13 +269,30 @@
return err
}
+func (ss *realClient) DisableAnonAccess() error {
+ log.Printf("Disabling anon access")
+ _, err := ss.RunCommand("settings", "anon-access", "no-access")
+ return err
+}
+
+func (ss *realClient) DisableKeyless() error {
+ log.Printf("Disabling anon access")
+ _, err := ss.RunCommand("settings", "allow-keyless", "false")
+ return err
+}
+
type Repository struct {
*git.Repository
Addr RepositoryAddress
+ Ref string
}
func (ss *realClient) GetRepo(name string) (RepoIO, error) {
- r, err := CloneRepository(RepositoryAddress{ss.addr, name}, ss.signer)
+ return ss.GetRepoBranch(name, "master")
+}
+
+func (ss *realClient) GetRepoBranch(name, branch string) (RepoIO, error) {
+ r, err := CloneRepositoryBranch(RepositoryAddress{ss.addr, name}, branch, ss.signer)
if err != nil {
return nil, err
}
@@ -305,7 +326,12 @@
}
func CloneRepository(addr RepositoryAddress, signer ssh.Signer) (*Repository, error) {
- fmt.Printf("Cloning repository: %s %s\n", addr.Addr, addr.Name)
+ return CloneRepositoryBranch(addr, "master", signer)
+}
+
+func CloneRepositoryBranch(addr RepositoryAddress, branch string, signer ssh.Signer) (*Repository, error) {
+ fmt.Printf("Cloning repository: %s %s %s\n", addr.Addr, addr.Name, branch)
+ ref := fmt.Sprintf("refs/heads/%s", branch)
c, err := git.Clone(memory.NewStorage(), memfs.New(), &git.CloneOptions{
URL: addr.FullAddress(),
Auth: &gitssh.PublicKeys{
@@ -320,7 +346,7 @@
},
},
RemoteName: "origin",
- ReferenceName: "refs/heads/master",
+ ReferenceName: plumbing.ReferenceName(ref),
SingleBranch: true,
Depth: 1,
InsecureSkipTLS: true,
@@ -348,6 +374,7 @@
return &Repository{
Repository: c,
Addr: addr,
+ Ref: ref,
}, nil
}
diff --git a/core/installer/soft/repoio.go b/core/installer/soft/repoio.go
index 191b291..458f688 100644
--- a/core/installer/soft/repoio.go
+++ b/core/installer/soft/repoio.go
@@ -209,6 +209,7 @@
if len(st) == 0 {
return "", nil // TODO(gio): maybe return ErrorNothingToCommit
}
+ fmt.Printf("@@@ %+v\n", st)
hash, err := wt.Commit(message, &git.CommitOptions{
Author: &object.Signature{
Name: "pcloud-installer",
@@ -223,11 +224,12 @@
Auth: auth(r.signer),
}
if o.ToBranch != "" {
- gopts.RefSpecs = []config.RefSpec{config.RefSpec(fmt.Sprintf("refs/heads/master:refs/heads/%s", o.ToBranch))}
+ gopts.RefSpecs = []config.RefSpec{config.RefSpec(fmt.Sprintf("%s:refs/heads/%s", r.repo.Ref, o.ToBranch))}
}
if o.Force {
gopts.Force = true
}
+ fmt.Println(3333)
return hash.String(), r.repo.Push(gopts)
}
@@ -259,6 +261,7 @@
if o.ToBranch != "" {
popts = append(popts, WithToBranch(o.ToBranch))
}
+ fmt.Println(2222)
return r.CommitAndPush(msg, popts...)
}
diff --git a/core/installer/values-tmpl/appmanager.cue b/core/installer/values-tmpl/appmanager.cue
index aad8f52..24d0d8d 100644
--- a/core/installer/values-tmpl/appmanager.cue
+++ b/core/installer/values-tmpl/appmanager.cue
@@ -29,57 +29,59 @@
_domain: "\(_subdomain).\(input.network.domain)"
url: "https://\(_domain)"
-ingress: {
- appmanager: {
- auth: {
- enabled: true
- groups: input.authGroups
- }
- network: input.network
- subdomain: _subdomain
- service: {
- name: "appmanager"
- port: name: _httpPortName
- }
- }
-}
-
-images: {
- appmanager: {
- repository: "giolekva"
- name: "pcloud-installer"
- tag: "latest"
- pullPolicy: "Always"
- }
-}
-
-charts: {
- appmanager: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/appmanager"
- }
-}
-
-helm: {
- appmanager: {
- chart: charts.appmanager
- values: {
- repoAddr: input.repoAddr
- sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
- headscaleAPIAddr: "http://headscale-api.\(global.namespacePrefix)app-headscale.svc.cluster.local"
- ingress: {
- className: input.network.ingressClass
- domain: _domain
- certificateIssuer: ""
+out: {
+ ingress: {
+ appmanager: {
+ auth: {
+ enabled: true
+ groups: input.authGroups
}
- clusterRoleName: "\(global.id)-appmanager"
- portName: _httpPortName
- image: {
- repository: images.appmanager.fullName
- tag: images.appmanager.tag
- pullPolicy: images.appmanager.pullPolicy
+ network: input.network
+ subdomain: _subdomain
+ service: {
+ name: "appmanager"
+ port: name: _httpPortName
+ }
+ }
+ }
+
+ images: {
+ appmanager: {
+ repository: "giolekva"
+ name: "pcloud-installer"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
+ }
+
+ charts: {
+ appmanager: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/appmanager"
+ }
+ }
+
+ helm: {
+ appmanager: {
+ chart: charts.appmanager
+ values: {
+ repoAddr: input.repoAddr
+ sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
+ headscaleAPIAddr: "http://headscale-api.\(global.namespacePrefix)app-headscale.svc.cluster.local"
+ ingress: {
+ className: input.network.ingressClass
+ domain: _domain
+ certificateIssuer: ""
+ }
+ clusterRoleName: "\(global.id)-appmanager"
+ portName: _httpPortName
+ image: {
+ repository: images.appmanager.fullName
+ tag: images.appmanager.tag
+ pullPolicy: images.appmanager.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/cert-manager.cue b/core/installer/values-tmpl/cert-manager.cue
index 0a89102..66e21af 100644
--- a/core/installer/values-tmpl/cert-manager.cue
+++ b/core/installer/values-tmpl/cert-manager.cue
@@ -3,104 +3,106 @@
name: "cert-manager"
namespace: "cert-manager"
-images: {
- certManager: {
- registry: "quay.io"
- repository: "jetstack"
- name: "cert-manager-controller"
- tag: "v1.12.2"
- pullPolicy: "IfNotPresent"
+out: {
+ images: {
+ certManager: {
+ registry: "quay.io"
+ repository: "jetstack"
+ name: "cert-manager-controller"
+ tag: "v1.12.2"
+ pullPolicy: "IfNotPresent"
+ }
+ cainjector: {
+ registry: "quay.io"
+ repository: "jetstack"
+ name: "cert-manager-cainjector"
+ tag: "v1.12.2"
+ pullPolicy: "IfNotPresent"
+ }
+ webhook: {
+ registry: "quay.io"
+ repository: "jetstack"
+ name: "cert-manager-webhook"
+ tag: "v1.12.2"
+ pullPolicy: "IfNotPresent"
+ }
+ dnsChallengeSolver: {
+ repository: "giolekva"
+ name: "dns-challenge-solver"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
- cainjector: {
- registry: "quay.io"
- repository: "jetstack"
- name: "cert-manager-cainjector"
- tag: "v1.12.2"
- pullPolicy: "IfNotPresent"
- }
- webhook: {
- registry: "quay.io"
- repository: "jetstack"
- name: "cert-manager-webhook"
- tag: "v1.12.2"
- pullPolicy: "IfNotPresent"
- }
- dnsChallengeSolver: {
- repository: "giolekva"
- name: "dns-challenge-solver"
- tag: "latest"
- pullPolicy: "Always"
- }
-}
-charts: {
- certManager: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/cert-manager"
+ charts: {
+ certManager: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/cert-manager"
+ }
+ dnsChallengeSolver: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/cert-manager-webhook-pcloud"
+ }
}
- dnsChallengeSolver: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/cert-manager-webhook-pcloud"
- }
-}
-helm: {
- "cert-manager": {
- chart: charts.certManager
- dependsOn: [{
- name: "ingress-public"
- namespace: "\(global.pcloudEnvName)-ingress-public"
- }]
- values: {
- fullnameOverride: "\(global.pcloudEnvName)-cert-manager"
- installCRDs: true
- dns01RecursiveNameserversOnly: true
- dns01RecursiveNameservers: "1.1.1.1:53,8.8.8.8:53"
- image: {
- repository: images.certManager.fullName
- tag: images.certManager.tag
- pullPolicy: images.certManager.pullPolicy
- }
- cainjector: {
+ helm: {
+ "cert-manager": {
+ chart: charts.certManager
+ dependsOn: [{
+ name: "ingress-public"
+ namespace: "\(global.pcloudEnvName)-ingress-public"
+ }]
+ values: {
+ fullnameOverride: "\(global.pcloudEnvName)-cert-manager"
+ installCRDs: true
+ dns01RecursiveNameserversOnly: true
+ dns01RecursiveNameservers: "1.1.1.1:53,8.8.8.8:53"
image: {
- repository: images.cainjector.fullName
- tag: images.cainjector.tag
- pullPolicy: images.cainjector.pullPolicy
+ repository: images.certManager.fullName
+ tag: images.certManager.tag
+ pullPolicy: images.certManager.pullPolicy
}
- }
- webhook: {
- image: {
- repository: images.webhook.fullName
- tag: images.webhook.tag
- pullPolicy: images.webhook.pullPolicy
+ cainjector: {
+ image: {
+ repository: images.cainjector.fullName
+ tag: images.cainjector.tag
+ pullPolicy: images.cainjector.pullPolicy
+ }
+ }
+ webhook: {
+ image: {
+ repository: images.webhook.fullName
+ tag: images.webhook.tag
+ pullPolicy: images.webhook.pullPolicy
+ }
}
}
}
- }
- "cert-manager-webhook-pcloud": {
- chart: charts.dnsChallengeSolver
- dependsOn: [{
- name: "cert-manager"
- namespace: release.namespace
- }]
- values: {
- fullnameOverride: "\(global.pcloudEnvName)-cert-manager-webhook-pcloud"
- certManager: {
- name: "\(global.pcloudEnvName)-cert-manager"
- namespace: "\(global.pcloudEnvName)-cert-manager"
+ "cert-manager-webhook-pcloud": {
+ chart: charts.dnsChallengeSolver
+ dependsOn: [{
+ name: "cert-manager"
+ namespace: release.namespace
+ }]
+ values: {
+ fullnameOverride: "\(global.pcloudEnvName)-cert-manager-webhook-pcloud"
+ certManager: {
+ name: "\(global.pcloudEnvName)-cert-manager"
+ namespace: "\(global.pcloudEnvName)-cert-manager"
+ }
+ image: {
+ repository: images.dnsChallengeSolver.fullName
+ tag: images.dnsChallengeSolver.tag
+ pullPolicy: images.dnsChallengeSolver.pullPolicy
+ }
+ logLevel: 2
+ apiGroupName: "dodo.cloud"
+ resolverName: "dns-resolver-pcloud"
}
- image: {
- repository: images.dnsChallengeSolver.fullName
- tag: images.dnsChallengeSolver.tag
- pullPolicy: images.dnsChallengeSolver.pullPolicy
- }
- logLevel: 2
- apiGroupName: "dodo.cloud"
- resolverName: "dns-resolver-pcloud"
}
}
}
diff --git a/core/installer/values-tmpl/certificate-issuer-custom.cue b/core/installer/values-tmpl/certificate-issuer-custom.cue
index 0b1bc6e..8721e7f 100644
--- a/core/installer/values-tmpl/certificate-issuer-custom.cue
+++ b/core/installer/values-tmpl/certificate-issuer-custom.cue
@@ -7,8 +7,6 @@
domain: string
}
-images: {}
-
name: "Network"
namespace: "ingress-custom"
readme: "Configure custom public domain"
@@ -36,29 +34,31 @@
</g>
</svg>"""
-charts: {
- "certificate-issuer": {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/certificate-issuer-public"
+out: {
+ charts: {
+ "certificate-issuer": {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/certificate-issuer-public"
+ }
}
-}
-helm: {
- "certificate-issuer": {
- chart: charts["certificate-issuer"]
- dependsOn: [{
- name: "ingress-nginx"
- namespace: "\(global.namespacePrefix)ingress-private"
- }]
- values: {
- issuer: {
- name: input.name
- server: "https://acme-v02.api.letsencrypt.org/directory"
- domain: input.domain
- contactEmail: global.contactEmail
- ingressClass: networks.public.ingressClass
+ helm: {
+ "certificate-issuer": {
+ chart: charts["certificate-issuer"]
+ dependsOn: [{
+ name: "ingress-nginx"
+ namespace: "\(global.namespacePrefix)ingress-private"
+ }]
+ values: {
+ issuer: {
+ name: input.name
+ server: "https://acme-v02.api.letsencrypt.org/directory"
+ domain: input.domain
+ contactEmail: global.contactEmail
+ 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 c67702b..66dc53c 100644
--- a/core/installer/values-tmpl/certificate-issuer-private.cue
+++ b/core/installer/values-tmpl/certificate-issuer-private.cue
@@ -3,34 +3,34 @@
name: "certificate-issuer-private"
namespace: "ingress-private"
-images: {}
-
-charts: {
- "certificate-issuer-private": {
- path: "charts/certificate-issuer-private"
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
+out: {
+ charts: {
+ "certificate-issuer-private": {
+ path: "charts/certificate-issuer-private"
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ }
}
-}
-helm: {
- "certificate-issuer-private": {
- chart: charts["certificate-issuer-private"]
- dependsOn: [{
- name: "ingress-nginx"
- namespace: "\(global.namespacePrefix)ingress-private"
- }]
- values: {
- issuer: {
- name: "\(global.id)-private"
- server: "https://acme-v02.api.letsencrypt.org/directory"
- domain: global.privateDomain
- contactEmail: global.contactEmail
- }
- config: {
- createTXTAddr: "http://dns-api.\(global.id)-dns.svc.cluster.local/create-txt-record"
- deleteTXTAddr: "http://dns-api.\(global.id)-dns.svc.cluster.local/delete-txt-record"
+ helm: {
+ "certificate-issuer-private": {
+ chart: charts["certificate-issuer-private"]
+ dependsOn: [{
+ name: "ingress-nginx"
+ namespace: "\(global.namespacePrefix)ingress-private"
+ }]
+ values: {
+ issuer: {
+ name: "\(global.id)-private"
+ server: "https://acme-v02.api.letsencrypt.org/directory"
+ domain: global.privateDomain
+ contactEmail: global.contactEmail
+ }
+ config: {
+ createTXTAddr: "http://dns-api.\(global.id)-dns.svc.cluster.local/create-txt-record"
+ deleteTXTAddr: "http://dns-api.\(global.id)-dns.svc.cluster.local/delete-txt-record"
+ }
}
}
}
diff --git a/core/installer/values-tmpl/certificate-issuer-public.cue b/core/installer/values-tmpl/certificate-issuer-public.cue
index 15f2d11..04a6e50 100644
--- a/core/installer/values-tmpl/certificate-issuer-public.cue
+++ b/core/installer/values-tmpl/certificate-issuer-public.cue
@@ -2,30 +2,30 @@
network: #Network
}
-images: {}
-
name: "certificate-issuer-public"
namespace: "ingress-private"
-charts: {
- "certificate-issuer-public": {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/certificate-issuer-public"
+out: {
+ charts: {
+ "certificate-issuer-public": {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/certificate-issuer-public"
+ }
}
-}
-helm: {
- "certificate-issuer-public": {
- chart: charts["certificate-issuer-public"]
- values: {
- issuer: {
- name: input.network.certificateIssuer
- server: "https://acme-v02.api.letsencrypt.org/directory"
- domain: input.network.domain
- contactEmail: global.contactEmail
- ingressClass: input.network.ingressClass
+ helm: {
+ "certificate-issuer-public": {
+ chart: charts["certificate-issuer-public"]
+ values: {
+ issuer: {
+ name: input.network.certificateIssuer
+ server: "https://acme-v02.api.letsencrypt.org/directory"
+ domain: input.network.domain
+ contactEmail: global.contactEmail
+ ingressClass: input.network.ingressClass
+ }
}
}
}
diff --git a/core/installer/values-tmpl/coder.cue b/core/installer/values-tmpl/coder.cue
index 7f98189..4365830 100644
--- a/core/installer/values-tmpl/coder.cue
+++ b/core/installer/values-tmpl/coder.cue
@@ -12,125 +12,127 @@
description: readme
icon: "<svg xmlns='http://www.w3.org/2000/svg' width='50px' height='50px' viewBox='0 0 16 16'><path fill='currentColor' fill-rule='evenodd' d='M11.573.275a1.203 1.203 0 0 0-.191.073c-.039.021-1.383 1.172-2.986 2.558C6.792 4.291 5.462 5.424 5.44 5.424c-.022 0-.664-.468-1.427-1.04c-.762-.571-1.428-1.057-1.48-1.078c-.15-.063-.468-.05-.613.024C1.754 3.416.189 4.975.094 5.15a.741.741 0 0 0 .04.766c.041.057.575.557 1.185 1.11c.611.553 1.107 1.015 1.102 1.026c-.004.012-.495.442-1.091.957c-.596.514-1.122.981-1.168 1.036a.746.746 0 0 0-.069.804c.096.175 1.659 1.734 1.827 1.821c.166.087.497.089.653.005c.059-.031.7-.502 1.424-1.046l1.318-.988l.109.1l2.73 2.473c1.846 1.671 2.666 2.396 2.772 2.453l.15.08h1.348l1.631-.814c1.5-.748 1.64-.823 1.748-.942c.213-.237.197.241.197-5.738c0-5.821.009-5.468-.151-5.699c-.058-.084-.41-.331-1.634-1.148c-.857-.572-1.613-1.065-1.68-1.095c-.1-.045-.187-.056-.482-.063c-.237-.005-.401.004-.48.027m1.699 2.305l1.233.82l.001 4.82l.001 4.82l-1.205.6l-1.204.6h-.569L8.66 11.644c-1.578-1.428-2.912-2.616-2.963-2.641c-.199-.094-.5-.101-.661-.014c-.034.018-.651.475-1.372 1.015c-.721.541-1.322.983-1.335.983c-.03 0-.477-.448-.461-.462c.673-.577 2.078-1.794 2.182-1.891c.086-.081.169-.192.21-.28c.057-.127.065-.174.054-.343c-.01-.158-.028-.223-.091-.324c-.053-.086-.454-.466-1.229-1.167l-1.15-1.04l.231-.233a1.83 1.83 0 0 1 .256-.234c.013 0 .644.465 1.4 1.033c1.496 1.123 1.537 1.148 1.81 1.116a.968.968 0 0 0 .253-.069c.062-.029.503-.39.979-.802L7.96 5.265a5929.2 5929.2 0 0 0 2.187-1.89a191.687 191.687 0 0 1 1.879-1.614c.008-.001.568.368 1.246.819M11.64 4.257a1.5 1.5 0 0 0-.16.051c-.059.021-1.079.738-2.267 1.593C6.867 7.59 6.92 7.547 6.851 7.854a.556.556 0 0 0 0 .292c.068.307.017.264 2.362 1.953c1.188.855 2.214 1.576 2.28 1.601c.347.133.743-.029.929-.38l.071-.133V4.813l-.071-.133a.76.76 0 0 0-.369-.356c-.127-.056-.324-.088-.413-.067m-.66 4.5l-.007.757l-1.046-.75A41.313 41.313 0 0 1 8.881 8c0-.007.471-.351 1.046-.764l1.046-.75l.007.757a95.51 95.51 0 0 1 0 1.514'/></svg>"
-ingress: {
- coder: {
- auth: enabled: false
- network: input.network
- subdomain: input.subdomain
- service: {
+out: {
+ ingress: {
+ coder: {
+ auth: enabled: false
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "coder"
+ port: name: "http"
+ }
+ }
+ }
+
+ images: {
+ postgres: {
+ repository: "library"
+ name: "postgres"
+ tag: "15.3"
+ pullPolicy: "IfNotPresent"
+ }
+ coder: {
+ registry: "ghcr.io"
+ repository: "coder"
name: "coder"
- port: name: "http"
+ tag: "latest"
+ pullPolicy: "IfNotPresent"
}
}
-}
-images: {
- postgres: {
- repository: "library"
- name: "postgres"
- tag: "15.3"
- pullPolicy: "IfNotPresent"
- }
- coder: {
- registry: "ghcr.io"
- repository: "coder"
- name: "coder"
- tag: "latest"
- pullPolicy: "IfNotPresent"
- }
-}
-
-charts: {
- postgres: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/postgresql"
- }
- coder: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/coder"
- }
- oauth2Client: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/oauth2-client"
- }
-}
-
-_oauth2ClientSecretName: "oauth2-credentials"
-
-helm: {
- "oauth2-client": {
- chart: charts.oauth2Client
- values: {
- name: "\(release.namespace)-coder"
- secretName: _oauth2ClientSecretName
- grantTypes: ["authorization_code"]
- responseTypes: ["code"]
- scope: "openid profile email"
- redirectUris: ["\(url)/api/v2/users/oidc/callbackzot"]
- hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
+ charts: {
+ postgres: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/postgresql"
+ }
+ coder: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/coder"
+ }
+ oauth2Client: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/oauth2-client"
}
}
- postgres: {
- chart: charts.postgres
- values: {
- fullnameOverride: "postgres"
- image: {
- registry: images.postgres.registry
- repository: images.postgres.imageName
- tag: images.postgres.tag
- pullPolicy: images.postgres.pullPolicy
- }
- auth: {
- username: "coder"
- password: "coder"
- database: "coder"
+
+ _oauth2ClientSecretName: "oauth2-credentials"
+
+ helm: {
+ "oauth2-client": {
+ chart: charts.oauth2Client
+ values: {
+ name: "\(release.namespace)-coder"
+ secretName: _oauth2ClientSecretName
+ grantTypes: ["authorization_code"]
+ responseTypes: ["code"]
+ scope: "openid profile email"
+ redirectUris: ["\(url)/api/v2/users/oidc/callbackzot"]
+ hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
}
}
- }
- coder: {
- chart: charts.coder
- values: coder: {
- image: {
- repo: images.coder.fullName
- tag: images.coder.tag
- pullPolicy: images.coder.pullPolicy
- }
- envUseClusterAccessURL: false
- env: [{
- name: "CODER_ACCESS_URL"
- value: url
- }, {
- name: "CODER_PG_CONNECTION_URL"
- value: "postgres://coder:coder@postgres.\(release.namespace).svc.cluster.local:5432/coder?sslmode=disable"
- }, {
- name: "CODER_OIDC_ISSUER_URL"
- value: "https://hydra.\(networks.public.domain)"
- }, {
- name: "CODER_OIDC_EMAIL_DOMAIN"
- value: networks.public.domain
- }, {
- name: "CODER_OIDC_CLIENT_ID"
- valueFrom: {
- secretKeyRef: {
- name: _oauth2ClientSecretName
- key: "client_id"
- }
+ postgres: {
+ chart: charts.postgres
+ values: {
+ fullnameOverride: "postgres"
+ image: {
+ registry: images.postgres.registry
+ repository: images.postgres.imageName
+ tag: images.postgres.tag
+ pullPolicy: images.postgres.pullPolicy
}
- }, {
- name: "CODER_OIDC_CLIENT_SECRET"
- valueFrom: {
- secretKeyRef: {
- name: _oauth2ClientSecretName
- key: "client_secret"
- }
+ auth: {
+ username: "coder"
+ password: "coder"
+ database: "coder"
}
- }]
+ }
+ }
+ coder: {
+ chart: charts.coder
+ values: coder: {
+ image: {
+ repo: images.coder.fullName
+ tag: images.coder.tag
+ pullPolicy: images.coder.pullPolicy
+ }
+ envUseClusterAccessURL: false
+ env: [{
+ name: "CODER_ACCESS_URL"
+ value: url
+ }, {
+ name: "CODER_PG_CONNECTION_URL"
+ value: "postgres://coder:coder@postgres.\(release.namespace).svc.cluster.local:5432/coder?sslmode=disable"
+ }, {
+ name: "CODER_OIDC_ISSUER_URL"
+ value: "https://hydra.\(networks.public.domain)"
+ }, {
+ name: "CODER_OIDC_EMAIL_DOMAIN"
+ value: networks.public.domain
+ }, {
+ name: "CODER_OIDC_CLIENT_ID"
+ valueFrom: {
+ secretKeyRef: {
+ name: _oauth2ClientSecretName
+ key: "client_id"
+ }
+ }
+ }, {
+ name: "CODER_OIDC_CLIENT_SECRET"
+ valueFrom: {
+ secretKeyRef: {
+ name: _oauth2ClientSecretName
+ key: "client_secret"
+ }
+ }
+ }]
+ }
}
}
}
diff --git a/core/installer/values-tmpl/config-repo.cue b/core/installer/values-tmpl/config-repo.cue
index f56da11..26ada75 100644
--- a/core/installer/values-tmpl/config-repo.cue
+++ b/core/installer/values-tmpl/config-repo.cue
@@ -7,41 +7,40 @@
name: "config-repo"
namespace: "config-repo"
-images: {
- softserve: {
- repository: "charmcli"
- name: "soft-serve"
- tag: "v0.7.1"
- pullPolicy: "IfNotPresent"
+out: {
+ images: {
+ softserve: {
+ repository: "charmcli"
+ name: "soft-serve"
+ tag: "v0.7.1"
+ pullPolicy: "IfNotPresent"
+ }
}
-}
-charts: {
- softserve: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/soft-serve"
+ charts: {
+ softserve: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/soft-serve"
+ }
}
-}
-helm: {
- softserve: {
- chart: charts.softserve
- values: {
- serviceType: "ClusterIP"
- addressPool: ""
- reservedIP: ""
- adminKey: input.adminKey
- privateKey: input.privateKey
- publicKey: input.publicKey
- ingress: {
- enabled: false
- }
- image: {
- repository: images.softserve.fullName
- tag: images.softserve.tag
- pullPolicy: images.softserve.pullPolicy
+ helm: {
+ softserve: {
+ chart: charts.softserve
+ values: {
+ serviceType: "ClusterIP"
+ addressPool: ""
+ reservedIP: ""
+ adminKey: input.adminKey
+ privateKey: input.privateKey
+ publicKey: input.publicKey
+ image: {
+ repository: images.softserve.fullName
+ tag: images.softserve.tag
+ pullPolicy: images.softserve.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/core-auth.cue b/core/installer/values-tmpl/core-auth.cue
index 079da27..d535c97 100644
--- a/core/installer/values-tmpl/core-auth.cue
+++ b/core/installer/values-tmpl/core-auth.cue
@@ -36,344 +36,353 @@
}
"""###
-images: {
- kratos: {
- repository: "oryd"
- name: "kratos"
- tag: "v1.1.0-distroless"
- pullPolicy: "IfNotPresent"
+out: {
+ images: {
+ kratos: {
+ repository: "oryd"
+ name: "kratos"
+ tag: "v1.1.0-distroless"
+ pullPolicy: "IfNotPresent"
+ }
+ hydra: {
+ repository: "oryd"
+ name: "hydra"
+ tag: "v2.2.0-distroless"
+ pullPolicy: "IfNotPresent"
+ }
+ ui: {
+ repository: "giolekva"
+ name: "auth-ui"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
+ postgres: {
+ repository: "library"
+ name: "postgres"
+ tag: "15.3"
+ pullPolicy: "IfNotPresent"
+ }
}
- hydra: {
- repository: "oryd"
- name: "hydra"
- tag: "v2.2.0-distroless"
- pullPolicy: "IfNotPresent"
- }
- ui: {
- repository: "giolekva"
- name: "auth-ui"
- tag: "latest"
- pullPolicy: "Always"
- }
- postgres: {
- repository: "library"
- name: "postgres"
- tag: "15.3"
- pullPolicy: "IfNotPresent"
- }
-}
-charts: {
- auth: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/auth"
+ charts: {
+ auth: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/auth"
+ }
+ postgres: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/postgresql"
+ }
}
- postgres: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/postgresql"
- }
-}
-helm: {
- postgres: {
- chart: charts.postgres
- values: {
- fullnameOverride: "postgres"
- image: {
- registry: images.postgres.registry
- repository: images.postgres.imageName
- tag: images.postgres.tag
- pullPolicy: images.postgres.pullPolicy
- }
- service: {
- type: "ClusterIP"
- port: 5432
- }
- primary: {
- initdb: {
- scripts: {
- "init.sql": """
- CREATE USER kratos WITH PASSWORD 'kratos';
- CREATE USER hydra WITH PASSWORD 'hydra';
- CREATE DATABASE kratos WITH OWNER = kratos;
- CREATE DATABASE hydra WITH OWNER = hydra;
- """
+ helm: {
+ postgres: {
+ chart: charts.postgres
+ values: {
+ fullnameOverride: "postgres"
+ image: {
+ registry: images.postgres.registry
+ repository: images.postgres.imageName
+ tag: images.postgres.tag
+ pullPolicy: images.postgres.pullPolicy
+ }
+ service: {
+ type: "ClusterIP"
+ port: 5432
+ }
+ primary: {
+ initdb: {
+ scripts: {
+ "init.sql": """
+ CREATE USER kratos WITH PASSWORD 'kratos';
+ CREATE USER hydra WITH PASSWORD 'hydra';
+ CREATE DATABASE kratos WITH OWNER = kratos;
+ CREATE DATABASE hydra WITH OWNER = hydra;
+ """
+ }
+ }
+ persistence: {
+ size: "1Gi"
+ }
+ securityContext: {
+ enabled: true
+ fsGroup: 0
+ }
+ containerSecurityContext: {
+ enabled: true
+ runAsUser: 0
}
}
- persistence: {
- size: "1Gi"
- }
- securityContext: {
- enabled: true
- fsGroup: 0
- }
- containerSecurityContext: {
- enabled: true
- runAsUser: 0
- }
- }
- volumePermissions: {
- securityContext: {
- runAsUser: 0
+ volumePermissions: {
+ securityContext: {
+ runAsUser: 0
+ }
}
}
}
- }
- auth: {
- chart: charts.auth
- dependsOn: [{
- name: "postgres"
- namespace: release.namespace
- }]
- values: {
- kratos: {
- fullnameOverride: "kratos"
- image: {
- repository: images.kratos.fullName
- tag: images.kratos.tag
- pullPolicy: images.kratos.pullPolicy
- }
- service: {
- admin: {
- enabled: true
- type: "ClusterIP"
- port: 80
- name: "http"
- }
- public: {
- enabled: true
- type: "ClusterIP"
- port: 80
- name: "http"
- }
- }
- ingress: {
- admin: enabled: false
- public: {
- enabled: true
- className: input.network.ingressClass
- annotations: {
- "acme.cert-manager.io/http01-edit-in-place": "true"
- "cert-manager.io/cluster-issuer": input.network.certificateIssuer
- }
- hosts: [{
- host: "accounts.\(input.network.domain)"
- paths: [{
- path: "/"
- pathType: "Prefix"
- }]
- }]
- tls: [{
- hosts: ["accounts.\(input.network.domain)"]
- secretName: "cert-accounts.\(input.network.domain)"
- }]
- }
- }
- secret: {
- enabled: true
- }
+ auth: {
+ chart: charts.auth
+ dependsOn: [{
+ name: "postgres"
+ namespace: release.namespace
+ }]
+ values: {
kratos: {
- automigration: {
+ fullnameOverride: "kratos"
+ image: {
+ repository: images.kratos.fullName
+ tag: images.kratos.tag
+ pullPolicy: images.kratos.pullPolicy
+ }
+ service: {
+ admin: {
+ enabled: true
+ type: "ClusterIP"
+ port: 80
+ name: "http"
+ }
+ public: {
+ enabled: true
+ type: "ClusterIP"
+ port: 80
+ name: "http"
+ }
+ }
+ ingress: {
+ admin: enabled: false
+ public: {
+ enabled: true
+ className: input.network.ingressClass
+ annotations: {
+ "acme.cert-manager.io/http01-edit-in-place": "true"
+ "cert-manager.io/cluster-issuer": input.network.certificateIssuer
+ }
+ hosts: [{
+ host: "accounts.\(input.network.domain)"
+ paths: [{
+ path: "/"
+ pathType: "Prefix"
+ }]
+ }]
+ tls: [{
+ hosts: ["accounts.\(input.network.domain)"]
+ secretName: "cert-accounts.\(input.network.domain)"
+ }]
+ }
+ }
+ secret: {
enabled: true
}
- development: false
- courier: {
- enabled: false
- }
- config: {
- version: "v0.7.1-alpha.1"
- 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.\(input.network.domain)"
- cors: {
- enabled: true
- debug: false
- allow_credentials: true
- allowed_origins: [
- "https://\(input.network.domain)",
- "https://*.\(input.network.domain)",
- ]
- }
- }
- admin: {
- base_url: "https://kratos-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
- }
+ kratos: {
+ automigration: {
+ enabled: true
}
- selfservice: {
- default_browser_return_url: "https://accounts-ui.\(input.network.domain)"
- allowed_return_urls: [
- "https://*.\(input.network.domain)/",
- // TODO(gio): replace with input.network.privateSubdomain
- "https://*.\(global.privateDomain)",
- ]
- methods: {
- password: {
- enabled: true
- }
- }
- flows: {
- error: {
- ui_url: "https://accounts-ui.\(input.network.domain)/error"
- }
- settings: {
- ui_url: "https://accounts-ui.\(input.network.domain)/settings"
- privileged_session_max_age: "15m"
- }
- recovery: {
- enabled: false
- }
- verification: {
- enabled: false
- }
- logout: {
- after: {
- default_browser_return_url: "https://accounts-ui.\(input.network.domain)/login"
- }
- }
- login: {
- ui_url: "https://accounts-ui.\(input.network.domain)/login"
- lifespan: "10m"
- after: {
- password: {
- default_browser_return_url: "https://accounts-ui.\(input.network.domain)/"
- }
- }
- }
- registration: {
- lifespan: "10m"
- ui_url: "https://accounts-ui.\(input.network.domain)/register"
- after: {
- password: {
- hooks: [{
- hook: "session"
- }]
- default_browser_return_url: "https://accounts-ui.\(input.network.domain)/"
- }
- }
- }
- }
- }
- log: {
- level: "debug"
- format: "text"
- leak_sensitive_values: true
- }
- cookies: {
- path: "/"
- same_site: "None"
- domain: input.network.domain
- }
- secrets: {
- cookie: ["PLEASE-CHANGE-ME-I-AM-VERY-INSECURE"]
- }
- hashers: {
- argon2: {
- parallelism: 1
- memory: "128MB"
- iterations: 2
- salt_length: 16
- key_length: 16
- }
- }
- identity: {
- schemas: [{
- id: "user"
- url: "file:///etc/config/identity.schema.json"
- }]
- default_schema_id: "user"
- }
+ development: false
courier: {
- smtp: {
- connection_uri: "smtps://test-z1VmkYfYPjgdPRgPFgmeZ31esT9rUgS%40\(input.network.domain):iW%213Kk%5EPPLFrZa%24%21bbpTPN9Wv3b8mvwS6ZJvMLtce%23A2%2A4MotD@mx1.\(input.network.domain)"
+ enabled: false
+ }
+ config: {
+ version: "v0.7.1-alpha.1"
+ 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.\(input.network.domain)"
+ cors: {
+ enabled: true
+ debug: false
+ allow_credentials: true
+ allowed_origins: [
+ "https://\(input.network.domain)",
+ "https://*.\(input.network.domain)",
+ ]
+ }
+ }
+ admin: {
+ base_url: "https://kratos-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
+ }
+ }
+ selfservice: {
+ default_browser_return_url: "https://accounts-ui.\(input.network.domain)"
+ allowed_return_urls: [
+ "https://*.\(input.network.domain)/",
+ // TODO(gio): replace with input.network.privateSubdomain
+ "https://*.\(global.privateDomain)",
+ ]
+ methods: {
+ password: {
+ enabled: true
+ }
+ }
+ flows: {
+ error: {
+ ui_url: "https://accounts-ui.\(input.network.domain)/error"
+ }
+ settings: {
+ ui_url: "https://accounts-ui.\(input.network.domain)/settings"
+ privileged_session_max_age: "15m"
+ }
+ recovery: {
+ enabled: false
+ }
+ verification: {
+ enabled: false
+ }
+ logout: {
+ after: {
+ default_browser_return_url: "https://accounts-ui.\(input.network.domain)/login"
+ }
+ }
+ login: {
+ ui_url: "https://accounts-ui.\(input.network.domain)/login"
+ lifespan: "10m"
+ after: {
+ password: {
+ default_browser_return_url: "https://accounts-ui.\(input.network.domain)/"
+ }
+ }
+ }
+ registration: {
+ lifespan: "10m"
+ ui_url: "https://accounts-ui.\(input.network.domain)/register"
+ after: {
+ password: {
+ hooks: [{
+ hook: "session"
+ }]
+ default_browser_return_url: "https://accounts-ui.\(input.network.domain)/"
+ }
+ }
+ }
+ }
+ }
+ log: {
+ level: "debug"
+ format: "text"
+ leak_sensitive_values: true
+ }
+ cookies: {
+ path: "/"
+ same_site: "None"
+ domain: input.network.domain
+ }
+ secrets: {
+ cookie: ["PLEASE-CHANGE-ME-I-AM-VERY-INSECURE"]
+ }
+ hashers: {
+ argon2: {
+ parallelism: 1
+ memory: "128MB"
+ iterations: 2
+ salt_length: 16
+ key_length: 16
+ }
+ }
+ identity: {
+ schemas: [{
+ id: "user"
+ url: "file:///etc/config/identity.schema.json"
+ }]
+ default_schema_id: "user"
+ }
+ courier: {
+ smtp: {
+ connection_uri: "smtps://test-z1VmkYfYPjgdPRgPFgmeZ31esT9rUgS%40\(input.network.domain):iW%213Kk%5EPPLFrZa%24%21bbpTPN9Wv3b8mvwS6ZJvMLtce%23A2%2A4MotD@mx1.\(input.network.domain)"
+ }
}
}
- }
- identitySchemas: {
- "identity.schema.json": _userSchema
- }
- }
- }
- hydra: {
- fullnameOverride: "hydra"
- image: {
- repository: images.hydra.fullName
- tag: images.hydra.tag
- pullPolicy: images.hydra.pullPolicy
- }
- service: {
- admin: {
- enabled: true
- type: "ClusterIP"
- port: 80
- name: "http"
- }
- public: {
- enabled: true
- type: "ClusterIP"
- port: 80
- name: "http"
- }
- }
- ingress: {
- admin: enabled: false
- public: {
- enabled: true
- className: input.network.ingressClass
- annotations: {
- "acme.cert-manager.io/http01-edit-in-place": "true"
- "cert-manager.io/cluster-issuer": input.network.certificateIssuer
+ identitySchemas: {
+ "identity.schema.json": _userSchema
}
- hosts: [{
- host: "hydra.\(input.network.domain)"
- paths: [{
- path: "/"
- pathType: "Prefix"
- }]
- }]
- tls: [{
- hosts: ["hydra.\(input.network.domain)"]
- secretName: "cert-hydra.\(input.network.domain)"
- }]
}
}
- secret: {
- enabled: true
- }
- maester: {
- enabled: false
- }
hydra: {
- automigration: {
+ fullnameOverride: "hydra"
+ image: {
+ repository: images.hydra.fullName
+ tag: images.hydra.tag
+ pullPolicy: images.hydra.pullPolicy
+ }
+ service: {
+ admin: {
+ enabled: true
+ type: "ClusterIP"
+ port: 80
+ name: "http"
+ }
+ public: {
+ enabled: true
+ type: "ClusterIP"
+ port: 80
+ name: "http"
+ }
+ }
+ ingress: {
+ admin: enabled: false
+ public: {
+ enabled: true
+ className: input.network.ingressClass
+ annotations: {
+ "acme.cert-manager.io/http01-edit-in-place": "true"
+ "cert-manager.io/cluster-issuer": input.network.certificateIssuer
+ }
+ hosts: [{
+ host: "hydra.\(input.network.domain)"
+ paths: [{
+ path: "/"
+ pathType: "Prefix"
+ }]
+ }]
+ tls: [{
+ hosts: ["hydra.\(input.network.domain)"]
+ secretName: "cert-hydra.\(input.network.domain)"
+ }]
+ }
+ }
+ secret: {
enabled: true
}
- config: {
- version: "v1.10.6"
- dsn: "postgres://hydra:hydra@postgres.\(global.namespacePrefix)core-auth.svc:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4"
- serve: {
- cookies: {
- same_site_mode: "None"
- }
- public: {
- cors: {
- enabled: true
- debug: false
- allow_credentials: true
- allowed_origins: [
- "https://\(input.network.domain)",
- "https://*.\(input.network.domain)"
- ]
+ maester: {
+ enabled: false
+ }
+ hydra: {
+ automigration: {
+ enabled: true
+ }
+ config: {
+ version: "v1.10.6"
+ dsn: "postgres://hydra:hydra@postgres.\(global.namespacePrefix)core-auth.svc:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4"
+ serve: {
+ cookies: {
+ same_site_mode: "None"
}
- }
- admin: {
- cors: {
- allowed_origins: [
- "https://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
- ]
+ public: {
+ cors: {
+ enabled: true
+ debug: false
+ allow_credentials: true
+ allowed_origins: [
+ "https://\(input.network.domain)",
+ "https://*.\(input.network.domain)"
+ ]
+ }
+ }
+ admin: {
+ cors: {
+ allowed_origins: [
+ "https://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
+ ]
+ }
+ tls: {
+ allow_termination_from: [
+ "0.0.0.0/0",
+ "10.42.0.0/16",
+ "10.43.0.0/16",
+ ]
+ }
}
tls: {
allow_termination_from: [
@@ -383,54 +392,47 @@
]
}
}
- tls: {
- allow_termination_from: [
- "0.0.0.0/0",
- "10.42.0.0/16",
- "10.43.0.0/16",
- ]
+ urls: {
+ self: {
+ public: "https://hydra.\(input.network.domain)"
+ issuer: "https://hydra.\(input.network.domain)"
+ }
+ consent: "https://accounts-ui.\(input.network.domain)/consent"
+ login: "https://accounts-ui.\(input.network.domain)/login"
+ logout: "https://accounts-ui.\(input.network.domain)/logout"
}
- }
- urls: {
- self: {
- public: "https://hydra.\(input.network.domain)"
- issuer: "https://hydra.\(input.network.domain)"
+ secrets: {
+ system: ["youReallyNeedToChangeThis"]
}
- 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"]
- }
- oidc: {
- subject_identifiers: {
- supported_types: [
- "pairwise",
- "public",
- ]
- pairwise: {
- salt: "youReallyNeedToChangeThis"
+ oidc: {
+ subject_identifiers: {
+ supported_types: [
+ "pairwise",
+ "public",
+ ]
+ pairwise: {
+ salt: "youReallyNeedToChangeThis"
+ }
}
}
- }
- log: {
- level: "trace"
- leak_sensitive_values: false
+ log: {
+ level: "trace"
+ leak_sensitive_values: false
+ }
}
}
}
- }
- ui: {
- 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: {
- repository: images.ui.fullName
- tag: images.ui.tag
- pullPolicy: images.ui.pullPolicy
+ ui: {
+ 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: {
+ repository: images.ui.fullName
+ tag: images.ui.tag
+ pullPolicy: images.ui.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/csi-driver-smb.cue b/core/installer/values-tmpl/csi-driver-smb.cue
index d765f7d..4627b3b 100644
--- a/core/installer/values-tmpl/csi-driver-smb.cue
+++ b/core/installer/values-tmpl/csi-driver-smb.cue
@@ -9,58 +9,60 @@
pullPolicy: "IfNotPresent"
}
-images: {
- smb: _baseImage & {
- name: "smbplugin"
- tag: "v1.11.0"
+out: {
+ images: {
+ smb: _baseImage & {
+ name: "smbplugin"
+ tag: "v1.11.0"
+ }
+ csiProvisioner: _baseImage & {
+ name: "csi-provisioner"
+ tag: "v3.5.0"
+ }
+ livenessProbe: _baseImage & {
+ name: "livenessprobe"
+ tag: "v2.10.0"
+ }
+ nodeDriverRegistrar: _baseImage & {
+ name: "csi-node-driver-registrar"
+ tag: "v2.8.0"
+ }
}
- csiProvisioner: _baseImage & {
- name: "csi-provisioner"
- tag: "v3.5.0"
- }
- livenessProbe: _baseImage & {
- name: "livenessprobe"
- tag: "v2.10.0"
- }
- nodeDriverRegistrar: _baseImage & {
- name: "csi-node-driver-registrar"
- tag: "v2.8.0"
- }
-}
-charts: {
- csiDriverSMB: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/csi-driver-smb"
+ charts: {
+ csiDriverSMB: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/csi-driver-smb"
+ }
}
-}
-helm: {
- "csi-driver-smb": {
- chart: charts.csiDriverSMB
- values: {
- image: {
- smb: {
- repository: images.smb.fullName
- tag: images.smb.tag
- pullPolicy: images.smb.pullPolicy
- }
- csiProvisioner: {
- repository: images.csiProvisioner.fullName
- tag: images.csiProvisioner.tag
- pullPolicy: images.csiProvisioner.pullPolicy
- }
- livenessProbe: {
- repository: images.livenessProbe.fullName
- tag: images.livenessProbe.tag
- pullPolicy: images.livenessProbe.pullPolicy
- }
- nodeDriverRegistrar: {
- repository: images.nodeDriverRegistrar.fullName
- tag: images.nodeDriverRegistrar.tag
- pullPolicy: images.nodeDriverRegistrar.pullPolicy
+ helm: {
+ "csi-driver-smb": {
+ chart: charts.csiDriverSMB
+ values: {
+ image: {
+ smb: {
+ repository: images.smb.fullName
+ tag: images.smb.tag
+ pullPolicy: images.smb.pullPolicy
+ }
+ csiProvisioner: {
+ repository: images.csiProvisioner.fullName
+ tag: images.csiProvisioner.tag
+ pullPolicy: images.csiProvisioner.pullPolicy
+ }
+ livenessProbe: {
+ repository: images.livenessProbe.fullName
+ tag: images.livenessProbe.tag
+ pullPolicy: images.livenessProbe.pullPolicy
+ }
+ nodeDriverRegistrar: {
+ repository: images.nodeDriverRegistrar.fullName
+ tag: images.nodeDriverRegistrar.tag
+ pullPolicy: images.nodeDriverRegistrar.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/dns-gateway.cue b/core/installer/values-tmpl/dns-gateway.cue
index 59d2c37..bca02df 100644
--- a/core/installer/values-tmpl/dns-gateway.cue
+++ b/core/installer/values-tmpl/dns-gateway.cue
@@ -10,109 +10,111 @@
name: "dns-gateway"
namespace: "dns-gateway"
-images: {
- coredns: {
- repository: "coredns"
- name: "coredns"
- tag: "1.11.1"
- pullPolicy: "IfNotPresent"
+out: {
+ images: {
+ coredns: {
+ repository: "coredns"
+ name: "coredns"
+ tag: "1.11.1"
+ pullPolicy: "IfNotPresent"
+ }
}
-}
-charts: {
- coredns: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/coredns"
+ charts: {
+ coredns: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/coredns"
+ }
}
-}
-helm: {
- coredns: {
- chart: charts.coredns
- values: {
- image: {
- repository: images.coredns.fullName
- tag: images.coredns.tag
- pullPolicy: images.coredns.pullPolicy
- }
- replicaCount: 1
- resources: {
- limits: {
- cpu: "100m"
- memory: "128Mi"
+ helm: {
+ coredns: {
+ chart: charts.coredns
+ values: {
+ image: {
+ repository: images.coredns.fullName
+ tag: images.coredns.tag
+ pullPolicy: images.coredns.pullPolicy
}
- requests: {
- cpu: "100m"
- memory: "128Mi"
+ replicaCount: 1
+ resources: {
+ limits: {
+ cpu: "100m"
+ memory: "128Mi"
+ }
+ requests: {
+ cpu: "100m"
+ memory: "128Mi"
+ }
}
- }
- rollingUpdate: {
- maxUnavailable: 1
- maxSurge: "25%"
- }
- terminationGracePeriodSeconds: 30
- serviceType: "ClusterIP"
- service: name: "coredns"
- serviceAccount: create: false
- rbac: {
- create: false
- pspEnable: false
- }
- isClusterService: false
- if len(input.servers) > 0 {
- servers: [
- for s in input.servers {
+ rollingUpdate: {
+ maxUnavailable: 1
+ maxSurge: "25%"
+ }
+ terminationGracePeriodSeconds: 30
+ serviceType: "ClusterIP"
+ service: name: "coredns"
+ serviceAccount: create: false
+ rbac: {
+ create: false
+ pspEnable: false
+ }
+ isClusterService: false
+ if len(input.servers) > 0 {
+ servers: [
+ for s in input.servers {
+ zones: [{
+ zone: s.zone
+ }]
+ port: 53
+ plugins: [{
+ name: "log"
+ }, {
+ name: "forward"
+ parameters: ". \(s.address)"
+ }, {
+ name: "health"
+ configBlock: "lameduck 5s"
+ }, {
+ name: "ready"
+ }]
+ }
+ ]
+ }
+ if len(input.servers) == 0 {
+ servers: [{
zones: [{
- zone: s.zone
+ zone: "."
}]
port: 53
plugins: [{
- name: "log"
- }, {
- name: "forward"
- parameters: ". \(s.address)"
- }, {
- name: "health"
- configBlock: "lameduck 5s"
- }, {
name: "ready"
}]
- }
- ]
- }
- if len(input.servers) == 0 {
- servers: [{
- zones: [{
- zone: "."
}]
- port: 53
- plugins: [{
- name: "ready"
- }]
- }]
+ }
+ livenessProbe: {
+ enabled: true
+ initialDelaySeconds: 60
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 5
+ successThreshold: 1
+ }
+ readinessProbe: {
+ enabled: true
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 5
+ successThreshold: 1
+ }
+ zoneFiles: []
+ hpa: enabled: false
+ autoscaler: enabled: false
+ deployment: enabled: true
}
- livenessProbe: {
- enabled: true
- initialDelaySeconds: 60
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 5
- successThreshold: 1
- }
- readinessProbe: {
- enabled: true
- initialDelaySeconds: 30
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 5
- successThreshold: 1
- }
- zoneFiles: []
- hpa: enabled: false
- autoscaler: enabled: false
- deployment: enabled: true
}
}
}
diff --git a/core/installer/values-tmpl/dodo-app-instance-status.cue b/core/installer/values-tmpl/dodo-app-instance-status.cue
index ad66153..b72a272 100644
--- a/core/installer/values-tmpl/dodo-app-instance-status.cue
+++ b/core/installer/values-tmpl/dodo-app-instance-status.cue
@@ -8,15 +8,17 @@
_subdomain: "status.\(input.appSubdomain)"
-ingress: {
- "status-\(input.appName)": {
- auth: enabled: false
- network: input.network
- subdomain: _subdomain
- appRoot: "/\(input.appName)"
- service: {
- name: "web"
- port: name: "http"
+out: {
+ ingress: {
+ "status-\(input.appName)": {
+ auth: enabled: false
+ network: input.network
+ subdomain: _subdomain
+ appRoot: "/\(input.appName)"
+ service: {
+ name: "web"
+ port: name: "http"
+ }
}
}
}
diff --git a/core/installer/values-tmpl/dodo-app-instance.cue b/core/installer/values-tmpl/dodo-app-instance.cue
index e0d6906..ad20ac7 100644
--- a/core/installer/values-tmpl/dodo-app-instance.cue
+++ b/core/installer/values-tmpl/dodo-app-instance.cue
@@ -5,6 +5,7 @@
input: {
repoAddr: string
repoHost: string
+ branch: string
gitRepoPublicKey: string
// TODO(gio): auto generate
fluxKeys: #SSHKey
@@ -58,7 +59,7 @@
}
spec: {
interval: "1m0s"
- ref: branch: "dodo"
+ ref: branch: input.branch
secretRef: name: "app"
timeout: "60s"
url: input.repoAddr
diff --git a/core/installer/values-tmpl/dodo-app.cue b/core/installer/values-tmpl/dodo-app.cue
index 07c2f1a..8bb57c0 100644
--- a/core/installer/values-tmpl/dodo-app.cue
+++ b/core/installer/values-tmpl/dodo-app.cue
@@ -52,57 +52,6 @@
_domain: "\(input.subdomain).\(input.network.domain)"
url: "https://\(_domain)"
-images: {
- softserve: {
- repository: "charmcli"
- name: "soft-serve"
- tag: "v0.7.1"
- pullPolicy: "IfNotPresent"
- }
- dodoApp: {
- repository: "giolekva"
- name: "pcloud-installer"
- tag: "latest"
- pullPolicy: "Always"
- }
-}
-
-charts: {
- softserve: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/soft-serve"
- }
- dodoApp: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/dodo-app"
- }
-}
-
-volumes: db: size: "10Gi"
-
-ingress: {
- "dodo-app": {
- auth: {
- if input.external {
- enabled: false
- }
- if !input.external {
- enabled: true
- }
- }
- network: input.network
- subdomain: input.subdomain
- service: {
- name: "web"
- port: name: "http"
- }
- }
-}
-
portForward: [#PortForward & {
allocator: input.network.allocatePortAddr
reservator: input.network.reservePortAddr
@@ -112,51 +61,106 @@
targetPort: 22
}]
-helm: {
- softserve: {
- chart: charts.softserve
- info: "Installing Git server"
- values: {
- serviceType: "ClusterIP"
- addressPool: ""
- reservedIP: ""
- adminKey: strings.Join([input.fluxKeys.public, input.dAppKeys.public], "\n")
- privateKey: input.ssKeys.private
- publicKey: input.ssKeys.public
- ingress: {
- enabled: false
+out: {
+ images: {
+ softserve: {
+ repository: "charmcli"
+ name: "soft-serve"
+ tag: "v0.7.1"
+ pullPolicy: "IfNotPresent"
+ }
+ dodoApp: {
+ repository: "giolekva"
+ name: "pcloud-installer"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
+ }
+
+ charts: {
+ softserve: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/soft-serve"
+ }
+ dodoApp: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/dodo-app"
+ }
+ }
+
+ volumes: {
+ "config-repo": size: "10Gi"
+ db: size: "10Gi"
+ }
+
+ ingress: {
+ "dodo-app": {
+ auth: {
+ if input.external {
+ enabled: false
+ }
+ if !input.external {
+ enabled: true
+ }
}
- image: {
- repository: images.softserve.fullName
- tag: images.softserve.tag
- pullPolicy: images.softserve.pullPolicy
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "web"
+ port: name: "http"
}
}
}
- "dodo-app": {
- chart: charts.dodoApp
- info: "Installing supervisor"
- values: {
- image: {
- repository: images.dodoApp.fullName
- tag: images.dodoApp.tag
- pullPolicy: images.dodoApp.pullPolicy
+
+ helm: {
+ softserve: {
+ chart: charts.softserve
+ info: "Installing Git server"
+ values: {
+ serviceType: "ClusterIP"
+ addressPool: ""
+ reservedIP: ""
+ adminKey: strings.Join([input.fluxKeys.public, input.dAppKeys.public], "\n")
+ privateKey: input.ssKeys.private
+ publicKey: input.ssKeys.public
+ image: {
+ repository: images.softserve.fullName
+ tag: images.softserve.tag
+ pullPolicy: images.softserve.pullPolicy
+ }
+ persistentVolumeClaimName: volumes["config-repo"].name
}
- clusterRoleName: "\(release.namespace)-dodo-app"
- port: 8080
- apiPort: 8081
- repoAddr: "soft-serve.\(release.namespace).svc.cluster.local:22"
- sshPrivateKey: base64.Encode(null, input.dAppKeys.private)
- self: "api.\(release.namespace).svc.cluster.local"
- repoPublicAddr: "ssh://\(_domain):\(input.sshPort)"
- namespace: release.namespace
- envAppManagerAddr: "http://appmanager.\(global.namespacePrefix)appmanager.svc.cluster.local"
- envConfig: base64.Encode(null, json.Marshal(global))
- gitRepoPublicKey: input.ssKeys.public
- persistentVolumeClaimName: volumes.db.name
- allowedNetworks: strings.Join([for n in input.allowedNetworks { n.name }], ",")
- external: input.external
- fetchUsersAddr: "http://memberships-api.\(global.namespacePrefix)core-auth-memberships.svc.cluster.local/api/users"
+ }
+ "dodo-app": {
+ chart: charts.dodoApp
+ info: "Installing supervisor"
+ values: {
+ image: {
+ repository: images.dodoApp.fullName
+ tag: images.dodoApp.tag
+ pullPolicy: images.dodoApp.pullPolicy
+ }
+ clusterRoleName: "\(release.namespace)-dodo-app"
+ port: 8080
+ apiPort: 8081
+ repoAddr: "soft-serve.\(release.namespace).svc.cluster.local:22"
+ sshPrivateKey: base64.Encode(null, input.dAppKeys.private)
+ self: "api.\(release.namespace).svc.cluster.local"
+ repoPublicAddr: "ssh://\(_domain):\(input.sshPort)"
+ namespace: release.namespace
+ envAppManagerAddr: "http://appmanager.\(global.namespacePrefix)appmanager.svc.cluster.local"
+ envConfig: base64.Encode(null, json.Marshal(global))
+ gitRepoPublicKey: input.ssKeys.public
+ persistentVolumeClaimName: volumes.db.name
+ allowedNetworks: strings.Join([for n in input.allowedNetworks { n.name }], ",")
+ external: input.external
+ fetchUsersAddr: "http://memberships-api.\(global.namespacePrefix)core-auth-memberships.svc.cluster.local/api/users"
+ headscaleAPIAddr: "http://headscale-api.\(global.namespacePrefix)app-headscale.svc"
+ }
}
}
}
diff --git a/core/installer/values-tmpl/env-dns.cue b/core/installer/values-tmpl/env-dns.cue
index adc8b3b..2b73ada 100644
--- a/core/installer/values-tmpl/env-dns.cue
+++ b/core/installer/values-tmpl/env-dns.cue
@@ -10,201 +10,203 @@
description: "Environment local DNS manager"
icon: ""
-images: {
- coredns: {
- repository: "coredns"
- name: "coredns"
- tag: "1.11.1"
- pullPolicy: "IfNotPresent"
+out: {
+ images: {
+ coredns: {
+ repository: "coredns"
+ name: "coredns"
+ tag: "1.11.1"
+ pullPolicy: "IfNotPresent"
+ }
+ api: {
+ repository: "giolekva"
+ name: "dns-api"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
- api: {
- repository: "giolekva"
- name: "dns-api"
- tag: "latest"
- pullPolicy: "Always"
- }
-}
-charts: {
- coredns: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/coredns"
+ charts: {
+ coredns: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/coredns"
+ }
+ api: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/dns-api"
+ }
+ service: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/service"
+ }
+ ipAddressPool: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/metallb-ipaddresspool"
+ }
}
- api: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/dns-api"
- }
- service: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/service"
- }
- ipAddressPool: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/metallb-ipaddresspool"
- }
-}
-volumes: data: {
- accessMode: "ReadWriteMany"
- size: "5Gi"
-}
+ volumes: data: {
+ accessMode: "ReadWriteMany"
+ size: "5Gi"
+ }
-helm: {
- coredns: {
- chart: charts.coredns
- values: {
- image: {
- repository: images.coredns.fullName
- tag: images.coredns.tag
- pullPolicy: images.coredns.pullPolicy
- }
- replicaCount: 1
- resources: {
- limits: {
- cpu: "100m"
- memory: "128Mi"
+ helm: {
+ coredns: {
+ chart: charts.coredns
+ values: {
+ image: {
+ repository: images.coredns.fullName
+ tag: images.coredns.tag
+ pullPolicy: images.coredns.pullPolicy
}
- requests: {
- cpu: "100m"
- memory: "128Mi"
- }
- }
- rollingUpdate: {
- maxUnavailable: 1
- maxSurge: "25%"
- }
- terminationGracePeriodSeconds: 30
- serviceType: "LoadBalancer"
- service: {
- name: "coredns"
- annotations: {
- "metallb.universe.tf/loadBalancerIPs": global.network.dns
- }
- }
- serviceAccount: create: false
- rbac: {
- create: false
- pspEnable: false
- }
- isClusterService: false
- servers: [{
- zones: [{
- zone: "."
- }]
- port: 53
- plugins: [
- {
- name: "log"
- },
- {
- name: "health"
- configBlock: "lameduck 5s"
- },
- {
- name: "ready"
+ replicaCount: 1
+ resources: {
+ limits: {
+ cpu: "100m"
+ memory: "128Mi"
}
- ]
- }]
- extraConfig: import: parameters: "\(_mountPath)/coredns.conf"
- extraVolumes: [{
- name: volumes.data.name
- persistentVolumeClaim: claimName: volumes.data.name
- }]
- extraVolumeMounts: [{
- name: volumes.data.name
- mountPath: _mountPath
- }]
- livenessProbe: {
- enabled: true
- initialDelaySeconds: 60
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 5
- successThreshold: 1
- }
- readinessProbe: {
- enabled: true
- initialDelaySeconds: 30
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 5
- successThreshold: 1
- }
- zoneFiles: []
- hpa: enabled: false
- autoscaler: enabled: false
- deployment: enabled: true
- }
- }
- api: {
- chart: charts.api
- values: {
- image: {
- repository: images.api.fullName
- tag: images.api.tag
- pullPolicy: images.api.pullPolicy
- }
- config: "coredns.conf"
- db: "records.db"
- zone: networks.public.domain
- publicIP: strings.Join(global.publicIP, ",")
- privateIP: global.network.ingress
- nameserverIP: strings.Join(global.nameserverIP, ",")
- service: type: "ClusterIP"
- volume: {
- claimName: volumes.data.name
- mountPath: _mountPath
+ requests: {
+ cpu: "100m"
+ memory: "128Mi"
+ }
+ }
+ rollingUpdate: {
+ maxUnavailable: 1
+ maxSurge: "25%"
+ }
+ terminationGracePeriodSeconds: 30
+ serviceType: "LoadBalancer"
+ service: {
+ name: "coredns"
+ annotations: {
+ "metallb.universe.tf/loadBalancerIPs": global.network.dns
+ }
+ }
+ serviceAccount: create: false
+ rbac: {
+ create: false
+ pspEnable: false
+ }
+ isClusterService: false
+ servers: [{
+ zones: [{
+ zone: "."
+ }]
+ port: 53
+ plugins: [
+ {
+ name: "log"
+ },
+ {
+ name: "health"
+ configBlock: "lameduck 5s"
+ },
+ {
+ name: "ready"
+ }
+ ]
+ }]
+ extraConfig: import: parameters: "\(_mountPath)/coredns.conf"
+ extraVolumes: [{
+ name: volumes.data.name
+ persistentVolumeClaim: claimName: volumes.data.name
+ }]
+ extraVolumeMounts: [{
+ name: volumes.data.name
+ mountPath: _mountPath
+ }]
+ livenessProbe: {
+ enabled: true
+ initialDelaySeconds: 60
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 5
+ successThreshold: 1
+ }
+ readinessProbe: {
+ enabled: true
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ timeoutSeconds: 5
+ failureThreshold: 5
+ successThreshold: 1
+ }
+ zoneFiles: []
+ hpa: enabled: false
+ autoscaler: enabled: false
+ deployment: enabled: true
}
}
- }
- "coredns-svc-cluster": {
- chart: charts.service
- values: {
- name: "dns"
- type: "LoadBalancer"
- protocol: "TCP"
- ports: [{
- name: "udp-53"
- port: 53
- protocol: "UDP"
- targetPort: 53
- }]
- targetPort: "http"
- selector:{
- "app.kubernetes.io/instance": "coredns"
- "app.kubernetes.io/name": "coredns"
- }
- annotations: {
- "metallb.universe.tf/loadBalancerIPs": global.network.dnsInClusterIP
+ api: {
+ chart: charts.api
+ values: {
+ image: {
+ repository: images.api.fullName
+ tag: images.api.tag
+ pullPolicy: images.api.pullPolicy
+ }
+ config: "coredns.conf"
+ db: "records.db"
+ zone: networks.public.domain
+ publicIP: strings.Join(global.publicIP, ",")
+ privateIP: global.network.ingress
+ nameserverIP: strings.Join(global.nameserverIP, ",")
+ service: type: "ClusterIP"
+ volume: {
+ claimName: volumes.data.name
+ mountPath: _mountPath
+ }
}
}
- }
- "ipaddresspool-dns": {
- chart: charts.ipAddressPool
- values: {
- name: "\(global.id)-dns"
- autoAssign: false
- from: global.network.dns
- to: global.network.dns
- namespace: "metallb-system"
+ "coredns-svc-cluster": {
+ chart: charts.service
+ values: {
+ name: "dns"
+ type: "LoadBalancer"
+ protocol: "TCP"
+ ports: [{
+ name: "udp-53"
+ port: 53
+ protocol: "UDP"
+ targetPort: 53
+ }]
+ targetPort: "http"
+ selector:{
+ "app.kubernetes.io/instance": "coredns"
+ "app.kubernetes.io/name": "coredns"
+ }
+ annotations: {
+ "metallb.universe.tf/loadBalancerIPs": global.network.dnsInClusterIP
+ }
+ }
}
- }
- "ipaddresspool-dns-in-cluster": {
- chart: charts.ipAddressPool
- values: {
- name: "\(global.id)-dns-in-cluster"
- autoAssign: false
- from: global.network.dnsInClusterIP
- to: global.network.dnsInClusterIP
- namespace: "metallb-system"
+ "ipaddresspool-dns": {
+ chart: charts.ipAddressPool
+ values: {
+ name: "\(global.id)-dns"
+ autoAssign: false
+ from: global.network.dns
+ to: global.network.dns
+ namespace: "metallb-system"
+ }
+ }
+ "ipaddresspool-dns-in-cluster": {
+ chart: charts.ipAddressPool
+ values: {
+ name: "\(global.id)-dns-in-cluster"
+ autoAssign: false
+ from: global.network.dnsInClusterIP
+ to: global.network.dnsInClusterIP
+ namespace: "metallb-system"
+ }
}
}
}
diff --git a/core/installer/values-tmpl/env-manager.cue b/core/installer/values-tmpl/env-manager.cue
index cf38521..dbde7de 100644
--- a/core/installer/values-tmpl/env-manager.cue
+++ b/core/installer/values-tmpl/env-manager.cue
@@ -12,37 +12,39 @@
name: "env-manager"
namespace: "env-manager"
-images: {
- envManager: {
- repository: "giolekva"
- name: "pcloud-installer"
- tag: "latest"
- pullPolicy: "Always"
+out: {
+ images: {
+ envManager: {
+ repository: "giolekva"
+ name: "pcloud-installer"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
-}
-charts: {
- envManager: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/env-manager"
+ charts: {
+ envManager: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/env-manager"
+ }
}
-}
-helm: {
- "env-manager": {
- chart: charts.envManager
- values: {
- repoIP: input.repoIP
- repoPort: input.repoPort
- repoName: input.repoName
- sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
- clusterRoleName: "\(global.pcloudEnvName)-env-manager"
- image: {
- repository: images.envManager.fullName
- tag: images.envManager.tag
- pullPolicy: images.envManager.pullPolicy
+ helm: {
+ "env-manager": {
+ chart: charts.envManager
+ values: {
+ repoIP: input.repoIP
+ repoPort: input.repoPort
+ repoName: input.repoName
+ sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
+ clusterRoleName: "\(global.pcloudEnvName)-env-manager"
+ image: {
+ repository: images.envManager.fullName
+ tag: images.envManager.tag
+ pullPolicy: images.envManager.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/fluxcd-reconciler.cue b/core/installer/values-tmpl/fluxcd-reconciler.cue
index 3e742ff..fde9396 100644
--- a/core/installer/values-tmpl/fluxcd-reconciler.cue
+++ b/core/installer/values-tmpl/fluxcd-reconciler.cue
@@ -3,32 +3,34 @@
name: "fluxcd-reconciler"
namespace: "fluxcd-reconciler"
-images: {
- fluxcdReconciler: {
- repository: "giolekva"
- name: "fluxcd-reconciler"
- tag: "latest"
- pullPolicy: "Always"
+out: {
+ images: {
+ fluxcdReconciler: {
+ repository: "giolekva"
+ name: "fluxcd-reconciler"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
-}
-charts: {
- fluxcdReconciler: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/fluxcd-reconciler"
+ charts: {
+ fluxcdReconciler: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/fluxcd-reconciler"
+ }
}
-}
-helm: {
- "fluxcd-reconciler": {
- chart: charts.fluxcdReconciler
- values: {
- image: {
- repository: images.fluxcdReconciler.fullName
- tag: images.fluxcdReconciler.tag
- pullPolicy: images.fluxcdReconciler.pullPolicy
+ helm: {
+ "fluxcd-reconciler": {
+ chart: charts.fluxcdReconciler
+ values: {
+ image: {
+ repository: images.fluxcdReconciler.fullName
+ tag: images.fluxcdReconciler.tag
+ pullPolicy: images.fluxcdReconciler.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/gerrit.cue b/core/installer/values-tmpl/gerrit.cue
index 91597da..4fc9eaf 100644
--- a/core/installer/values-tmpl/gerrit.cue
+++ b/core/installer/values-tmpl/gerrit.cue
@@ -32,76 +32,272 @@
<path class='cls-1' d='m20.91007091,3.11035315l-.40677547-.44522187c.00619982-.006201.47746668-.43902117.68457526-.67217354.1996669-.24555409.56179703-.8011513.56799921-.8073523l.50351019.32244483c-.02604351.02604351-.38817364.59404272-.62008623.86564032s-.71061876.71061876-.73046245.73666257h.00123949Zm2.60932297,17.51743602c-.01984369-.00619982-.40057565-.25175391-.60768422-.36213013-.22991143-.11154711-.46273235-.21699848-.69821676-.31624294l.35468845-1.01446206-1.48572655-.73046127-.47126449,1.43984054c-.29019943.00619982-1.18188444.08433271-2.50018743.63992992-1.58866109.66473157-2.79038804,1.69903731-2.80279005,1.70523714l-.23935309.20710857,1.0653084.03844552.03224451-.02604351c.006201-.01240201,1.18808545-.88548401,1.84785668-1.16948362.14882055-.0582892.34228763-.12277823.5493962-.16742357-.34848863.16742357-.73046127.37453214-.99461837.52335388-.32988562.1996669-.94253135.63248824-.96857486.65233193l-.31004312.21331076,1.12979743.02604351.03224451-.01240201c.0198425-.01240201,1.92474772-1.03306389,2.95781042-1.26001615l.32244512-.07813052c.23935427-.0582892.40677547-.10293454.69821676-.10293454.2579561,0,.60768422.03224333,1.13723792.11657604.65853175.09673235,1.09135073.2579561,1.09755291.26539778l.39437583.15502156-.5295537-.72302077-.01984369-.01240201.00868117-.00744404Zm-14.84982503-12.065638h-.05208702l-1.66059121,1.51797106v.04464652c-.02604351.43902117.12897805.85943932.42661916,1.18808545.29764111.32244512.69077626.50971119,1.12979683.52335269h.07069003c.87804233,0,1.5948621-.67837425,1.64074811-1.55021558.0374887-.90290667-.65442416-1.66979928-1.55641658-1.72507964l.00124067.00123949Zm-.07813112,3.02850045h-.06448843c-.19170127-.00438435-.37976864-.05320469-.5493962-.14261955.46794696.07532156.90835369-.24296393.98367584-.7109109.01272844-.07907552.01432452-.1595431.00474153-.23906095-.06419689-.46466491-.49097867-.79070078-.95617285-.73046127-.43424238.06072443-.75232622.4398538-.73666227.87804233-.0493023-.1478661-.0732039-.30301539-.07069003-.45886367l1.50556906-1.38279201c.74277694.07474203,1.29972245.71365481,1.27241697,1.45968304-.0345792.7442305-.65017228,1.32863287-1.39519402,1.32450399l.00620041.00247898Zm15.42526651-6.16117612l-.48490836-.32244512-.67837543.43902117-.65233193-.47126568-.497308.29764111.67217325.48490718-.69077508.44522217.49110818.29764111.66473157-.42041815.63992992.46506467.50971001-.28399961-.67217325-.48490718.69821912-.44646166Zm15.66337715,25.53267101c-.35468845-.34228645-.69077508-.68457526-1.04050557-1.03306389-.79630214-.80614711-1.57814907-1.62644429-2.34516705-2.46050124-.90996396-.98277224-1.78242858-1.99961393-2.61552279-3.04834414-.37553745-.46918054-.73095919-.95411256-1.06530722-1.45348322-.41339634-.64390149-.78257785-1.31514039-1.10499459-2.00908043-.34239052-.73667646-.66127566-1.48404945-.95617285-2.24099065.40057565.34228645.76890797.73046245,1.09755291,1.14344011.03224333-.35468845.07068885-.71061876.09673235-1.0727489l.03844552-.5295537c0-.05828802.01984369-.11037504-.01240201-.16122256-.02454382-.04479436-.05499414-.08608905-.09053253-.12277705-.19346707-.24555409-.43282134-.46506467-.66473157-.68457526-.31804304-.29794743-.64094706-.59066724-.96857486-.87804233l-.29764111-.2579561c-.04464534-.04464652-.09673235-.08433153-.14261955-.12277705-.05208702-.05208702-.07068885-.16122256-.09053253-.22571159l-.2579561-.79495029c1.00825987.47126568,1.83421518,1.22777045,2.60932297,2.00907925.00619982-.36213013.00619982-.71681977,0-1.0789499,0-.18726607,0-.37453214-.01240201-.56799921,0-.05208702.01240201-.16742357-.02604351-.21330958-.01984369-.03224451-.05208702-.05828802-.07068885-.09053253-.18106507-.19346707-.38817364-.35468964-.5878429-.51715169-.28399961-.23935309-.58164071-.45886367-.87184014-.67837425-.2579561-.19346707-.52335388-.38073314-.7875098-.56799921-.03224333-.02604351-.12897805-.06448902-.11037622-.09673354l.06448902-.13517905c.03844552-.05828802.02604351-.07069003.09053253-.04464652l.28399961.09673354c.66473157.2579561,1.2848178.60768422,1.8863022,1.00825987-.20820614-.74461962-.49853567-1.46378708-.86564032-2.1442583-.65563881-1.25890203-1.46959424-2.42878067-2.42205572-3.4811643-.62615595-.7038808-1.29947171-1.36435044-2.01528025-1.97683473-.36833232-.31004312-.7552641-.60768422-1.15583975-.87804233-.18726489-.12277705-.36833232-.24555409-.56799921-.36213013-.08433271-.04464593-.17486524-.09053253-.25175391-.15502156-.29764111-.23315267-.60024254-.46506467-.90408584-.70441776.39437583.16122256.77510779.34228763,1.13723792.55559721-.20710857-.32244512-.56179703-.5493962-.89788365-.71681977-.51418543-.25650845-1.05045934-.46611966-1.60230259-.62628724.18726489-.19966778.38817364-.38073285.57544089-.57544001.18726489-.19966778.36833232-.40677665.5431952-.62008623.21331076-.24555409.42041934-.49110818.62008623-.74906398l-2.70605533-1.69903628c-.1996669.4005758-.45886485.78130865-.7552641,1.12359627-.29764111.33608662-.64612974.60768452-.99461837.89168413-.31004312.2579558-.62628724.51715199-.93012935.77510779-.08433153.07068973-.15502156.14261984-.24555409.19966778-.03844552.03844522-.15502156.006201-.20710857.006201h-.39437464c-.49110818.01240171-.98221636.05208731-1.47332454.11657634-.09673354.006201-.18726607.0198428-.29020061.01240171l-.29020061-.0198428c-.22571159-.01240171-.45266266-.02604351-.67837425-.02604351-.47746668-.006201-.95617285,0-1.43984054.03844522-.40456023.03341748-.80618022.09600232-1.20172695.18726607-.39394768.09978762-.76465136.27545061-1.09135191.51715199-.32244512.23315267-.63992873.5295537-.83339581.87804233-.19346707.34228763-.28399961.74906428-.35468964,1.13723792-.21951058.0198425-.43902117.0198425-.65853175.02604351-.67978583.03606293-1.3523068.15773294-2.00163816.36213013-.81508789.25388636-1.56763764.67642986-2.20874732,1.24017246-.32830018.30005267-.62690964.63105596-.89168383.98841737-.03224451.03844552-.06448902.08433153-.10293425.11037563-.0198428.01240201-.04464623.02604351-.05828802.04464652-.02450449.04328876-.05272095.08436938-.08433182.12277705l-.21951058.35468964c-.2777986.47126568-.45886367.98221636-.63248794,1.49812856l-.07813082.19966808.05828802-.03224451c-.01893831.1114525-.03383025.22355549-.04464623.33608662l-.01240171.16742357v.09053253l-.11037533.0198425c-.2219529.04571925-.44169382.10158624-.6585316.16742357-.19552693.05895389-.38235909.14361185-.55559735.25175509-.17486436.10293454-.32244483.25175509-.47126553.39437464-.53470711.51039244-.92674,1.15166711-1.13723814,1.86025869C-.00047122,14.62163461-.05875932,15.26032385.07021861,15.84816557c.03224448.14882055.07813087.31004312.17486431.43282016.12277708.14882055.32988588.20710857.51715187.15502156.21951051-.05828802.41297744-.19966808.61388537-.30384211l.52335269-.26539659c.74906398-.36833114,1.53781386-.73666227,2.37741068-.86564032.05828802-.006201.16122256.11037504.21330958.14882055.08433182.06448902.16742327.12277705.24555409.17486406.18106507.11657604.36833114.21330958.55559721.29764111.43282016.18726607.89168383.29020061,1.35054809.38073314.83339581.17486406,1.67919363.28399961,2.53243194.29764111.34228763.006201.68457526,0,1.03306389-.02604351.36833114-.03224451.74286328-.08433153,1.11739542-.08433153.41297766-.006201.81975431.03844552,1.22777045.09053253.42041815.05208702.83959681.11037504,1.26001497.17486406.85943932.12897805,1.70523714.2777986,2.55103495.45886367-.18726607.29764111-.37453214.60024373-.55559721.90408584-.01240201.0198425-.12277705,0-.14882055,0-.06889702-.00619746-.13821155-.00619746-.20710857,0-.12277705,0-.25175509.01240201-.37453214.03224451-.34628049.04689132-.68643449.13130683-1.01446088.25175509-.81355331.30384211-1.55641658.8011513-2.19634532,1.38279201-.36833114.32244512-.71061876.67217325-1.00825987,1.0591074-.07769174.10364181-.15294943.20908372-.22571159.31624294.16742357-.03844552.34848863-.07068885.52335269-.11657604.10293454-.02604351.19346707-.04464534.29020061-.06448902.03224451-.01240201.04464652-.02604351.08433153-.04464534.36033003-.33479036.74230148-.64550526,1.14343892-.93012935.18726607-.12897805.37453214-.25175391.58164071-.35468845.2715976-.13517787.58164071-.21331076.87804233-.28399961-.5431952.29764111-1.12359642.57544089-1.6147046.96237268-.28399961.23315208-.5431952.48490836-.81355331.73046245l1.0851509-.17486524c.01240201,0,.0198425-.00619982.03844552-.01984369l.2777986-.15502156c.18726607-.10293454.38073314-.20710857.57543971-.30384329.39437464-.20710857.79495029-.40057565,1.20792795-.56179703.39437464-.15502156.79495029-.29764111,1.21412895-.37453214.36213013-.07813052.70441776-.08433271,1.0727489,0,.56179821.12277823,1.10499341.38073196,1.60230259.68457526.03224451.02604351.05828802.0582892.09053253.02604351.02604351-.02604351.16122256-.12277823.14882055-.15502156l-.29764111-.54939738c-.02604351-.05208702-.03844552-.08433271-.08433153-.11037622l-.21951058-.12897805c-.28953356-.16791321-.56980641-.3513106-.83959681-.5493962-.06448902-.03844552-.12897805-.06448902-.13517905-.14882055-.01240201-.07069003.0198425-.14882055.04464652-.21951058.05208702-.14882055.12897805-.28399961.21330958-.41297766.05828802-.09673354.12277705-.18106507.18106507-.2715976.02604351-.03224451.0198425-.03844552.05208702-.02604351l.19966808.05828802c.38817364.12897805.77510779.26539659,1.17568344.36213013.44522217.11657604.89788483.20710857,1.35674969.29020061l.07813052.0198425c-.09053253-.05208702-.14882174-.14882055-.21951058-.22571159-.03844552-.05208702-.0582892-.08433153-.12277823-.09673354l-.17486524-.03844552c-.12277823-.02604351-.23935427-.04464652-.36833232-.07813052-.43511464-.0892824-.86422461-.20567275-1.28481898-.34848863-.62132927-.20887792-1.25299907-.38562961-1.89250321-.5295537-.8031773-.17243002-1.610817-.32337238-2.4220569-.45266266-.41297766-.07069003-.82719481-.12277705-1.24017246-.18106507-.40961518-.06287106-.82115347-.11250393-1.23397146-.14882055-.89168383-.05208702-1.77592716.14882055-2.673812.13517905-.60024373-.006201-1.21412895-.09053253-1.80817168-.17486406l-.11657604-.01240201c.42041815-.15502156.82719481-.31004312,1.24017246-.47126568.39437464-.15502156.78130879-.31624412,1.16948243-.47746668.20710857-.08433153.41297766-.17486406.61388523-.2579561.18726607-.08433153.37453214-.16742357.5431952-.28399961.67837425-.45886367,1.11739542-1.20172695,1.6147046-1.83421518.45266266-.59404272.96857486-1.15584093,1.63454711-1.49812856.21330958-.11037504.43282016-.19346707.66473275-.2579561-.47126568-.72302077-.91028684-1.53781357-1.03306389-2.40345389l.15502156.05828802c.05828802.0198425.11037504.02604351.12277705.07813112l.04464652.21950999c.04464652.14882055.09053253.29020061.14261955.43282016.12277705.31624412.26539659.62008623.43282016.91028684.36978352.65215334.79332405,1.27232236,1.26621597,1.85405769.89168383,1.13723792,1.89250321,2.1578998,2.86851856,3.21080619.23935309.2579561.45886367.5357547.67837425.81355331.25175509.31004312.50351019.62008623.7552641.92392834.1996669.23315208.38817364.47126568.5878429.70441776l.15502156.18726607c.02604351.03224451.06448902.04464652.10293454.05828802,1.00081819.49730919,2.00908043.99461837,3.00989862,1.47952673.72302077.34848863,1.43983936.69821676,2.17030181,1.03306389.38817364.18106507.77510779.36213013,1.17568344.5295537.04464534.01984369.10293454.04464534.16122138.06448902.02604351.01240201.04464534.02604351.07813052.03844552l.02604351.07813052c.04464534.12277823.08433271.23935427.12277823.36213013.08433271.23315208.16122138.45886485.24555409.68457526.54939738,1.51177006,1.14963993,3.00369643,1.89250202,4.42493633.578322,1.08265063,1.1791086,2.15315236,1.80196949,3.21080737.66473157,1.12359642,1.343107,2.23479083,2.02768226,3.34598525.54939738.88548401,1.09755291,1.77592598,1.66679162,2.65521017.23935427.37453214.47746668.76270578.72302077,1.13723792l.10293454.15502156,1.60230259-2.35136687c.01240201-.01240201.13517787-.16742357.12277823-.18106507l-.2579561-.40057565c-.47746668-.74286209-.96237268-1.48572655-1.43983936-2.22859101l-1.54401576-2.39601221,1.0851509,1.31830299,1.84785668,2.23479083c.1996669.23935427.38817364.47746668.58164071.72302077.36213013-.66473157.73046245-1.32450517,1.09755291-1.98303692.14261955-.2715976.29019943-.54939738.4390188-.81355331l-.00495796-.01239964ZM20.05063278,1.84413718c.50971001-.40677665.93012935-.93012935,1.25257447-1.49812827l1.95079123,1.23397175.29764111.18106507c-.40677547.49730919-.81975313,1.00081908-1.2848178,1.44728133-.06097634.05293118-.11933415.10880527-.17486524.16742327-.03224333.04464623-.07813052.08433182-.11657604.12277705l-.05208702.06448902c-.03844552-.01240171-.07813052-.02604351-.11657604-.03224451-.23935427-.06448902-.47746668-.12897805-.71681859-.18106507-.48385337-.10967516-.97316382-.19371042-1.46588405-.25175509-.31624412-.03844522-.63992873-.06448902-.95617285-.09673354.45266266-.38817394.91772734-.77510779,1.38279319-1.15584064l-.00000237-.00124038Zm-2.90076426,2.26703535c.38817364-.16122256.8011513-.24555409,1.20792795-.31624412.81333332-.13418557,1.6412555-.15588524,2.46050242-.06448902.5878429.06448902,1.16328143.17486406,1.72508082.34848863l-.23315208.18726607-.37453214-.10293454c-.23315208-.04464593-.46506467-.09673354-.69821676-.13517905-.41077543-.06070432-.8250115-.09508601-1.24017246-.10293454-.76375012-.01441855-1.52604905.07231982-2.26703535.2579561-.50273314.13067111-.99001049.31485561-1.45348204.5493962-.47126568.2579561-.91772734.57543971-1.28481898.96237386-.22622016.22823196-.4255346.4816405-.59404272.75526528-.09673354.14882055-.17486406.29764111-.25175509.45266266-.03753719.07754153-.06985385.15750409-.09673354.23935309l-.05208702.12277705c-.00516494.02191581-.01179409.04346025-.0198425.06448902l-.11037504-.0198425-.13517905-.01240201c.38817364-1.19552594,1.26001497-2.13185629,2.34516587-2.73210002.34228763-.18726607.70441776-.35468964,1.0727489-.45886367l-.00000118.00496151Zm-6.49726393.61388523c.43902117-.63248824,1.13723792-1.0727489,1.8863022-1.23397146.8271948-.16122256,1.67919363-.19346678,2.51879044-.17486436-.86564032.21951058-1.73748165.54319549-2.46050242,1.0789502-.56594483.12955226-1.09433828.38801929-1.54401457.75526528-.14516831.12120698-.28113388.2530277-.40677665.39437464-.0588983.06001006-.11281735.12471257-.16122256.19346707-.0198425.0198425-.04464652.04464593-.05828802.07813112h-.14261955c.03844552-.21951058.09053253-.44522217.16122256-.65853175.05208702-.14882055.11037504-.29764111.19966808-.43282016l.0074405-.00000059Zm1.45348204.09673354c-.23729515.23928035-.45347638.49861373-.64612974.77510779-.07813052.11037563-.16122256.25175509-.29764111.31004312-.14261955.06448902-.32244512-.006201-.46506467-.04464593.37108569-.46297185.85614544-.82153135,1.40759603-1.04050497h.00123949ZM3.81181355,9.56917155c.12897805-.26539659.2976414-.52335269.45266296-.76890678.02604351-.04464652.09053253-.07813052.12277705-.10293454.08433182-.05828802.16122227-.11657604.23935338-.18106507.5097106-.36833114,1.02686288-.73666227,1.55021558-1.0789499.2777986-.18106507.5493962-.35468964.83339581-.50971119.29764111-.16742357.60768481-.29764111.93012935-.40677665.57867031-.17905976,1.17035173-.31298572,1.76972616-.40057565.28399902-.03844552.59404213-.09673354.87804174-.02604351-.5493962.31004312-1.09135191.62008623-1.64074811.92392834-.56179821.31624412-1.13723792.60768422-1.71143814.91028684-.5493962.29764111-1.09135191.62008623-1.62090561.95617285-.55559721.34228763-1.1049937.69077626-1.65314982,1.04050438-.13517876.08433153-.26539689.17486406-.40057565.2579561.07813082-.20710857.14882055-.42041815.25175509-.61388523h-.00123979Zm1.66679162,5.05122238c-.04464593.09053253-.21951058.07069003-.31004312.07069003-.15502156,0-.30384211,0-.45886367.006201-.42560113.02528184-.8463806.10360514-1.25257417.23315208-.7875095.23935309-1.52417192.62008623-2.26083434.99461837-.16122241.09053253-.33608677.22571159-.52335277.2715976-.10319415.02663487-.21197917-.01459359-.27159775-.10293454-.05594793-.10200492-.09094479-.2141635-.10293432-.32988562-.04154617-.19982775-.06109201-.40360223-.05828809-.60768422,0-.5493962.12897794-1.09135191.35468934-1.58866109.16122241-.34848863.36833121-.66473275.61388537-.94997185.25175502-.29020061.54319557-.58164071.89168405-.74286328.58784172-.2715976,1.28481869-.35468964,1.92474772-.38817364.12277705-.01240201.23935338-.01240201.36213043-.01240201.16122256,0,.35468934-.02604351.5097109.03224451.12277734.04464652.19966778.17486406.2517548.28399961.07069003.17486406.12277705.37453214.16122256.55559721.10293454.43282016.20710857.86564032.23935309,1.31086249.0198425.19346707.03224451.39437464.006201.58784172-.01240201.12277705-.0198425.2579561-.07813112.37453214l.00124008.00123949Zm4.67669024-3.26785472c-.32191467.20096789-.6640036.36764871-1.02066188.49730919-.35418402.1315481-.71942294.2311592-1.09135191.29764111-.16122256.0198425-.32244512.04464652-.48490718.03224451-.16742357,0-.31624412-.05828802-.48490718-.11037504-.32637412-.09433498-.64220606-.22191387-.94253135-.38073314-.11292439-.06073625-.21015763-.14693057-.28399961-.25175509-.04557969-.08727414-.05918097-.18774744-.03844552-.28399961.0198425-.38073314.15502156-.75526528.33608662-1.09135191.31004312-.56799921.79495029-1.01446088,1.38899302-1.28481898,1.45348204-.65233074,3.08058865-.04464652,4.31456011.81355331l.13517905.09673354c-.2579561.2777986-.51715169.5357547-.78130879.79495029-.32988562.31004312-.67217325.62628724-1.05290639.87184133l.006201-.00123949Zm3.57789784-3.18476268c-.78077184-.34143075-1.53056113-.74972779-2.24099184-1.22032996.74286328.31004312,1.54401457.49730919,2.33772537.61388523.42661916.05828802.86564032.11657604,1.29225948.12897805.46506467.0198425.93633035-.03224451,1.38899302-.12277705.90408584-.16742357,1.76972616-.50351019,2.59071996-.91028684.82099498-.40677665,1.59486092-.88548283,2.33772537-1.42123753.35468845-.25175509.71061876-.51715169,1.04670539-.8011513.03224333-.02604351.28399961-.2715976.30384329-.2579561l.06448902.05208702.89168383.69077626c.5431952.42041815,1.0851509.83959681,1.63454829,1.26001497-1.50363058.54005862-3.02220601,1.03756828-4.55391438,1.49192756-.8594405.2579561-1.71143814.49730919-2.58327947.69821735-.68457526.16122256-1.38279201.31004252-2.07976928.34228704-.83959681.03844552-1.66059061-.21951058-2.42825791-.54319579l-.00248017-.0012389Zm14.63031445,6.51710643c.12897805.03224451.24555409.07813052.35468845.11037504l.16122138.05828802c.02604351.006201.04464534.02604351.07068885.03224451l.03224333.09673354c.07813052.24555409.14882174.47746668.23315208.71681977-.24555409-.21330958-.497308-.42041815-.74286209-.62628724l-.14882174-.12277705c-.03844552-.02604351-.07813052-.03844552-.05208702-.07813052l.09673235-.18726607h-.0049556Zm-1.10499459,2.38361139l.0582892-.10293454.04464534-.07069003c.01984369-.03224451.01240201-.03844552.05208702-.0198425.21331076.08433153.42661916.18106507.63248824.2777986.40057565.18106507.7875098.38073314,1.16328143.60024373.18106507.11037504.36213013.22571159.53575352.34228763l.24555409.17486406.12277823.09053253c.05208702.04464652.07068885.10293454.09673235.16742238.16742357.46506467.36213013.93632917.55559721,1.39519402.12897805.31624294.2715976.62628605.41297766.93632917-.49014545-.60819752-1.01871039-1.18440245-1.58245891-1.72508082-.56908259-.56757817-1.16417557-1.10845996-1.78336766-1.62090561l-.53575352-.43902117-.0186042-.00619746Zm6.21450381,10.62579745l-.1996669.14882174.01240201.02604351.10293454.15502156.45266266.69077508,1.49192637,2.31912354c.51715169.79495148,1.0268617,1.59486092,1.54401576,2.38981239l.50971001.79495148.13517787.21951058c.02113995.02331852.03869389.04964825.05208702.07813052-.43282134.63248824-.86564032,1.27241579-1.29846167,1.90490403-.04464534.0582892-.08433271.12277823-.12277823.18106507-.39437583-.61388641-.7875098-1.22777045-1.18188326-1.84785668-.65853175-1.04670539-1.31086131-2.11201261-1.95699105-3.16492018-.7160782-1.16891354-1.41396616-2.3488737-2.09341078-3.53945232-.63248824-1.11739423-1.24017246-2.25463452-1.74988247-3.43651778-.4903607-1.15152755-.93632207-2.32145824-1.33690482-3.50720899.8011513.32244512,1.62090442.60768422,2.44810159.86564032.23935427.07068885.47746668.14882174.71681859.20710857l.10293454.03224333c.01240201,0,.02604351-.06448902.03224333-.08433271.03224333-.10293454.05208702-.21331076.07813052-.32244512.04464534-.20710857.08433271-.42041934.11657604-.62628605.34228645.70441894.72302077,1.39519402,1.16328143,2.04132376.35468845.52335388.73666227,1.0268617,1.13723792,1.52417207.8640815,1.08055958,1.76924361,2.12762215,2.71349701,3.13887667.76890797.81355331,1.54401576,1.6283461,2.33152319,2.42205572l.63992992.63992992c.01240201.01240201.06448902.05208702.06448902.07068885l-.05208702.08433271-.24555409.45886485-.97477468,1.76352634c-.29764111-.36213013-.59404272-.71681859-.89168383-1.0851509l-1.86025869-2.25463452c-.52335388-.63992992-1.05290757-1.27861798-1.57625909-1.9185479l-.31004312-.36833232.00496033-.00123713Z'/>
</svg>"""
-ingress: {
- gerrit: {
- auth: enabled: false
- network: input.network
- subdomain: input.subdomain
- service: {
- name: "gerrit-gerrit-service"
- port: number: _httpPort // TODO(gio): make optional
+out: {
+ ingress: {
+ gerrit: {
+ auth: enabled: false
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "gerrit-gerrit-service"
+ port: number: _httpPort // TODO(gio): make optional
+ }
}
}
-}
-// TODO(gio): configure busybox
-_images: {
- gerrit: #Image & {
- repository: "k8sgerrit"
- name: "gerrit"
- tag: _version
- pullPolicy: "Always"
+ // TODO(gio): configure busybox
+ images: {
+ gerrit: {
+ repository: "k8sgerrit"
+ name: "gerrit"
+ tag: _version
+ pullPolicy: "Always"
+ }
+ gerritInit: {
+ repository: "k8sgerrit"
+ name: "gerrit-init"
+ tag: _version
+ pullPolicy: "Always"
+ }
+ gitGC: {
+ repository: "k8sgerrit"
+ name: "git-gc"
+ tag: _version
+ pullPolicy: "Always"
+ }
}
- gerritInit: #Image & {
- repository: "k8sgerrit"
- name: "gerrit-init"
- tag: _version
- pullPolicy: "Always"
- }
- gitGC: #Image & {
- repository: "k8sgerrit"
- name: "git-gc"
- tag: _version
- pullPolicy: "Always"
- }
-}
-images: _images
+ _images: images
-charts: {
- ingress: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/ingress"
+ charts: {
+ ingress: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/ingress"
+ }
+ gerrit: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/gerrit"
+ }
+ oauth2Client: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/oauth2-client"
+ }
+ resourceRenderer: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/resource-renderer"
+ }
}
- gerrit: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/gerrit"
- }
- oauth2Client: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/oauth2-client"
- }
- resourceRenderer: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/resource-renderer"
- }
-}
-volumes: {
- git: {
- accessMode: "ReadWriteMany"
- size: "50Gi"
+ volumes: {
+ git: {
+ accessMode: "ReadWriteMany"
+ size: "50Gi"
+ }
+ logs: {
+ accessMode: "ReadWriteMany"
+ size: "5Gi"
+ }
}
- logs: {
- accessMode: "ReadWriteMany"
- size: "5Gi"
+
+ helm: {
+ "oauth2-client": {
+ chart: charts.oauth2Client
+ info: "Creating OAuth2 client"
+ values: {
+ name: "\(release.namespace)-gerrit"
+ secretName: _oauth2ClientCredentials
+ grantTypes: ["authorization_code"]
+ scope: "openid profile email"
+ hydraAdmin: "http://hydra-admin.\(global.id)-core-auth.svc.cluster.local"
+ redirectUris: ["https://\(_domain)/oauth"]
+ }
+ }
+ "config-renderer": {
+ chart: charts.resourceRenderer
+ info: "Generating Gerrit configuration"
+ values: {
+ name: "config-renderer"
+ secretName: _oauth2ClientCredentials
+ resourceTemplate: """
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: \(_gerritConfigMapName)
+ namespace: \(release.namespace)
+ data:
+ replication.config: |
+ [gerrit]
+ autoReload = false
+ replicateOnStartup = true
+ defaultForceUpdate = true
+ gerrit.config: |
+ [gerrit]
+ basePath = git # FIXED
+ serverId = gerrit-1
+ # The canonical web URL has to be set to the Ingress host, if an Ingress
+ # is used. If a LoadBalancer-service is used, this should be set to the
+ # LoadBalancer's external IP. This can only be done manually after installing
+ # the chart, when you know the external IP the LoadBalancer got from the
+ # cluster.
+ canonicalWebUrl = https://\(_domain)
+ disableReverseDnsLookup = true
+ [index]
+ type = LUCENE
+ [auth]
+ type = OAUTH
+ gitBasicAuthPolicy = HTTP
+ userNameToLowerCase = true
+ userNameCaseInsensitive = true
+ [plugin "gerrit-oauth-provider-pcloud-oauth"]
+ root-url = https://hydra.\(networks.public.domain)
+ client-id = "{{ .client_id }}"
+ client-secret = "{{ .client_secret }}"
+ link-to-existing-openid-accounts = true
+ [download]
+ command = branch
+ command = checkout
+ command = cherry_pick
+ command = pull
+ command = format_patch
+ command = reset
+ scheme = http
+ scheme = anon_http
+ [httpd]
+ # If using an ingress use proxy-http or proxy-https
+ listenUrl = proxy-http://*:8080/
+ requestLog = true
+ gracefulStopTimeout = 1m
+ [sshd]
+ listenAddress = 0.0.0.0:29418
+ advertisedAddress = \(_domain):\(input.sshPort)
+ [transfer]
+ timeout = 120 s
+ [user]
+ name = Gerrit Code Review
+ email = gerrit@\(networks.public.domain)
+ anonymousCoward = Unnamed User
+ [cache]
+ directory = cache
+ [container]
+ user = gerrit # FIXED
+ javaHome = /usr/lib/jvm/java-11-openjdk # FIXED
+ javaOptions = -Djavax.net.ssl.trustStore=/var/gerrit/etc/keystore # FIXED
+ javaOptions = -Xms200m
+ # Has to be lower than 'gerrit.resources.limits.memory'. Also
+ # consider memories used by other applications in the container.
+ javaOptions = -Xmx4g
+ """
+ }
+ }
+ gerrit: {
+ chart: charts.gerrit
+ info: "Installing Gerrit server"
+ values: {
+ images: {
+ busybox: {
+ registry: _dockerIO
+ tag: "latest"
+ }
+ registry: {
+ name: _dockerIO
+ ImagePullSecret: create: false
+ imagePullPolicy: "Always"
+ }
+ version: _version
+ }
+ storageClasses: {
+ default: {
+ name: _longhorn
+ create: false
+ }
+ shared: {
+ name: _longhorn
+ create: false
+ }
+ }
+ persistence: {
+ enabled: true
+ size: "10Gi"
+ }
+ nfsWorkaround: {
+ enabled: false
+ chownOnStartup: false
+ idDomain: _domain
+ }
+ networkPolicies: enabled: false
+ gitRepositoryStorage: {
+ externalPVC: {
+ use: true
+ name: volumes.git.name
+ }
+ }
+ logStorage: {
+ enabled: true
+ externalPVC: {
+ use: true
+ name: volumes.logs.name
+ }
+ }
+ ingress: enabled: false
+ gitGC: {
+ image: _images.gitGC.imageName
+ logging: persistence: enabled: false
+ }
+ gerrit: {
+ images: {
+ gerritInit: _images.gerritInit.imageName
+ gerrit: _images.gerrit.imageName
+ }
+ service: {
+ type: "LoadBalancer"
+ externalTrafficPolicy: ""
+ additionalAnnotations: {
+ "metallb.universe.tf/address-pool": global.id
+ }
+ http: port: _httpPort
+ ssh: {
+ enabled: true
+ port: _sshPort
+ }
+ }
+ pluginManagement: {
+ plugins: [{
+ name: "gitiles"
+ }, {
+ name: "download-commands"
+ }, {
+ name: "singleusergroup"
+ }, {
+ name: "codemirror-editor"
+ }, {
+ name: "reviewnotes"
+ }, {
+ name: "oauth"
+ url: "https://drive.google.com/uc?export=download&id=1rSUpZCAVvHZTmRgUl4enrsAM73gndjeP"
+ sha1: "cbdc5228a18b051a6e048a8e783e556394cc5db1"
+ }, {
+ name: "webhooks"
+ }]
+ libs: []
+ cache: enabled: false
+ }
+ etc: {
+ secret: {
+ ssh_host_ecdsa_key: input.key.private
+ "ssh_host_ecdsa_key.pub": input.key.public
+ }
+ existingConfigMapName: _gerritConfigMapName
+ }
+ }
+ }
+ }
}
}
@@ -124,197 +320,3 @@
_oauth2ClientCredentials: "gerrit-oauth2-credentials"
_gerritConfigMapName: "gerrit-config"
-
-helm: {
- "oauth2-client": {
- chart: charts.oauth2Client
- info: "Creating OAuth2 client"
- values: {
- name: "\(release.namespace)-gerrit"
- secretName: _oauth2ClientCredentials
- grantTypes: ["authorization_code"]
- scope: "openid profile email"
- hydraAdmin: "http://hydra-admin.\(global.id)-core-auth.svc.cluster.local"
- redirectUris: ["https://\(_domain)/oauth"]
- }
- }
- "config-renderer": {
- chart: charts.resourceRenderer
- info: "Generating Gerrit configuration"
- values: {
- name: "config-renderer"
- secretName: _oauth2ClientCredentials
- resourceTemplate: """
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: \(_gerritConfigMapName)
- namespace: \(release.namespace)
-data:
- replication.config: |
- [gerrit]
- autoReload = false
- replicateOnStartup = true
- defaultForceUpdate = true
- gerrit.config: |
- [gerrit]
- basePath = git # FIXED
- serverId = gerrit-1
- # The canonical web URL has to be set to the Ingress host, if an Ingress
- # is used. If a LoadBalancer-service is used, this should be set to the
- # LoadBalancer's external IP. This can only be done manually after installing
- # the chart, when you know the external IP the LoadBalancer got from the
- # cluster.
- canonicalWebUrl = https://\(_domain)
- disableReverseDnsLookup = true
- [index]
- type = LUCENE
- [auth]
- type = OAUTH
- gitBasicAuthPolicy = HTTP
- userNameToLowerCase = true
- userNameCaseInsensitive = true
- [plugin "gerrit-oauth-provider-pcloud-oauth"]
- root-url = https://hydra.\(networks.public.domain)
- client-id = "{{ .client_id }}"
- client-secret = "{{ .client_secret }}"
- link-to-existing-openid-accounts = true
- [download]
- command = branch
- command = checkout
- command = cherry_pick
- command = pull
- command = format_patch
- command = reset
- scheme = http
- scheme = anon_http
- [httpd]
- # If using an ingress use proxy-http or proxy-https
- listenUrl = proxy-http://*:8080/
- requestLog = true
- gracefulStopTimeout = 1m
- [sshd]
- listenAddress = 0.0.0.0:29418
- advertisedAddress = \(_domain):\(input.sshPort)
- [transfer]
- timeout = 120 s
- [user]
- name = Gerrit Code Review
- email = gerrit@\(networks.public.domain)
- anonymousCoward = Unnamed User
- [cache]
- directory = cache
- [container]
- user = gerrit # FIXED
- javaHome = /usr/lib/jvm/java-11-openjdk # FIXED
- javaOptions = -Djavax.net.ssl.trustStore=/var/gerrit/etc/keystore # FIXED
- javaOptions = -Xms200m
- # Has to be lower than 'gerrit.resources.limits.memory'. Also
- # consider memories used by other applications in the container.
- javaOptions = -Xmx4g
-"""
- }
- }
- gerrit: {
- chart: charts.gerrit
- info: "Installing Gerrit server"
- values: {
- images: {
- busybox: {
- registry: _dockerIO
- tag: "latest"
- }
- registry: {
- name: _dockerIO
- ImagePullSecret: create: false
- imagePullPolicy: "Always"
- }
- version: _version
- }
- storageClasses: {
- default: {
- name: _longhorn
- create: false
- }
- shared: {
- name: _longhorn
- create: false
- }
- }
- persistence: {
- enabled: true
- size: "10Gi"
- }
- nfsWorkaround: {
- enabled: false
- chownOnStartup: false
- idDomain: _domain
- }
- networkPolicies: enabled: false
- gitRepositoryStorage: {
- externalPVC: {
- use: true
- name: volumes.git.name
- }
- }
- logStorage: {
- enabled: true
- externalPVC: {
- use: true
- name: volumes.logs.name
- }
- }
- ingress: enabled: false
- gitGC: {
- image: _images.gitGC.imageName
- logging: persistence: enabled: false
- }
- gerrit: {
- images: {
- gerritInit: _images.gerritInit.imageName
- gerrit: _images.gerrit.imageName
- }
- service: {
- type: "LoadBalancer"
- externalTrafficPolicy: ""
- additionalAnnotations: {
- "metallb.universe.tf/address-pool": global.id
- }
- http: port: _httpPort
- ssh: {
- enabled: true
- port: _sshPort
- }
- }
- pluginManagement: {
- plugins: [{
- name: "gitiles"
- }, {
- name: "download-commands"
- }, {
- name: "singleusergroup"
- }, {
- name: "codemirror-editor"
- }, {
- name: "reviewnotes"
- }, {
- name: "oauth"
- url: "https://drive.google.com/uc?export=download&id=1rSUpZCAVvHZTmRgUl4enrsAM73gndjeP"
- sha1: "cbdc5228a18b051a6e048a8e783e556394cc5db1"
- }, {
- name: "webhooks"
- }]
- libs: []
- cache: enabled: false
- }
- etc: {
- secret: {
- ssh_host_ecdsa_key: input.key.private
- "ssh_host_ecdsa_key.pub": input.key.public
- }
- existingConfigMapName: _gerritConfigMapName
- }
- }
- }
- }
-}
diff --git a/core/installer/values-tmpl/headscale-controller.cue b/core/installer/values-tmpl/headscale-controller.cue
index a2e3f22..7d61ac2 100644
--- a/core/installer/values-tmpl/headscale-controller.cue
+++ b/core/installer/values-tmpl/headscale-controller.cue
@@ -3,46 +3,48 @@
name: "headscale-controller"
namespace: "core-headscale"
-images: {
- headscaleController: {
- repository: "giolekva"
- name: "headscale-controller"
- tag: "latest"
- pullPolicy: "Always"
+out: {
+ images: {
+ headscaleController: {
+ repository: "giolekva"
+ name: "headscale-controller"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
+ kubeRBACProxy: {
+ registry: "gcr.io"
+ repository: "kubebuilder"
+ name: "kube-rbac-proxy"
+ tag: "v0.13.0"
+ pullPolicy: "IfNotPresent"
+ }
}
- kubeRBACProxy: {
- registry: "gcr.io"
- repository: "kubebuilder"
- name: "kube-rbac-proxy"
- tag: "v0.13.0"
- pullPolicy: "IfNotPresent"
- }
-}
-charts: {
- headscaleController: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/headscale-controller"
+ charts: {
+ headscaleController: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/headscale-controller"
+ }
}
-}
-helm: {
- "headscale-controller": {
- chart: charts.headscaleController
- values: {
- installCRDs: true
- image: {
- repository: images.headscaleController.fullName
- tag: images.headscaleController.tag
- pullPolicy: images.headscaleController.pullPolicy
- }
- kubeRBACProxy: {
+ helm: {
+ "headscale-controller": {
+ chart: charts.headscaleController
+ values: {
+ installCRDs: true
image: {
- repository: images.kubeRBACProxy.fullName
- tag: images.kubeRBACProxy.tag
- pullPolicy: images.kubeRBACProxy.pullPolicy
+ repository: images.headscaleController.fullName
+ tag: images.headscaleController.tag
+ pullPolicy: images.headscaleController.pullPolicy
+ }
+ kubeRBACProxy: {
+ image: {
+ repository: images.kubeRBACProxy.fullName
+ tag: images.kubeRBACProxy.tag
+ pullPolicy: images.kubeRBACProxy.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/headscale-user.cue b/core/installer/values-tmpl/headscale-user.cue
new file mode 100644
index 0000000..036d0a3
--- /dev/null
+++ b/core/installer/values-tmpl/headscale-user.cue
@@ -0,0 +1,34 @@
+input: {
+ username: string
+ preAuthKey: {
+ enabled: bool | *false
+ }
+}
+
+name: "headscale-user"
+namespace: "app-headscale"
+
+out: {
+ charts: {
+ headscaleUser: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/headscale-user"
+ }
+ }
+
+ helm: {
+ "headscale-user-\(input.username)": {
+ chart: charts.headscaleUser
+ values: {
+ username: input.username
+ headscaleApiAddress: "http://headscale-api.\(global.namespacePrefix)app-headscale.svc.cluster.local"
+ preAuthKey: {
+ enabled: input.preAuthKey.enabled
+ secretName: "\(input.username)-headscale-preauthkey"
+ }
+ }
+ }
+ }
+}
diff --git a/core/installer/values-tmpl/headscale.cue b/core/installer/values-tmpl/headscale.cue
index e13c1f0..fdbcb5a 100644
--- a/core/installer/values-tmpl/headscale.cue
+++ b/core/installer/values-tmpl/headscale.cue
@@ -8,89 +8,92 @@
namespace: "app-headscale"
icon: "<svg xmlns='http://www.w3.org/2000/svg' width='50' height='50' viewBox='0 0 48 48'><circle cx='24' cy='24' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='24' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='10' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='10' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='10' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='24' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='38' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='38' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='38' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='38' r='2' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='24' r='2' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='24' r='2' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='24' r='2' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/></svg>"
-images: {
- headscale: {
- repository: "headscale"
- name: "headscale"
- tag: "0.22.3"
- pullPolicy: "IfNotPresent"
- }
- api: {
- repository: "giolekva"
- name: "headscale-api"
- tag: "latest"
- pullPolicy: "Always"
- }
-}
-
-charts: {
- oauth2Client: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/oauth2-client"
- }
- headscale: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/headscale"
- }
-}
-
_domain: "\(input.subdomain).\(input.network.domain)"
_oauth2ClientSecretName: "oauth2-client"
-helm: {
- "oauth2-client": {
- chart: charts.oauth2Client
- // TODO(gio): remove once hydra maester is installed as part of dodo itself
- dependsOn: [{
- name: "auth"
- namespace: "\(global.namespacePrefix)core-auth"
- }]
- values: {
- name: "\(release.namespace)-headscale"
- secretName: _oauth2ClientSecretName
- grantTypes: ["authorization_code"]
- responseTypes: ["code"]
- scope: "openid profile email"
- redirectUris: ["https://\(_domain)/oidc/callback"]
- hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
+out: {
+ images: {
+ headscale: {
+ repository: "headscale"
+ name: "headscale"
+ tag: "0.22.3"
+ pullPolicy: "IfNotPresent"
+ }
+ api: {
+ repository: "giolekva"
+ name: "headscale-api"
+ tag: "latest"
+ pullPolicy: "Always"
}
}
- headscale: {
- chart: charts.headscale
- dependsOn: [{
- name: "auth"
- namespace: "\(global.namespacePrefix)core-auth"
- }]
- values: {
- image: {
- repository: images.headscale.fullName
- tag: images.headscale.tag
- pullPolicy: images.headscale.pullPolicy
- }
- storage: size: "5Gi"
- ingressClassName: input.network.ingressClass
- certificateIssuer: input.network.certificateIssuer
- domain: _domain
- publicBaseDomain: input.network.domain
- ipAddressPool: "\(global.id)-headscale"
- oauth2: {
+
+ charts: {
+ oauth2Client: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/oauth2-client"
+ }
+ headscale: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/headscale"
+ }
+ }
+
+ helm: {
+ "oauth2-client": {
+ chart: charts.oauth2Client
+ // TODO(gio): remove once hydra maester is installed as part of dodo itself
+ dependsOn: [{
+ name: "auth"
+ namespace: "\(global.namespacePrefix)core-auth"
+ }]
+ values: {
+ name: "\(release.namespace)-headscale"
secretName: _oauth2ClientSecretName
- issuer: "https://hydra.\(input.network.domain)"
+ grantTypes: ["authorization_code"]
+ responseTypes: ["code"]
+ scope: "openid profile email"
+ redirectUris: ["https://\(_domain)/oidc/callback"]
+ hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
}
- api: {
- port: 8585
- ipSubnet: input.ipSubnet
+ }
+ headscale: {
+ chart: charts.headscale
+ dependsOn: [{
+ name: "auth"
+ namespace: "\(global.namespacePrefix)core-auth"
+ }]
+ values: {
image: {
- repository: images.api.fullName
- tag: images.api.tag
- pullPolicy: images.api.pullPolicy
+ repository: images.headscale.fullName
+ tag: images.headscale.tag
+ pullPolicy: images.headscale.pullPolicy
}
+ storage: size: "5Gi"
+ ingressClassName: input.network.ingressClass
+ certificateIssuer: input.network.certificateIssuer
+ domain: _domain
+ publicBaseDomain: input.network.domain
+ ipAddressPool: "\(global.id)-headscale"
+ oauth2: {
+ secretName: _oauth2ClientSecretName
+ issuer: "https://hydra.\(input.network.domain)"
+ }
+ api: {
+ port: 8585
+ ipSubnet: input.ipSubnet
+ self: "http://headscale-api.\(release.namespace).svc.cluster/sync-users"
+ image: {
+ repository: images.api.fullName
+ tag: images.api.tag
+ pullPolicy: images.api.pullPolicy
+ }
+ }
+ ui: enabled: false
}
- ui: enabled: false
}
}
}
diff --git a/core/installer/values-tmpl/hydra-maester.cue b/core/installer/values-tmpl/hydra-maester.cue
index 406dab3..22ba9b5 100644
--- a/core/installer/values-tmpl/hydra-maester.cue
+++ b/core/installer/values-tmpl/hydra-maester.cue
@@ -3,37 +3,39 @@
name: "hydra-maester"
namespace: "auth"
-images: {
- hydraMaester: {
- repository: "giolekva"
- name: "ory-hydra-maester"
- tag: "latest"
- pullPolicy: "Always"
+out: {
+ images: {
+ hydraMaester: {
+ repository: "giolekva"
+ name: "ory-hydra-maester"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
-}
-charts: {
- hydraMaester: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/hydra-maester"
+ charts: {
+ hydraMaester: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/hydra-maester"
+ }
}
-}
-helm: {
- "hydra-maester": {
- chart: charts.hydraMaester
- values: {
- adminService: {
- name: "foo.bar.svc.cluster.local"
- port: 80
- scheme: "http"
- }
- image: {
- repository: images.hydraMaester.fullName
- tag: images.hydraMaester.tag
- pullPolicy: images.hydraMaester.pullPolicy
+ helm: {
+ "hydra-maester": {
+ chart: charts.hydraMaester
+ values: {
+ adminService: {
+ name: "foo.bar.svc.cluster.local"
+ port: 80
+ scheme: "http"
+ }
+ image: {
+ repository: images.hydraMaester.fullName
+ tag: images.hydraMaester.tag
+ pullPolicy: images.hydraMaester.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/ingress-public.cue b/core/installer/values-tmpl/ingress-public.cue
index abb2439..fe6098e 100644
--- a/core/installer/values-tmpl/ingress-public.cue
+++ b/core/installer/values-tmpl/ingress-public.cue
@@ -9,116 +9,118 @@
name: "ingress-public"
namespace: "ingress-public"
-images: {
- ingressNginx: {
- registry: "registry.k8s.io"
- repository: "ingress-nginx"
- name: "controller"
- tag: "v1.8.0"
- pullPolicy: "IfNotPresent"
- }
- portAllocator: {
- repository: "giolekva"
- name: "port-allocator"
- tag: "latest"
- pullPolicy: "Always"
- }
-}
-
-charts: {
- ingressNginx: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/ingress-nginx"
- }
- portAllocator: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/port-allocator"
- }
-}
-
-helm: {
- "ingress-public": {
- chart: charts.ingressNginx
- values: {
- fullnameOverride: "\(global.pcloudEnvName)-ingress-public"
- controller: {
- kind: "Deployment"
- replicaCount: 1 // TODO(gio): configurable
- topologySpreadConstraints: [{
- labelSelector: {
- matchLabels: {
- "app.kubernetes.io/instance": "ingress-public"
- }
- }
- maxSkew: 1
- topologyKey: "kubernetes.io/hostname"
- whenUnsatisfiable: "DoNotSchedule"
- }]
- hostNetwork: false
- hostPort: enabled: false
- updateStrategy: {
- type: "RollingUpdate"
- rollingUpdate: {
- maxSurge: "100%"
- maxUnavailable: "30%"
- }
- }
- service: {
- enabled: true
- type: "NodePort"
- nodePorts: {
- http: 80
- https: 443
- tcp: {
- "53": 53
- }
- udp: {
- "53": 53
- }
- }
- }
- ingressClassByName: true
- ingressClassResource: {
- name: networks.public.ingressClass
- enabled: true
- default: false
- controllerValue: "k8s.io/\(networks.public.ingressClass)"
- }
- config: {
- "proxy-body-size": "200M" // TODO(giolekva): configurable
- "server-snippet": """
- more_clear_headers "X-Frame-Options";
- """
- }
- image: {
- registry: images.ingressNginx.registry
- image: images.ingressNginx.imageName
- tag: images.ingressNginx.tag
- pullPolicy: images.ingressNginx.pullPolicy
- }
- }
- tcp: {
- "53": "\(global.pcloudEnvName)-dns-gateway/coredns:53"
- }
- udp: {
- "53": "\(global.pcloudEnvName)-dns-gateway/coredns:53"
- }
+out: {
+ images: {
+ ingressNginx: {
+ registry: "registry.k8s.io"
+ repository: "ingress-nginx"
+ name: "controller"
+ tag: "v1.8.0"
+ pullPolicy: "IfNotPresent"
+ }
+ portAllocator: {
+ repository: "giolekva"
+ name: "port-allocator"
+ tag: "latest"
+ pullPolicy: "Always"
}
}
- "port-allocator": {
- chart: charts.portAllocator
- values: {
- repoAddr: release.repoAddr
- sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
- ingressNginxPath: "\(release.appDir)/ingress-public.yaml"
- image: {
- repository: images.portAllocator.fullName
- tag: images.portAllocator.tag
- pullPolicy: images.portAllocator.pullPolicy
+
+ charts: {
+ ingressNginx: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/ingress-nginx"
+ }
+ portAllocator: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/port-allocator"
+ }
+ }
+
+ helm: {
+ "ingress-public": {
+ chart: charts.ingressNginx
+ values: {
+ fullnameOverride: "\(global.pcloudEnvName)-ingress-public"
+ controller: {
+ kind: "Deployment"
+ replicaCount: 1 // TODO(gio): configurable
+ topologySpreadConstraints: [{
+ labelSelector: {
+ matchLabels: {
+ "app.kubernetes.io/instance": "ingress-public"
+ }
+ }
+ maxSkew: 1
+ topologyKey: "kubernetes.io/hostname"
+ whenUnsatisfiable: "DoNotSchedule"
+ }]
+ hostNetwork: false
+ hostPort: enabled: false
+ updateStrategy: {
+ type: "RollingUpdate"
+ rollingUpdate: {
+ maxSurge: "100%"
+ maxUnavailable: "30%"
+ }
+ }
+ service: {
+ enabled: true
+ type: "NodePort"
+ nodePorts: {
+ http: 80
+ https: 443
+ tcp: {
+ "53": 53
+ }
+ udp: {
+ "53": 53
+ }
+ }
+ }
+ ingressClassByName: true
+ ingressClassResource: {
+ name: networks.public.ingressClass
+ enabled: true
+ default: false
+ controllerValue: "k8s.io/\(networks.public.ingressClass)"
+ }
+ config: {
+ "proxy-body-size": "200M" // TODO(giolekva): configurable
+ "server-snippet": """
+ more_clear_headers "X-Frame-Options";
+ """
+ }
+ image: {
+ registry: images.ingressNginx.registry
+ image: images.ingressNginx.imageName
+ tag: images.ingressNginx.tag
+ pullPolicy: images.ingressNginx.pullPolicy
+ }
+ }
+ tcp: {
+ "53": "\(global.pcloudEnvName)-dns-gateway/coredns:53"
+ }
+ udp: {
+ "53": "\(global.pcloudEnvName)-dns-gateway/coredns:53"
+ }
+ }
+ }
+ "port-allocator": {
+ chart: charts.portAllocator
+ values: {
+ repoAddr: release.repoAddr
+ sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
+ ingressNginxPath: "\(release.appDir)/ingress-public.yaml"
+ image: {
+ repository: images.portAllocator.fullName
+ tag: images.portAllocator.tag
+ pullPolicy: images.portAllocator.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/jellyfin.cue b/core/installer/values-tmpl/jellyfin.cue
index 4df8248..3fecee0 100644
--- a/core/installer/values-tmpl/jellyfin.cue
+++ b/core/installer/values-tmpl/jellyfin.cue
@@ -13,37 +13,39 @@
readme: "jellyfin application will be installed on \(input.network.name) network and be accessible to any user on https://\(_domain)"
-images: {
- jellyfin: {
- repository: "jellyfin"
- name: "jellyfin"
- tag: "10.8.10"
- pullPolicy: "IfNotPresent"
+out: {
+ images: {
+ jellyfin: {
+ repository: "jellyfin"
+ name: "jellyfin"
+ tag: "10.8.10"
+ pullPolicy: "IfNotPresent"
+ }
}
-}
-charts: {
- jellyfin: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/jellyfin"
+ charts: {
+ jellyfin: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/jellyfin"
+ }
}
-}
-helm: {
- jellyfin: {
- chart: charts.jellyfin
- values: {
- pcloudInstanceId: global.id
- ingress: {
- className: input.network.ingressClass
- domain: _domain
- }
- image: {
- repository: images.jellyfin.fullName
- tag: images.jellyfin.tag
- pullPolicy: images.jellyfin.pullPolicy
+ helm: {
+ jellyfin: {
+ chart: charts.jellyfin
+ values: {
+ pcloudInstanceId: global.id
+ ingress: {
+ className: input.network.ingressClass
+ domain: _domain
+ }
+ image: {
+ repository: images.jellyfin.fullName
+ tag: images.jellyfin.tag
+ pullPolicy: images.jellyfin.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/jenkins.cue b/core/installer/values-tmpl/jenkins.cue
index d2f3602..7da855d 100644
--- a/core/installer/values-tmpl/jenkins.cue
+++ b/core/installer/values-tmpl/jenkins.cue
@@ -32,114 +32,116 @@
_jenkinsServiceHTTPPortNumber: 80
-ingress: {
- jenkins: {
- auth: enabled: false
- network: input.network
- subdomain: input.subdomain
- service: {
+out: {
+ ingress: {
+ jenkins: {
+ auth: enabled: false
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "jenkins"
+ port: number: _jenkinsServiceHTTPPortNumber
+ }
+ }
+ }
+
+ images: {
+ jenkins: {
+ repository: "jenkins"
name: "jenkins"
- port: number: _jenkinsServiceHTTPPortNumber
+ tag: "2.452-jdk17"
+ pullPolicy: "IfNotPresent"
+ }
+ }
+
+ charts: {
+ jenkins: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/jenkins"
+ }
+ oauth2Client: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/oauth2-client"
+ }
+ }
+
+ volumes: jenkins: size: "10Gi"
+
+ helm: {
+ "oauth2-client": {
+ chart: charts.oauth2Client
+ info: "Creating OAuth2 client"
+ values: {
+ name: "\(release.namespace)-jenkins"
+ secretName: _oauth2ClientCredentials
+ grantTypes: ["authorization_code"]
+ scope: "openid profile email offline offline_access"
+ hydraAdmin: "http://hydra-admin.\(global.id)-core-auth.svc.cluster.local"
+ redirectUris: ["https://\(_domain)/securityRealm/finishLogin"]
+ tokenEndpointAuthMethod: "client_secret_post"
+ }
+ }
+ jenkins: {
+ chart: charts.jenkins
+ info: "Installing Jenkins server"
+ values: {
+ fullnameOverride: "jenkins"
+ controller: {
+ image: {
+ repository: images.jenkins.imageName
+ tag: images.jenkins.tag
+ pullPolicy: images.jenkins.pullPolicy
+ }
+ jenkinsUrlProtocol: "https://"
+ jenkinsUrl: _domain
+ sidecars: configAutoReload: enabled: false
+ ingress: enabled: false
+ servicePort: _jenkinsServiceHTTPPortNumber
+ installPlugins: [
+ "kubernetes:4203.v1dd44f5b_1cf9",
+ "workflow-aggregator:596.v8c21c963d92d",
+ "git:5.2.1",
+ "configuration-as-code:1775.v810dc950b_514",
+ "gerrit-code-review:0.4.9",
+ "oic-auth:4.239.v325750a_96f3b_",
+ ]
+ additionalExistingSecrets: [{
+ name: _oauth2ClientCredentials
+ keyName: _oauth2ClientId
+ }, {
+ name: _oauth2ClientCredentials
+ keyName: _oauth2ClientSecret
+ }]
+ JCasC: {
+ defaultConfig: true
+ overwriteConfiguration: false
+ securityRealm: """
+ oic:
+ clientId: "${\(_oauth2ClientCredentials)-\(_oauth2ClientId)}"
+ clientSecret: "${\(_oauth2ClientCredentials)-\(_oauth2ClientSecret)}"
+ wellKnownOpenIDConfigurationUrl: "https://hydra.\(networks.public.domain)/.well-known/openid-configuration"
+ userNameField: "email"
+ """
+ }
+ }
+ agent: {
+ runAsUser: 1000
+ runAsGroup: 1000
+ jenkinsUrl: "http://jenkins.\(release.namespace).svc.cluster.local"
+ }
+ persistence: {
+ enabled: true
+ existingClaim: volumes.jenkins.name
+ }
+ }
}
}
}
-images: {
- jenkins: {
- repository: "jenkins"
- name: "jenkins"
- tag: "2.452-jdk17"
- pullPolicy: "IfNotPresent"
- }
-}
-
-charts: {
- jenkins: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/jenkins"
- }
- oauth2Client: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/oauth2-client"
- }
-}
-
-volumes: jenkins: size: "10Gi"
-
_oauth2ClientCredentials: "oauth2-credentials"
_oauth2ClientId: "client_id"
_oauth2ClientSecret: "client_secret"
-
-helm: {
- "oauth2-client": {
- chart: charts.oauth2Client
- info: "Creating OAuth2 client"
- values: {
- name: "\(release.namespace)-jenkins"
- secretName: _oauth2ClientCredentials
- grantTypes: ["authorization_code"]
- scope: "openid profile email offline offline_access"
- hydraAdmin: "http://hydra-admin.\(global.id)-core-auth.svc.cluster.local"
- redirectUris: ["https://\(_domain)/securityRealm/finishLogin"]
- tokenEndpointAuthMethod: "client_secret_post"
- }
- }
- jenkins: {
- chart: charts.jenkins
- info: "Installing Jenkins server"
- values: {
- fullnameOverride: "jenkins"
- controller: {
- image: {
- repository: images.jenkins.imageName
- tag: images.jenkins.tag
- pullPolicy: images.jenkins.pullPolicy
- }
- jenkinsUrlProtocol: "https://"
- jenkinsUrl: _domain
- sidecars: configAutoReload: enabled: false
- ingress: enabled: false
- servicePort: _jenkinsServiceHTTPPortNumber
- installPlugins: [
- "kubernetes:4203.v1dd44f5b_1cf9",
- "workflow-aggregator:596.v8c21c963d92d",
- "git:5.2.1",
- "configuration-as-code:1775.v810dc950b_514",
- "gerrit-code-review:0.4.9",
- "oic-auth:4.239.v325750a_96f3b_",
- ]
- additionalExistingSecrets: [{
- name: _oauth2ClientCredentials
- keyName: _oauth2ClientId
- }, {
- name: _oauth2ClientCredentials
- keyName: _oauth2ClientSecret
- }]
- JCasC: {
- defaultConfig: true
- overwriteConfiguration: false
- securityRealm: """
-oic:
- clientId: "${\(_oauth2ClientCredentials)-\(_oauth2ClientId)}"
- clientSecret: "${\(_oauth2ClientCredentials)-\(_oauth2ClientSecret)}"
- wellKnownOpenIDConfigurationUrl: "https://hydra.\(networks.public.domain)/.well-known/openid-configuration"
- userNameField: "email"
-"""
- }
- }
- agent: {
- runAsUser: 1000
- runAsGroup: 1000
- jenkinsUrl: "http://jenkins.\(release.namespace).svc.cluster.local"
- }
- persistence: {
- enabled: true
- existingClaim: volumes.jenkins.name
- }
- }
- }
-}
diff --git a/core/installer/values-tmpl/launcher.cue b/core/installer/values-tmpl/launcher.cue
index 4574b72..09c0ec3 100644
--- a/core/installer/values-tmpl/launcher.cue
+++ b/core/installer/values-tmpl/launcher.cue
@@ -19,51 +19,53 @@
_httpPortName: "http"
-ingress: {
- launcher: {
- auth: enabled: true
- network: input.network
- subdomain: _subdomain
- service: {
- name: "launcher"
- port: name: _httpPortName
+out: {
+ ingress: {
+ launcher: {
+ auth: enabled: true
+ network: input.network
+ subdomain: _subdomain
+ service: {
+ name: "launcher"
+ port: name: _httpPortName
+ }
}
}
-}
-images: {
- launcher: {
- repository: "giolekva"
- name: "pcloud-installer"
- tag: "latest"
- pullPolicy: "Always"
- }
-}
+ images: {
+ launcher: {
+ repository: "giolekva"
+ name: "pcloud-installer"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
+ }
-charts: {
- launcher: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/launcher"
- }
-}
+ charts: {
+ launcher: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/launcher"
+ }
+ }
-helm: {
- launcher: {
- chart: charts.launcher
- values: {
- image: {
- repository: images.launcher.fullName
- tag: images.launcher.tag
- pullPolicy: images.launcher.pullPolicy
- }
- portName: _httpPortName
- repoAddr: input.repoAddr
- sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
- logoutUrl: "https://accounts-ui.\(networks.public.domain)/logout"
- repoAddr: input.repoAddr
- sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
- }
- }
+ helm: {
+ launcher: {
+ chart: charts.launcher
+ values: {
+ image: {
+ repository: images.launcher.fullName
+ tag: images.launcher.tag
+ pullPolicy: images.launcher.pullPolicy
+ }
+ portName: _httpPortName
+ repoAddr: input.repoAddr
+ sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
+ 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 4cb0f0e..8bf8426 100644
--- a/core/installer/values-tmpl/matrix.cue
+++ b/core/installer/values-tmpl/matrix.cue
@@ -29,131 +29,133 @@
<path class='cls-1' d='m1.04503942.90944884v37.86613982h2.72503927v.90945071H0V0h3.77007869v.90944884H1.04503942Zm11.64590578,12.00472508v1.91314893h.05456692c.47654392-.69956134,1.10875881-1.27913948,1.84700726-1.69322862.71598361-.40511792,1.54771632-.60354293,2.48031496-.60354293.89291332,0,1.70811022.17692893,2.44889755.51921281.74078733.34393731,1.29803124.96236184,1.68661493,1.83212566.41999952-.61842453.99212662-1.16740212,1.70976444-1.64031434.71763782-.47456723,1.57086583-.71102334,2.55637717-.71102334.74905523,0,1.44188933.09259881,2.08346495.27614143.64157561.18188998,1.18393635.47291301,1.64196855.8763783.45637641.40511792.80858321.92433073,1.06818882,1.57252004.25133929.6481893.3803142,1.42700774.3803142,2.34307056v9.47149555h-3.88417161v-8.02133831c0-.4729138-.01653581-.92433073-.0529127-1.34267762-.02666609-.3797812-.12779852-.75060537-.2976383-1.09133833-.16496703-.31157689-.41647821-.56882971-.72425151-.74078733-.32078781-.1818892-.75566893-.27448879-1.29803124-.27448879-.54897601,0-.99212662.10582699-1.32779444.3125199-.33038665.20312114-.60355081.48709839-.79370003.82511744-.19910782.35594888-.32873086.74650374-.38196842,1.15086631-.06370056.42978918-.09685576.86355382-.09921329,1.29803124v7.88409548h-3.8858274v-7.93700819c0-.41999952-.00661369-.83173271-.0297632-1.24346433-.01353647-.38990201-.09350161-.7746348-.23645611-1.13763734-.13486952-.34292964-.3751576-.63417029-.68622041-.83173271-.32078781-.20669291-.78708634-.31417253-1.41212614-.31417253-.18354341,0-.42826743.03968532-.72590573.1223628-.2976383.08433012-.59527502.23645611-.87637751.46629853-.31383822.26829772-.56214032.60483444-.72590573.98385871-.19842501.42826743-.29763751.99212662-.29763751,1.68661335v8.21149541h-3.88417713v-14.16259852l3.66259868.00000079Zm25.94905485,25.86141789V.90944884h-2.72504056v-.90944884h3.77007988v39.68503937h-3.77007988v-.90944756h2.72504056Z'/>
</svg>"""
-images: {
- matrix: {
- repository: "matrixdotorg"
- name: "synapse"
- tag: "v1.104.0"
- pullPolicy: "IfNotPresent"
- }
- postgres: {
- repository: "library"
- name: "postgres"
- tag: "15.3"
- pullPolicy: "IfNotPresent"
- }
-}
-
-charts: {
- oauth2Client: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/oauth2-client"
- }
- matrix: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/matrix"
- }
- postgres: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/postgresql"
- }
-}
-
-_oauth2ClientSecretName: "oauth2-client"
-
-helm: {
- "oauth2-client": {
- chart: charts.oauth2Client
- info: "Creating OAuth2 client"
- values: {
- name: "\(release.namespace)-matrix"
- secretName: _oauth2ClientSecretName
- grantTypes: ["authorization_code"]
- responseTypes: ["code"]
- scope: "openid profile"
- redirectUris: ["https://\(_domain)/_synapse/client/oidc/callback"]
- hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
+out: {
+ images: {
+ matrix: {
+ repository: "matrixdotorg"
+ name: "synapse"
+ tag: "v1.104.0"
+ pullPolicy: "IfNotPresent"
}
- }
- matrix: {
- dependsOn: [{
+ postgres: {
+ repository: "library"
name: "postgres"
- namespace: release.namespace
- }]
- chart: charts.matrix
- info: "Installing Synapse server"
- values: {
- domain: input.network.domain
- subdomain: input.subdomain
- oauth2: {
- secretName: "oauth2-client"
- issuer: "https://hydra.\(input.network.domain)"
- }
- postgresql: {
- host: "postgres"
- port: 5432
- database: "matrix"
- user: "matrix"
- password: "matrix"
- }
- certificateIssuer: input.network.certificateIssuer
- ingressClassName: input.network.ingressClass
- configMerge: {
- configName: "config-to-merge"
- fileName: "to-merge.yaml"
- }
- image: {
- repository: images.matrix.fullName
- tag: images.matrix.tag
- pullPolicy: images.matrix.pullPolicy
- }
+ tag: "15.3"
+ pullPolicy: "IfNotPresent"
}
}
- postgres: {
- chart: charts.postgres
- info: "Installing PostgreSQL"
- values: {
- fullnameOverride: "postgres"
- image: {
- registry: images.postgres.registry
- repository: images.postgres.imageName
- tag: images.postgres.tag
- pullPolicy: images.postgres.pullPolicy
+
+ charts: {
+ oauth2Client: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/oauth2-client"
+ }
+ matrix: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/matrix"
+ }
+ postgres: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/postgresql"
+ }
+ }
+
+ _oauth2ClientSecretName: "oauth2-client"
+
+ helm: {
+ "oauth2-client": {
+ chart: charts.oauth2Client
+ info: "Creating OAuth2 client"
+ values: {
+ name: "\(release.namespace)-matrix"
+ secretName: _oauth2ClientSecretName
+ grantTypes: ["authorization_code"]
+ responseTypes: ["code"]
+ scope: "openid profile"
+ redirectUris: ["https://\(_domain)/_synapse/client/oidc/callback"]
+ hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
}
- service: {
- type: "ClusterIP"
- port: 5432
+ }
+ matrix: {
+ dependsOn: [{
+ name: "postgres"
+ namespace: release.namespace
+ }]
+ chart: charts.matrix
+ info: "Installing Synapse server"
+ values: {
+ domain: input.network.domain
+ subdomain: input.subdomain
+ oauth2: {
+ secretName: "oauth2-client"
+ issuer: "https://hydra.\(input.network.domain)"
+ }
+ postgresql: {
+ host: "postgres"
+ port: 5432
+ database: "matrix"
+ user: "matrix"
+ password: "matrix"
+ }
+ certificateIssuer: input.network.certificateIssuer
+ ingressClassName: input.network.ingressClass
+ configMerge: {
+ configName: "config-to-merge"
+ fileName: "to-merge.yaml"
+ }
+ image: {
+ repository: images.matrix.fullName
+ tag: images.matrix.tag
+ pullPolicy: images.matrix.pullPolicy
+ }
}
- primary: {
- initdb: {
- scripts: {
- "init.sql": """
- CREATE USER matrix WITH PASSWORD 'matrix';
- CREATE DATABASE matrix WITH OWNER = matrix ENCODING = UTF8 LOCALE = 'C' TEMPLATE = template0;
- """
+ }
+ postgres: {
+ chart: charts.postgres
+ info: "Installing PostgreSQL"
+ values: {
+ fullnameOverride: "postgres"
+ image: {
+ registry: images.postgres.registry
+ repository: images.postgres.imageName
+ tag: images.postgres.tag
+ pullPolicy: images.postgres.pullPolicy
+ }
+ service: {
+ type: "ClusterIP"
+ port: 5432
+ }
+ primary: {
+ initdb: {
+ scripts: {
+ "init.sql": """
+ CREATE USER matrix WITH PASSWORD 'matrix';
+ CREATE DATABASE matrix WITH OWNER = matrix ENCODING = UTF8 LOCALE = 'C' TEMPLATE = template0;
+ """
+ }
+ }
+ persistence: {
+ size: "10Gi"
+ }
+ securityContext: {
+ enabled: true
+ fsGroup: 0
+ }
+ containerSecurityContext: {
+ enabled: true
+ runAsUser: 0
}
}
- persistence: {
- size: "10Gi"
- }
- securityContext: {
- enabled: true
- fsGroup: 0
- }
- containerSecurityContext: {
- enabled: true
- runAsUser: 0
- }
- }
- volumePermissions: {
- securityContext: {
- runAsUser: 0
+ volumePermissions: {
+ securityContext: {
+ runAsUser: 0
+ }
}
}
}
diff --git a/core/installer/values-tmpl/memberships.cue b/core/installer/values-tmpl/memberships.cue
index bf1424e..5fc55d1 100644
--- a/core/installer/values-tmpl/memberships.cue
+++ b/core/installer/values-tmpl/memberships.cue
@@ -15,52 +15,54 @@
_httpPortName: "http"
-ingress: {
- memberships: {
- auth: {
- enabled: true
- groups: input.authGroups
- }
- network: input.network
- subdomain: _subdomain
- service: {
- name: "memberships"
- port: name: _httpPortName
+out: {
+ ingress: {
+ memberships: {
+ auth: {
+ enabled: true
+ groups: input.authGroups
+ }
+ network: input.network
+ subdomain: _subdomain
+ service: {
+ name: "memberships"
+ port: name: _httpPortName
+ }
}
}
-}
-images: {
- memberships: {
- repository: "giolekva"
- name: "memberships"
- tag: "latest"
- pullPolicy: "Always"
- }
-}
+ images: {
+ memberships: {
+ repository: "giolekva"
+ name: "memberships"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
+ }
-charts: {
- memberships: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/memberships"
- }
-}
+ charts: {
+ memberships: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/memberships"
+ }
+ }
-helm: {
- memberships: {
- chart: charts.memberships
- values: {
- storage: {
- size: "1Gi"
- }
- image: {
- repository: images.memberships.fullName
- tag: images.memberships.tag
- pullPolicy: images.memberships.pullPolicy
- }
- portName: _httpPortName
- }
- }
+ helm: {
+ memberships: {
+ chart: charts.memberships
+ values: {
+ storage: {
+ size: "1Gi"
+ }
+ image: {
+ repository: images.memberships.fullName
+ tag: images.memberships.tag
+ pullPolicy: images.memberships.pullPolicy
+ }
+ portName: _httpPortName
+ }
+ }
+ }
}
diff --git a/core/installer/values-tmpl/metallb-ipaddresspool.cue b/core/installer/values-tmpl/metallb-ipaddresspool.cue
index 47236ce..a0bb4e5 100644
--- a/core/installer/values-tmpl/metallb-ipaddresspool.cue
+++ b/core/installer/values-tmpl/metallb-ipaddresspool.cue
@@ -9,26 +9,26 @@
name: "metallb-ipaddresspool"
namespace: "metallb-ipaddresspool"
-images: {}
-
-charts: {
- metallbIPAddressPool: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/metallb-ipaddresspool"
+out: {
+ charts: {
+ metallbIPAddressPool: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/metallb-ipaddresspool"
+ }
}
-}
-helm: {
- "metallb-ipaddresspool-\(input.name)": {
- chart: charts.metallbIPAddressPool
- values: {
- name: input.name
- from: input.from
- to: input.to
- autoAssign: input.autoAssign
- namespace: input.namespace
+ helm: {
+ "metallb-ipaddresspool-\(input.name)": {
+ chart: charts.metallbIPAddressPool
+ values: {
+ name: input.name
+ from: input.from
+ to: input.to
+ autoAssign: input.autoAssign
+ namespace: input.namespace
+ }
}
}
}
diff --git a/core/installer/values-tmpl/open-project.cue b/core/installer/values-tmpl/open-project.cue
index 927db43..6598094 100644
--- a/core/installer/values-tmpl/open-project.cue
+++ b/core/installer/values-tmpl/open-project.cue
@@ -13,160 +13,163 @@
icon: "<svg xmlns='http://www.w3.org/2000/svg' width='50' height='50' viewBox='0 0 24 24'><path fill='currentColor' d='M19.35.37h-1.86a4.63 4.63 0 0 0-4.652 4.624v5.609H4.652A4.63 4.63 0 0 0 0 15.23v3.721c0 2.569 2.083 4.679 4.652 4.679h1.86c2.57 0 4.652-2.11 4.652-4.679v-3.72c0-.063 0-.158-.005-.158H8.373v3.88c0 1.026-.835 1.886-1.861 1.886h-1.86c-1.027 0-1.861-.864-1.861-1.886V15.23a1.84 1.84 0 0 1 1.86-1.833h14.697c2.57 0 4.652-2.11 4.652-4.679V4.997A4.63 4.63 0 0 0 19.35.37m1.861 8.345c0 1.026-.835 1.886-1.861 1.886h-3.721V4.997a1.84 1.84 0 0 1 1.86-1.833h1.86a1.84 1.84 0 0 1 1.862 1.833zm-8.373 9.706v.03c0 .746.629 1.344 1.396 1.344s1.395-.594 1.395-1.34v-3.384h-2.791z'/></svg>"
_httpPort: 8080
-ingress: {
- gerrit: {
- auth: enabled: false
- network: input.network
- subdomain: input.subdomain
- service: {
- name: "open-project"
- port: number: _httpPort
+
+out: {
+ ingress: {
+ gerrit: {
+ auth: enabled: false
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "open-project"
+ port: number: _httpPort
+ }
}
}
-}
-images: {
- openProject: {
- repository: "openproject"
- name: "openproject"
- tag: "13.4.1"
- pullPolicy: "Always"
+ images: {
+ openProject: {
+ repository: "openproject"
+ name: "openproject"
+ tag: "13.4.1"
+ pullPolicy: "Always"
+ }
+ postgres: {
+ repository: "library"
+ name: "postgres"
+ tag: "15.3"
+ pullPolicy: "IfNotPresent"
+ }
}
- postgres: {
- repository: "library"
- name: "postgres"
- tag: "15.3"
- pullPolicy: "IfNotPresent"
- }
-}
-charts: {
- openProject: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/openproject"
+ charts: {
+ openProject: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/openproject"
+ }
+ volume: {
+ path: "charts/volumes"
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ }
+ postgres: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/postgresql"
+ }
}
- volume: {
- path: "charts/volumes"
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- }
- postgres: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/postgresql"
- }
-}
-volumes: {
- openProject: {
- name: "open-project"
- accessMode: "ReadWriteMany"
- size: "50Gi"
+ volumes: {
+ openProject: {
+ name: "open-project"
+ accessMode: "ReadWriteMany"
+ size: "50Gi"
+ }
}
-}
-helm: {
- "open-project": {
- chart: charts.openProject
- values: {
- image: {
- registry: images.openProject.registry
- repository: images.openProject.imageName
- tag: images.openProject.tag
- imagePullPolicy: images.openProject.pullPolicy
- }
- nameOverride: "open-project"
- ingress: enabled: false
- memcached: bundled: true
- s3: enabled: false
- openproject: {
- host: _domain
- https: false
- hsts: false
- oidc: enabled: false // TODO(gio): enable
- admin_user: {
- password: "admin"
- password_reset: false
- name: "admin"
- mail: "op-admin@\(networks.public.domain)"
+ helm: {
+ "open-project": {
+ chart: charts.openProject
+ values: {
+ image: {
+ registry: images.openProject.registry
+ repository: images.openProject.imageName
+ tag: images.openProject.tag
+ imagePullPolicy: images.openProject.pullPolicy
+ }
+ nameOverride: "open-project"
+ ingress: enabled: false
+ memcached: bundled: true
+ s3: enabled: false
+ openproject: {
+ host: _domain
+ https: false
+ hsts: false
+ oidc: enabled: false // TODO(gio): enable
+ admin_user: {
+ password: "admin"
+ password_reset: false
+ name: "admin"
+ mail: "op-admin@\(networks.public.domain)"
+ }
+ }
+ persistence: {
+ enabled: true
+ existingClaim: volumes.openProject.name
+ }
+ postgresql: {
+ bundled: false
+ connection: {
+ host: "postgres.\(release.namespace).svc.cluster.local"
+ port: 5432
+ }
+ auth: {
+ username: "openproject"
+ password: "openproject"
+ database: "openproject"
+ }
+ }
+ service: {
+ enabled: true
+ type: "ClusterIP"
+ }
+ initDb: {
+ image: {
+ registry: images.postgres.registry
+ repository: images.postgres.imageName
+ tag: images.postgres.tag
+ imagePullPolicy: images.postgres.pullPolicy
+ }
}
}
- persistence: {
- enabled: true
- existingClaim: volumes.openProject.name
- }
- postgresql: {
- bundled: false
- connection: {
- host: "postgres.\(release.namespace).svc.cluster.local"
- port: 5432
- }
- auth: {
- username: "openproject"
- password: "openproject"
- database: "openproject"
- }
- }
- service: {
- enabled: true
- type: "ClusterIP"
- }
- initDb: {
+ }
+ "open-project-volume": {
+ chart: charts.volume
+ values: volumes.openProject
+ }
+ postgres: {
+ chart: charts.postgres
+ values: {
+ fullnameOverride: "postgres"
image: {
registry: images.postgres.registry
repository: images.postgres.imageName
tag: images.postgres.tag
- imagePullPolicy: images.postgres.pullPolicy
+ pullPolicy: images.postgres.pullPolicy
}
- }
- }
- }
- "open-project-volume": {
- chart: charts.volume
- values: volumes.openProject
- }
- postgres: {
- chart: charts.postgres
- values: {
- fullnameOverride: "postgres"
- image: {
- registry: images.postgres.registry
- repository: images.postgres.imageName
- tag: images.postgres.tag
- pullPolicy: images.postgres.pullPolicy
- }
- service: {
- type: "ClusterIP"
- port: 5432
- }
- primary: {
- initdb: {
- scripts: {
- "init.sql": """
- CREATE USER openproject WITH PASSWORD 'openproject';
- CREATE DATABASE openproject WITH OWNER = openproject ENCODING = UTF8 LOCALE = 'C' TEMPLATE = template0;
- """
+ service: {
+ type: "ClusterIP"
+ port: 5432
+ }
+ primary: {
+ initdb: {
+ scripts: {
+ "init.sql": """
+ CREATE USER openproject WITH PASSWORD 'openproject';
+ CREATE DATABASE openproject WITH OWNER = openproject ENCODING = UTF8 LOCALE = 'C' TEMPLATE = template0;
+ """
+ }
+ }
+ persistence: {
+ size: "50Gi"
+ }
+ securityContext: {
+ enabled: true
+ fsGroup: 0
+ }
+ containerSecurityContext: {
+ enabled: true
+ runAsUser: 0
}
}
- persistence: {
- size: "50Gi"
- }
- securityContext: {
- enabled: true
- fsGroup: 0
- }
- containerSecurityContext: {
- enabled: true
- runAsUser: 0
- }
- }
- volumePermissions: {
- securityContext: {
- runAsUser: 0
+ volumePermissions: {
+ securityContext: {
+ runAsUser: 0
+ }
}
}
}
diff --git a/core/installer/values-tmpl/penpot.cue b/core/installer/values-tmpl/penpot.cue
index 0e25a43..21004f4 100644
--- a/core/installer/values-tmpl/penpot.cue
+++ b/core/installer/values-tmpl/penpot.cue
@@ -12,165 +12,167 @@
description: "Penpot is the first Open Source design and prototyping platform meant for cross-domain teams. Non dependent on operating systems, Penpot is web based and works with open standards (SVG). Penpot invites designers all over the world to fall in love with open source while getting developers excited about the design process in return."
icon: "<svg xmlns='http://www.w3.org/2000/svg' width='50' height='50' viewBox='0 0 24 24'><path fill='currentColor' d='M7.654 0L5.13 3.554v2.01L2.934 6.608l-.02-.009v13.109l8.563 4.045L12 24l.523-.247l8.563-4.045V6.6l-.017.008l-2.196-1.045V3.555l-.077-.108L16.349.001l-2.524 3.554v.004L11.989.973l-1.823 2.566l-.065-.091zm.447 2.065l.976 1.374H6.232l.964-1.358zm8.694 0l.976 1.374h-2.845l.965-1.358zm-4.36.971l.976 1.375h-2.845l.965-1.359zM5.962 4.132h1.35v4.544l-1.35-.638Zm2.042 0h1.343v5.506l-1.343-.635zm6.652 0h1.35V9l-1.35.637zm2.042 0h1.343v3.905l-1.343.634zm-6.402.972h1.35v5.62l-1.35-.638zm2.042 0h1.343v4.993l-1.343.634zm6.534 1.493l1.188.486l-1.188.561zM5.13 6.6v1.047l-1.187-.561ZM3.96 8.251l7.517 3.55v10.795l-7.516-3.55zm16.08 0v10.794l-7.517 3.55V11.802z'/></svg>"
-images: {
- postgres: {
- repository: "library"
- name: "postgres"
- tag: "15.3"
- pullPolicy: "IfNotPresent"
- }
- backend: {
- repository: "penpotapp"
- name: "backend"
- tag: "1.16.0-beta"
- pullPolicy: "IfNotPresent"
- }
- frontend: {
- repository: "penpotapp"
- name: "frontend"
- tag: "1.16.0-beta"
- pullPolicy: "IfNotPresent"
- }
- exporter: {
- repository: "penpotapp"
- name: "exporter"
- tag: "1.16.0-beta"
- pullPolicy: "IfNotPresent"
- }
-}
-
-charts: {
- postgres: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/postgresql"
- }
- oauth2Client: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/oauth2-client"
- }
- penpot: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/penpot"
- }
-}
-
-_oauth2SecretName: "oauth2-credentials"
-
-helm: {
- "oauth2-client": {
- chart: charts.oauth2Client
- values: {
- name: "\(release.namespace)-penpot"
- secretName: _oauth2SecretName
- grantTypes: ["authorization_code"]
- responseTypes: ["code"]
- scope: "openid profile email"
- redirectUris: ["https://\(_domain)/api/auth/oauth/oidc/callback"]
- hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
- tokenEndpointAuthMethod: "client_secret_post"
+out: {
+ images: {
+ postgres: {
+ repository: "library"
+ name: "postgres"
+ tag: "15.3"
+ pullPolicy: "IfNotPresent"
+ }
+ backend: {
+ repository: "penpotapp"
+ name: "backend"
+ tag: "1.16.0-beta"
+ pullPolicy: "IfNotPresent"
+ }
+ frontend: {
+ repository: "penpotapp"
+ name: "frontend"
+ tag: "1.16.0-beta"
+ pullPolicy: "IfNotPresent"
+ }
+ exporter: {
+ repository: "penpotapp"
+ name: "exporter"
+ tag: "1.16.0-beta"
+ pullPolicy: "IfNotPresent"
}
}
- postgres: {
- chart: charts.postgres
- values: {
- fullnameOverride: "postgres"
- image: {
- registry: images.postgres.registry
- repository: images.postgres.imageName
- tag: images.postgres.tag
- pullPolicy: images.postgres.pullPolicy
- }
- auth: {
- username: "penpot"
- password: "penpot"
- database: "penpot"
- }
+
+ charts: {
+ postgres: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/postgresql"
+ }
+ oauth2Client: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/oauth2-client"
+ }
+ penpot: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/penpot"
}
}
- penpot: {
- chart: charts.penpot
- values: {
- "global": {
- postgresqlEnabled: false
- redisEnabled: true // TODO(gio): provide redis from outside
+
+ _oauth2SecretName: "oauth2-credentials"
+
+ helm: {
+ "oauth2-client": {
+ chart: charts.oauth2Client
+ values: {
+ name: "\(release.namespace)-penpot"
+ secretName: _oauth2SecretName
+ grantTypes: ["authorization_code"]
+ responseTypes: ["code"]
+ scope: "openid profile email"
+ redirectUris: ["https://\(_domain)/api/auth/oauth/oidc/callback"]
+ hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
+ tokenEndpointAuthMethod: "client_secret_post"
}
- fullnameOverride: "penpot"
- backend: {
+ }
+ postgres: {
+ chart: charts.postgres
+ values: {
+ fullnameOverride: "postgres"
image: {
- repository: images.backend.fullName
- tag: images.backend.tag
- imagePullPolicy: images.backend.pullPolicy
+ registry: images.postgres.registry
+ repository: images.postgres.imageName
+ tag: images.postgres.tag
+ pullPolicy: images.postgres.pullPolicy
}
- }
- frontend: {
- image: {
- repository: images.frontend.fullName
- tag: images.frontend.tag
- imagePullPolicy: images.frontend.pullPolicy
- }
- ingress: {
- enabled: true
- className: input.network.ingressClass
- if input.network.certificateIssuer != "" {
- annotations: {
- "acme.cert-manager.io/http01-edit-in-place": "true"
- "cert-manager.io/cluster-issuer": input.network.certificateIssuer
- }
- }
- hosts: [_domain]
- tls: [{
- hosts: [_domain]
- secretName: "cert-\(_domain)"
- }]
- }
- }
- persistence: enabled: true
- config: {
- publicURI: _domain
- flags: "enable-login-with-oidc enable-registration enable-insecure-register disable-demo-users disable-demo-warning" // TODO(gio): remove enable-insecure-register?
- postgresql: {
- host: "postgres.\(release.namespace).svc.cluster.local"
- database: "penpot"
+ auth: {
username: "penpot"
password: "penpot"
+ database: "penpot"
}
- redis: host: "penpot-redis-headless.\(release.namespace).svc.cluster.local"
- providers: {
- oidc: {
+ }
+ }
+ penpot: {
+ chart: charts.penpot
+ values: {
+ "global": {
+ postgresqlEnabled: false
+ redisEnabled: true // TODO(gio): provide redis from outside
+ }
+ fullnameOverride: "penpot"
+ backend: {
+ image: {
+ repository: images.backend.fullName
+ tag: images.backend.tag
+ imagePullPolicy: images.backend.pullPolicy
+ }
+ }
+ frontend: {
+ image: {
+ repository: images.frontend.fullName
+ tag: images.frontend.tag
+ imagePullPolicy: images.frontend.pullPolicy
+ }
+ ingress: {
enabled: true
- baseURI: "https://hydra.\(networks.public.domain)"
- clientID: ""
- clientSecret: ""
- authURI: ""
- tokenURI: ""
- userURI: ""
- roles: ""
- rolesAttribute: ""
- scopes: ""
- nameAttribute: "name"
- emailAttribute: "email"
- }
- existingSecret: _oauth2SecretName
- secretKeys: {
- oidcClientIDKey: "client_id"
- oidcClientSecretKey: "client_secret"
+ className: input.network.ingressClass
+ if input.network.certificateIssuer != "" {
+ annotations: {
+ "acme.cert-manager.io/http01-edit-in-place": "true"
+ "cert-manager.io/cluster-issuer": input.network.certificateIssuer
+ }
+ }
+ hosts: [_domain]
+ tls: [{
+ hosts: [_domain]
+ secretName: "cert-\(_domain)"
+ }]
}
}
- }
- exporter: {
- image: {
- repository: images.exporter.fullName
- tag: images.exporter.tag
- imagePullPolicy: images.exporter.pullPolicy
+ persistence: enabled: true
+ config: {
+ publicURI: _domain
+ flags: "enable-login-with-oidc enable-registration enable-insecure-register disable-demo-users disable-demo-warning" // TODO(gio): remove enable-insecure-register?
+ postgresql: {
+ host: "postgres.\(release.namespace).svc.cluster.local"
+ database: "penpot"
+ username: "penpot"
+ password: "penpot"
+ }
+ redis: host: "penpot-redis-headless.\(release.namespace).svc.cluster.local"
+ providers: {
+ oidc: {
+ enabled: true
+ baseURI: "https://hydra.\(networks.public.domain)"
+ clientID: ""
+ clientSecret: ""
+ authURI: ""
+ tokenURI: ""
+ userURI: ""
+ roles: ""
+ rolesAttribute: ""
+ scopes: ""
+ nameAttribute: "name"
+ emailAttribute: "email"
+ }
+ existingSecret: _oauth2SecretName
+ secretKeys: {
+ oidcClientIDKey: "client_id"
+ oidcClientSecretKey: "client_secret"
+ }
+ }
}
+ exporter: {
+ image: {
+ repository: images.exporter.fullName
+ tag: images.exporter.tag
+ imagePullPolicy: images.exporter.pullPolicy
+ }
+ }
+ redis: image: tag: "7.0.8-debian-11-r16"
}
- redis: image: tag: "7.0.8-debian-11-r16"
}
}
}
diff --git a/core/installer/values-tmpl/pihole.cue b/core/installer/values-tmpl/pihole.cue
index 59cab5d..01a3ca1 100644
--- a/core/installer/values-tmpl/pihole.cue
+++ b/core/installer/values-tmpl/pihole.cue
@@ -2,6 +2,7 @@
network: #Network @name(Network)
subdomain: string @name(Subdomain)
auth: #Auth @name(Authentication)
+ storageSize: string
}
_domain: "\(input.subdomain).\(input.network.domain)"
@@ -33,83 +34,87 @@
_serviceWebPort: 80
-ingress: {
- pihole: {
- auth: input.auth
- network: input.network
- subdomain: input.subdomain
- service: {
- name: "pihole-web"
- port: number: _serviceWebPort
+out: {
+ ingress: {
+ pihole: {
+ auth: input.auth
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "pihole-web"
+ port: number: _serviceWebPort
+ }
}
}
-}
-images: {
- pihole: {
- repository: "pihole"
- name: "pihole"
- tag: "v5.8.1"
- pullPolicy: "IfNotPresent"
+ images: {
+ pihole: {
+ repository: "pihole"
+ name: "pihole"
+ tag: "v5.8.1"
+ pullPolicy: "IfNotPresent"
+ }
}
-}
-charts: {
- pihole: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/pihole"
+ charts: {
+ pihole: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/pihole"
+ }
}
-}
-helm: {
- pihole: {
- chart: charts.pihole
- info: "Installing Pi-hole server"
- values: {
- fullnameOverride: "pihole"
- persistentVolumeClaim: { // TODO(gio): create volume separately as a dependency
- enabled: true
- size: "5Gi"
- }
- admin: {
- enabled: false
- }
- ingress: {
- enabled: false
- }
- serviceDhcp: {
- enabled: false
- }
- serviceDns: {
- type: "ClusterIP"
- }
- serviceWeb: {
- type: "ClusterIP"
- http: {
+ volumes: data: size: input.storageSize
+
+ helm: {
+ pihole: {
+ chart: charts.pihole
+ info: "Installing Pi-hole server"
+ values: {
+ fullnameOverride: "pihole"
+ persistentVolumeClaim: {
enabled: true
- port: _serviceWebPort
+ existingClaim: volumes.data.name
}
- https: {
+ admin: {
enabled: false
}
- }
- virtualHost: _domain
- resources: {
- requests: {
- cpu: "250m"
- memory: "100M"
+ ingress: {
+ enabled: false
}
- limits: {
- cpu: "500m"
- memory: "250M"
+ serviceDhcp: {
+ enabled: false
}
- }
- image: {
- repository: images.pihole.fullName
- tag: images.pihole.tag
- pullPolicy: images.pihole.pullPolicy
+ serviceDns: {
+ type: "ClusterIP"
+ }
+ serviceWeb: {
+ type: "ClusterIP"
+ http: {
+ enabled: true
+ port: _serviceWebPort
+ }
+ https: {
+ enabled: false
+ }
+ }
+ virtualHost: _domain
+ resources: {
+ requests: {
+ cpu: "250m"
+ memory: "100M"
+ }
+ limits: {
+ cpu: "500m"
+ memory: "250M"
+ }
+ }
+ image: {
+ repository: images.pihole.fullName
+ tag: images.pihole.tag
+ pullPolicy: images.pihole.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/private-network.cue b/core/installer/values-tmpl/private-network.cue
index 255b375..653da67 100644
--- a/core/installer/values-tmpl/private-network.cue
+++ b/core/installer/values-tmpl/private-network.cue
@@ -14,119 +14,121 @@
name: "private-network"
namespace: "ingress-private"
-images: {
- "ingress-nginx": {
- registry: "registry.k8s.io"
- repository: "ingress-nginx"
- name: "controller"
- tag: "v1.8.0"
- pullPolicy: "IfNotPresent"
+out: {
+ images: {
+ "ingress-nginx": {
+ registry: "registry.k8s.io"
+ repository: "ingress-nginx"
+ name: "controller"
+ tag: "v1.8.0"
+ pullPolicy: "IfNotPresent"
+ }
+ "tailscale-proxy": {
+ repository: "tailscale"
+ name: "tailscale"
+ tag: "v1.42.0"
+ pullPolicy: "IfNotPresent"
+ }
+ portAllocator: {
+ repository: "giolekva"
+ name: "port-allocator"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
- "tailscale-proxy": {
- repository: "tailscale"
- name: "tailscale"
- tag: "v1.42.0"
- pullPolicy: "IfNotPresent"
- }
- portAllocator: {
- repository: "giolekva"
- name: "port-allocator"
- tag: "latest"
- pullPolicy: "Always"
- }
-}
-charts: {
- "ingress-nginx": {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/ingress-nginx"
+ charts: {
+ "ingress-nginx": {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/ingress-nginx"
+ }
+ "tailscale-proxy": {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/tailscale-proxy"
+ }
+ portAllocator: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/port-allocator"
+ }
}
- "tailscale-proxy": {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/tailscale-proxy"
- }
- portAllocator: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/port-allocator"
- }
-}
-_ingressPrivate: "\(global.id)-ingress-private"
+ _ingressPrivate: "\(global.id)-ingress-private"
-helm: {
- "ingress-nginx": {
- chart: charts["ingress-nginx"]
- values: {
- fullnameOverride: "\(global.id)-nginx-private"
- controller: {
- service: {
- enabled: true
- type: "LoadBalancer"
- annotations: {
- "metallb.universe.tf/address-pool": _ingressPrivate
+ helm: {
+ "ingress-nginx": {
+ chart: charts["ingress-nginx"]
+ values: {
+ fullnameOverride: "\(global.id)-nginx-private"
+ controller: {
+ service: {
+ enabled: true
+ type: "LoadBalancer"
+ annotations: {
+ "metallb.universe.tf/address-pool": _ingressPrivate
+ }
+ }
+ ingressClassByName: true
+ ingressClassResource: {
+ name: _ingressPrivate
+ enabled: true
+ default: false
+ controllerValue: "k8s.io/\(_ingressPrivate)"
+ }
+ config: {
+ "proxy-body-size": "200M" // TODO(giolekva): configurable
+ "force-ssl-redirect": "true"
+ "server-snippet": """
+ more_clear_headers "X-Frame-Options";
+ """
+ }
+ extraArgs: {
+ "default-ssl-certificate": "\(_ingressPrivate)/cert-wildcard.\(global.privateDomain)"
+ }
+ admissionWebhooks: {
+ enabled: false
+ }
+ image: {
+ registry: images["ingress-nginx"].registry
+ image: images["ingress-nginx"].imageName
+ tag: images["ingress-nginx"].tag
+ pullPolicy: images["ingress-nginx"].pullPolicy
}
}
- ingressClassByName: true
- ingressClassResource: {
- name: _ingressPrivate
- enabled: true
- default: false
- controllerValue: "k8s.io/\(_ingressPrivate)"
- }
- config: {
- "proxy-body-size": "200M" // TODO(giolekva): configurable
- "force-ssl-redirect": "true"
- "server-snippet": """
- more_clear_headers "X-Frame-Options";
- """
- }
- extraArgs: {
- "default-ssl-certificate": "\(_ingressPrivate)/cert-wildcard.\(global.privateDomain)"
- }
- admissionWebhooks: {
- enabled: false
- }
+ }
+ }
+ "tailscale-proxy": {
+ chart: charts["tailscale-proxy"]
+ values: {
+ hostname: input.privateNetwork.hostname
+ apiServer: "http://headscale-api.\(global.namespacePrefix)app-headscale.svc.cluster.local"
+ 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"
image: {
- registry: images["ingress-nginx"].registry
- image: images["ingress-nginx"].imageName
- tag: images["ingress-nginx"].tag
- pullPolicy: images["ingress-nginx"].pullPolicy
+ repository: images["tailscale-proxy"].fullName
+ tag: images["tailscale-proxy"].tag
+ pullPolicy: images["tailscale-proxy"].pullPolicy
}
}
}
- }
- "tailscale-proxy": {
- chart: charts["tailscale-proxy"]
- values: {
- hostname: input.privateNetwork.hostname
- apiServer: "http://headscale-api.\(global.namespacePrefix)app-headscale.svc.cluster.local"
- 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"
- image: {
- repository: images["tailscale-proxy"].fullName
- tag: images["tailscale-proxy"].tag
- pullPolicy: images["tailscale-proxy"].pullPolicy
- }
- }
- }
- "port-allocator": {
- chart: charts.portAllocator
- values: {
- repoAddr: release.repoAddr
- sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
- ingressNginxPath: "\(release.appDir)/resources/ingress-nginx.yaml"
- image: {
- repository: images.portAllocator.fullName
- tag: images.portAllocator.tag
- pullPolicy: images.portAllocator.pullPolicy
+ "port-allocator": {
+ chart: charts.portAllocator
+ values: {
+ repoAddr: release.repoAddr
+ sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
+ ingressNginxPath: "\(release.appDir)/resources/ingress-nginx.yaml"
+ image: {
+ repository: images.portAllocator.fullName
+ tag: images.portAllocator.tag
+ pullPolicy: images.portAllocator.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/qbittorrent.cue b/core/installer/values-tmpl/qbittorrent.cue
index d569311..bec6a3c 100644
--- a/core/installer/values-tmpl/qbittorrent.cue
+++ b/core/installer/values-tmpl/qbittorrent.cue
@@ -12,41 +12,43 @@
description: "qBittorrent is a cross-platform free and open-source BitTorrent client written in native C++. It relies on Boost, Qt 6 toolkit and the libtorrent-rasterbar library, with an optional search engine written in Python."
icon: "<svg xmlns='http://www.w3.org/2000/svg' width='50' height='50' viewBox='0 0 48 48'><circle cx='24' cy='24' r='21.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><path fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='M26.651 22.364a5.034 5.034 0 0 1 5.035-5.035h0a5.034 5.034 0 0 1 5.034 5.035v3.272a5.034 5.034 0 0 1-5.034 5.035h0a5.034 5.034 0 0 1-5.035-5.035m0 5.035V10.533m-5.302 15.103a5.034 5.034 0 0 1-5.035 5.035h0a5.034 5.034 0 0 1-5.034-5.035v-3.272a5.034 5.034 0 0 1 5.034-5.035h0a5.034 5.034 0 0 1 5.035 5.035m0-5.035v20.138'/></svg>"
-images: {
- qbittorrent: {
- registry: "lscr.io"
- repository: "linuxserver"
- name: "qbittorrent"
- tag: "4.5.3"
- pullPolicy: "IfNotPresent"
+out: {
+ images: {
+ qbittorrent: {
+ registry: "lscr.io"
+ repository: "linuxserver"
+ name: "qbittorrent"
+ tag: "4.5.3"
+ pullPolicy: "IfNotPresent"
+ }
}
-}
-charts: {
- qbittorrent: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/qbittorrent"
+ charts: {
+ qbittorrent: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/qbittorrent"
+ }
}
-}
-helm: {
- qbittorrent: {
- chart: charts.qbittorrent
- values: {
- pcloudInstanceId: global.id
- ingress: {
- className: input.network.ingressClass
- domain: _domain
- }
- webui: port: 8080
- bittorrent: port: 6881
- storage: size: "100Gi"
- image: {
- repository: images.qbittorrent.fullName
- tag: images.qbittorrent.tag
- pullPolicy: images.qbittorrent.pullPolicy
+ helm: {
+ qbittorrent: {
+ chart: charts.qbittorrent
+ values: {
+ pcloudInstanceId: global.id
+ ingress: {
+ className: input.network.ingressClass
+ domain: _domain
+ }
+ webui: port: 8080
+ bittorrent: port: 6881
+ storage: size: "100Gi"
+ image: {
+ repository: images.qbittorrent.fullName
+ tag: images.qbittorrent.tag
+ pullPolicy: images.qbittorrent.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/resource-renderer-controller.cue b/core/installer/values-tmpl/resource-renderer-controller.cue
index 23d1a54..1169be7 100644
--- a/core/installer/values-tmpl/resource-renderer-controller.cue
+++ b/core/installer/values-tmpl/resource-renderer-controller.cue
@@ -3,46 +3,48 @@
name: "resource-renderer-controller"
namespace: "rr-controller"
-images: {
- resourceRenderer: {
- repository: "giolekva"
- name: "resource-renderer-controller"
- tag: "latest"
- pullPolicy: "Always"
+out: {
+ images: {
+ resourceRenderer: {
+ repository: "giolekva"
+ name: "resource-renderer-controller"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
+ kubeRBACProxy: {
+ registry: "gcr.io"
+ repository: "kubebuilder"
+ name: "kube-rbac-proxy"
+ tag: "v0.13.0"
+ pullPolicy: "IfNotPresent"
+ }
}
- kubeRBACProxy: {
- registry: "gcr.io"
- repository: "kubebuilder"
- name: "kube-rbac-proxy"
- tag: "v0.13.0"
- pullPolicy: "IfNotPresent"
- }
-}
-charts: {
- resourceRenderer: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/resource-renderer-controller"
+ charts: {
+ resourceRenderer: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/resource-renderer-controller"
+ }
}
-}
-helm: {
- "resource-renderer": {
- chart: charts.resourceRenderer
- values: {
- installCRDs: true
- image: {
- repository: images.resourceRenderer.fullName
- tag: images.resourceRenderer.tag
- pullPolicy: images.resourceRenderer.pullPolicy
- }
- kubeRBACProxy: {
+ helm: {
+ "resource-renderer": {
+ chart: charts.resourceRenderer
+ values: {
+ installCRDs: true
image: {
- repository: images.kubeRBACProxy.fullName
- tag: images.kubeRBACProxy.tag
- pullPolicy: images.kubeRBACProxy.pullPolicy
+ repository: images.resourceRenderer.fullName
+ tag: images.resourceRenderer.tag
+ pullPolicy: images.resourceRenderer.pullPolicy
+ }
+ kubeRBACProxy: {
+ image: {
+ repository: images.kubeRBACProxy.fullName
+ tag: images.kubeRBACProxy.tag
+ pullPolicy: images.kubeRBACProxy.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/rpuppy.cue b/core/installer/values-tmpl/rpuppy.cue
index 65bfbdb..ab77052 100644
--- a/core/installer/values-tmpl/rpuppy.cue
+++ b/core/installer/values-tmpl/rpuppy.cue
@@ -32,47 +32,49 @@
_httpPortName: "http"
-ingress: {
- rpuppy: {
- auth: input.auth
- network: input.network
- subdomain: input.subdomain
- service: {
- name: "rpuppy"
- port: name: _httpPortName
+out: {
+ ingress: {
+ rpuppy: {
+ auth: input.auth
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "rpuppy"
+ port: name: _httpPortName
+ }
}
}
-}
-images: {
- rpuppy: {
- repository: "giolekva"
- name: "rpuppy"
- tag: "latest"
- pullPolicy: "Always"
+ images: {
+ rpuppy: {
+ repository: "giolekva"
+ name: "rpuppy"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
-}
-charts: {
- rpuppy: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/rpuppy"
+ charts: {
+ rpuppy: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/rpuppy"
+ }
}
-}
-helm: {
- rpuppy: {
- chart: charts.rpuppy
- info: "Installing rPuppy server"
- values: {
- image: {
- repository: images.rpuppy.fullName
- tag: images.rpuppy.tag
- pullPolicy: images.rpuppy.pullPolicy
+ helm: {
+ rpuppy: {
+ chart: charts.rpuppy
+ info: "Installing rPuppy server"
+ values: {
+ image: {
+ repository: images.rpuppy.fullName
+ tag: images.rpuppy.tag
+ pullPolicy: images.rpuppy.pullPolicy
+ }
+ portName: _httpPortName
}
- portName: _httpPortName
}
}
}
diff --git a/core/installer/values-tmpl/soft-serve.cue b/core/installer/values-tmpl/soft-serve.cue
index a52ddd7..a6f85c0 100644
--- a/core/installer/values-tmpl/soft-serve.cue
+++ b/core/installer/values-tmpl/soft-serve.cue
@@ -36,36 +36,6 @@
</g>
</svg>"""
-images: {
- softserve: {
- repository: "charmcli"
- name: "soft-serve"
- tag: "v0.7.1"
- pullPolicy: "IfNotPresent"
- }
-}
-
-charts: {
- softserve: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/soft-serve"
- }
-}
-
-ingress: {
- gerrit: { // TODO(gio): rename to soft-serve
- auth: enabled: false
- network: input.network
- subdomain: input.subdomain
- service: {
- name: "soft-serve"
- port: number: 80
- }
- }
-}
-
portForward: [#PortForward & {
allocator: input.network.allocatePortAddr
reservator: input.network.reservePortAddr
@@ -75,22 +45,55 @@
targetPort: 22
}]
-helm: {
- softserve: {
- chart: charts.softserve
- info: "Installing SoftServe server"
- values: {
- serviceType: "ClusterIP"
- adminKey: input.adminKey
- sshPublicPort: input.sshPort
- ingress: {
- enabled: false
- domain: _domain
+
+out: {
+ images: {
+ softserve: {
+ repository: "charmcli"
+ name: "soft-serve"
+ tag: "v0.7.1"
+ pullPolicy: "IfNotPresent"
+ }
+ }
+
+ charts: {
+ softserve: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/soft-serve"
+ }
+ }
+
+ ingress: {
+ softserve: {
+ auth: enabled: false
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "soft-serve"
+ port: number: 80
}
- image: {
- repository: images.softserve.fullName
- tag: images.softserve.tag
- pullPolicy: images.softserve.pullPolicy
+ }
+ }
+
+ volumes: data: size: "1Gi"
+
+ helm: {
+ softserve: {
+ chart: charts.softserve
+ info: "Installing SoftServe server"
+ values: {
+ serviceType: "ClusterIP"
+ adminKey: input.adminKey
+ host: _domain
+ sshPublicPort: input.sshPort
+ persistentVolumeClaimName: volumes.data.name
+ image: {
+ repository: images.softserve.fullName
+ tag: images.softserve.tag
+ pullPolicy: images.softserve.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/url-shortener.cue b/core/installer/values-tmpl/url-shortener.cue
index 26f3287..1fa70c4 100644
--- a/core/installer/values-tmpl/url-shortener.cue
+++ b/core/installer/values-tmpl/url-shortener.cue
@@ -2,6 +2,7 @@
network: #Network @name(Network)
subdomain: string @name(Subdomain)
auth: #Auth @name(Authentication)
+ storageSize: string @name(Storage Size)
}
_domain: "\(input.subdomain).\(input.network.domain)"
@@ -37,51 +38,53 @@
_httpPortName: "http"
-ingress: {
- "url-shorteners": {
- auth: input.auth
- network: input.network
- subdomain: input.subdomain
- service: {
- name: "url-shortener"
- port: name: _httpPortName
+out: {
+ ingress: {
+ "url-shorteners": {
+ auth: input.auth
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "url-shortener"
+ port: name: _httpPortName
+ }
}
}
-}
-images: {
- urlShortener: {
- repository: "giolekva"
- name: "url-shortener"
- tag: "latest"
- pullPolicy: "Always"
+ images: {
+ urlShortener: {
+ repository: "giolekva"
+ name: "url-shortener"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
-}
-charts: {
- urlShortener: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/url-shortener"
- }
-}
+ charts: {
+ urlShortener: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/url-shortener"
+ }
+ }
-helm: {
- "url-shortener": {
- chart: charts.urlShortener
- info: "Installing server"
- values: {
- storage: {
- size: "1Gi"
- }
- image: {
- repository: images.urlShortener.fullName
- tag: images.urlShortener.tag
- pullPolicy: images.urlShortener.pullPolicy
+ volumes: data: size: input.storageSize
+
+ helm: {
+ "url-shortener": {
+ chart: charts.urlShortener
+ info: "Installing server"
+ values: {
+ image: {
+ repository: images.urlShortener.fullName
+ tag: images.urlShortener.tag
+ pullPolicy: images.urlShortener.pullPolicy
+ }
+ portName: _httpPortName
+ persistentVolumeClaimNama: volumes.data.name
+ requireAuth: input.auth.enabled
}
- portName: _httpPortName
- requireAuth: input.auth.enabled
- }
- }
+ }
+ }
}
diff --git a/core/installer/values-tmpl/vaultwarden.cue b/core/installer/values-tmpl/vaultwarden.cue
index 4b675c5..69ac75f 100644
--- a/core/installer/values-tmpl/vaultwarden.cue
+++ b/core/installer/values-tmpl/vaultwarden.cue
@@ -1,6 +1,7 @@
input: {
network: #Network @name(Network)
subdomain: string @name(Subdomain)
+ storageSize: string
}
_domain: "\(input.subdomain).\(input.network.domain)"
@@ -30,36 +31,52 @@
<path class='cls-1' d='m16.59579535,39.68503937c-.31541688,0-.63121702-.07051848-.92555501-.21155543l-1.05816041-.49976138c-.48500615-.2368501-1.24959508-.66149397-2.27996967-1.26396705-1.22238414-.71514934-2.19948662-1.35211514-3.07502717-2.00364455-1.11583992-.82092705-2.19661223-1.72003763-3.20954883-2.67050406-1.0945694-.97882712-2.11363804-2.07876206-3.01753928-3.26071305-.8868465-1.18501701-1.60889438-2.47811126-2.15023867-3.84785602-.57832816-1.42493314-.87515729-2.93341534-.87975632-4.47715678V2.24126116C.00747343,1.01102034,1.01121196.00766505,2.23762026,0h28.73053054c1.23024082.00766505,2.23397936,1.01102034,2.24145278,2.23742863v19.16109658c.00210789,1.56060455-.29472124,3.08671637-.88205584,4.53387816-.53732013,1.38124234-1.26281729,2.6911997-2.15292143,3.88541478-.90620075,1.18501701-1.92526939,2.28571846-3.03382752,3.27757616-1.01025383.92747127-2.09447541,1.80971874-3.21625575,2.6168487-1.1200557.77263722-2.08834337,1.40347099-3.0577808,1.99214697-.71150844.43230892-1.2898366.73661148-1.71198933.95889798-.20983079.11037675-.38651024.20312387-.53042159.28590643l-1.10759999.52582256c-.29203847.13950394-.6063056.21002242-.92095598.21002242ZM30.96431827,1.28006366H2.24145278c-.52505605.00306602-.95813148.43614145-.96138913.96503003v19.20248786c.00421578,1.37740981.26942657,2.72569243.78815895,4.00345657.50167764,1.27009909,1.16796227,2.46278115,1.98256566,3.55198502.85101238,1.11219902,1.8152759,2.15311306,2.86155548,3.08901589.98706705.92593826,2.02836434,1.79208912,3.10607063,2.58465548.83989805.62546823,1.77944178,1.23713937,2.96024302,1.92776054,1.24921182.73124595,1.87947071,1.0646757,2.18798905,1.21567722l1.05336975.49746186c.23934124.11420927.51068408.11420927.7469593.00153301l1.06390919-.5028274c.10941861-.06591945.30047003-.16633162.52754719-.28590643.43039266-.22688553.96579653-.50819294,1.64377037-.92057273.94778366-.57564539,1.89633382-1.19344857,2.98515444-1.94385715,1.07042449-.77033771,2.1147878-1.62039196,3.09399817-2.51873603,1.05471113-.94433439,2.01878303-1.98524843,2.87171167-3.10051347.81632802-1.09610241,1.4858703-2.30488109,1.98486517-3.58724426.5283137-1.3015258.79333286-2.66437202.79160823-4.06017796V2.24279417c-.0044074-.52812207-.43690795-.95966449-.96522165-.96273051Zm-14.35951648,33.14751666c-.11535903,0-.23033481-.03142671-.33208837-.09274713-.19124304-.11650879-.30794346-.32346519-.30794346-.5472847V5.42455718c0-.35335889.28648131-.64003183.64003183-.64003183h11.18024461c.35355052,0,.64003183.28667294.64003183.64003183v15.77237716c.01935426.06132041.02951045.12647336.02951045.1923928,0,3.12887416-2.06649797,6.31983524-6.14219766,9.48473514-1.68688628,1.31915542-3.50848585,2.49114185-5.4122931,3.48146654-.09274713.04828983-.19411744.07205149-.29529612.07205149Zm.64003183-28.3629913v26.64985222c1.49621812-.83932318,2.93245721-1.79592164,4.2805482-2.85063278,3.66581104-2.84603375,5.5638695-5.63534611,5.64626881-8.29358609-.01724637-.05518837-.02663606-.11267626-.02663606-.17169716V6.06458901h-9.90018095Z'/>
</svg>"""
-images: {
- vaultwarden: {
- repository: "vaultwarden"
- name: "server"
- tag: "1.28.1"
- pullPolicy: "IfNotPresent"
+out: {
+ ingress: {
+ vaultwarden: {
+ auth: enabled: false
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "server"
+ port: name: _httpPortName
+ }
+ }
}
-}
-charts: {
- vaultwarden: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/vaultwarden"
+ images: {
+ vaultwarden: {
+ repository: "vaultwarden"
+ name: "server"
+ tag: "1.28.1"
+ pullPolicy: "IfNotPresent"
+ }
}
-}
-helm: {
- vaultwarden: {
- chart: charts.vaultwarden
- info: "Installing Vaultwarden server"
- values: {
- ingressClassName: input.network.ingressClass
- certificateIssuer: input.network.certificateIssuer
- domain: _domain
- image: {
- repository: images.vaultwarden.fullName
- tag: images.vaultwarden.tag
- pullPolicy: images.vaultwarden.pullPolicy
+ charts: {
+ vaultwarden: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/vaultwarden"
+ }
+ }
+
+ volumes: data: size: input.storageSize
+
+ helm: {
+ vaultwarden: {
+ chart: charts.vaultwarden
+ info: "Installing Vaultwarden server"
+ values: {
+ image: {
+ repository: images.vaultwarden.fullName
+ tag: images.vaultwarden.tag
+ pullPolicy: images.vaultwarden.pullPolicy
+ }
+ domain: _domain
+ persistentVolumeClaimName: volumes.data.name
+ httpPortName: _httpPortName
}
}
}
@@ -69,3 +86,5 @@
title: "Access"
contents: "Open [\(url)](\(url)) in a new tab."
}]
+
+_httpPortName: "http"
diff --git a/core/installer/values-tmpl/virtual-machine.cue b/core/installer/values-tmpl/virtual-machine.cue
index 292c082..5b08788 100644
--- a/core/installer/values-tmpl/virtual-machine.cue
+++ b/core/installer/values-tmpl/virtual-machine.cue
@@ -11,62 +11,20 @@
readme: "Virtual Machine"
description: "Virtual Machine"
icon: """
-<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 2048 2048"><path fill="currentColor" d="M1280 384H640V256h640zm0 1024H640v-128h640zm0 256H640v-128h640zM1408 0q27 0 50 10t40 27t28 41t10 50v1792H384V128q0-27 10-50t27-40t41-28t50-10zm0 128H512v1664h896z"/></svg>"""
+ <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 2048 2048"><path fill="currentColor" d="M1280 384H640V256h640zm0 1024H640v-128h640zm0 256H640v-128h640zM1408 0q27 0 50 10t40 27t28 41t10 50v1792H384V128q0-27 10-50t27-40t41-28t50-10zm0 128H512v1664h896z"/></svg>"""
-charts: {
- virtualMachine: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/virtual-machine"
- }
-}
-
-helm: {
- "virtual-machine": {
- chart: charts.virtualMachine
- values: {
- name: input.name
+out: {
+ vm: {
+ "\(input.name)": {
+ username: input.username
+ domain: global.domain
cpuCores: input.cpuCores
memory: input.memory
- disk: {
- source: "https://cloud.debian.org/images/cloud/bookworm-backports/latest/debian-12-backports-generic-amd64.qcow2"
- size: "64Gi"
+ vpn: {
+ enabled: true
+ loginServer: "https://headscale.\(global.domain)"
+ authKey: input.authKey
}
- ports: [22, 8080]
- cloudInit: userData: _cloudInitUserData
}
}
}
-
-_cloudInitUserData: {
- system_info: {
- default_user: {
- name: input.username
- home: "/home/\(input.username)"
- }
- }
- password: "dodo" // TODO(gio): remove if possible
- chpasswd: {
- expire: false
- }
- hostname: input.name
- ssh_pwauth: true
- disable_root: false
- ssh_authorized_keys: [
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOa7FUrmXzdY3no8qNGUk7OPaRcIUi8G7MVbLlff9eB/ lekva@gl-mbp-m1-max.local"
- ]
- runcmd: [
- ["sh", "-c", "curl -fsSL https://tailscale.com/install.sh | sh"],
- // TODO(gio): take auth key from input
- // TODO(gio): enable tailscale ssh
- ["sh", "-c", "tailscale up --login-server=https://headscale.\(global.domain) --auth-key=\(input.authKey) --accept-routes"],
- ["sh", "-c", "curl -fsSL https://code-server.dev/install.sh | HOME=/home/\(input.username) sh"],
- ["sh", "-c", "systemctl enable --now code-server@\(input.username)"],
- ["sh", "-c", "sleep 10"],
- // TODO(gio): listen only on tailscale interface
- ["sh", "-c", "sed -i -e 's/127.0.0.1/0.0.0.0/g' /home/\(input.username)/.config/code-server/config.yaml"],
- ["sh", "-c", "sed -i -e 's/auth: password/auth: none/g' /home/\(input.username)/.config/code-server/config.yaml"],
- ["sh", "-c", "systemctl restart --now code-server@\(input.username)"],
- ]
-}
diff --git a/core/installer/values-tmpl/welcome.cue b/core/installer/values-tmpl/welcome.cue
index 2d68207..6022fb7 100644
--- a/core/installer/values-tmpl/welcome.cue
+++ b/core/installer/values-tmpl/welcome.cue
@@ -11,43 +11,45 @@
name: "welcome"
namespace: "app-welcome"
-images: {
- welcome: {
- repository: "giolekva"
- name: "pcloud-installer"
- tag: "latest"
- pullPolicy: "Always"
+out: {
+ images: {
+ welcome: {
+ repository: "giolekva"
+ name: "pcloud-installer"
+ tag: "latest"
+ pullPolicy: "Always"
+ }
}
-}
-charts: {
- welcome: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/welcome"
+ charts: {
+ welcome: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/welcome"
+ }
}
-}
-helm: {
- welcome: {
- chart: charts.welcome
- values: {
- repoAddr: input.repoAddr
- sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
- createAccountAddr: "http://api.\(global.namespacePrefix)core-auth.svc.cluster.local/identities"
- loginAddr: "https://launcher.\(networks.public.domain)"
- membershipsAddr: "http://memberships-api.\(global.namespacePrefix)core-auth-memberships.svc.cluster.local"
- ingress: {
- className: input.network.ingressClass
- domain: "welcome.\(input.network.domain)"
- certificateIssuer: input.network.certificateIssuer
- }
- clusterRoleName: "\(global.id)-welcome"
- image: {
- repository: images.welcome.fullName
- tag: images.welcome.tag
- pullPolicy: images.welcome.pullPolicy
+ helm: {
+ welcome: {
+ chart: charts.welcome
+ values: {
+ repoAddr: input.repoAddr
+ sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
+ createAccountAddr: "http://api.\(global.namespacePrefix)core-auth.svc.cluster.local/identities"
+ loginAddr: "https://launcher.\(networks.public.domain)"
+ membershipsAddr: "http://memberships-api.\(global.namespacePrefix)core-auth-memberships.svc.cluster.local"
+ ingress: {
+ className: input.network.ingressClass
+ domain: "welcome.\(input.network.domain)"
+ certificateIssuer: input.network.certificateIssuer
+ }
+ clusterRoleName: "\(global.id)-welcome"
+ image: {
+ repository: images.welcome.fullName
+ tag: images.welcome.tag
+ pullPolicy: images.welcome.pullPolicy
+ }
}
}
}
diff --git a/core/installer/values-tmpl/zot.cue b/core/installer/values-tmpl/zot.cue
index 35fdbc7..c5cf631 100644
--- a/core/installer/values-tmpl/zot.cue
+++ b/core/installer/values-tmpl/zot.cue
@@ -39,153 +39,155 @@
</g>
</svg>"""
-ingress: {
- zot: {
- auth: enabled: false
- network: input.network
- subdomain: input.subdomain
- service: {
- name: "zot"
- port: number: _httpPort // TODO(gio): make optional
+out: {
+ ingress: {
+ zot: {
+ auth: enabled: false
+ network: input.network
+ subdomain: input.subdomain
+ service: {
+ name: "zot"
+ port: number: _httpPort // TODO(gio): make optional
+ }
}
}
-}
-// TODO(gio): configure busybox
-images: {
- zot: {
- registry: "ghcr.io"
- repository: "project-zot"
- name: "zot-linux-amd64"
- tag: "v2.0.3"
- pullPolicy: "IfNotPresent"
- }
-}
-
-charts: {
- zot: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/zot"
- }
- oauth2Client: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/oauth2-client"
- }
- resourceRenderer: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/resource-renderer"
- }
-}
-
-volumes: zot: size: "100Gi"
-
-_httpPort: 80
-_oauth2ClientSecretName: "oauth2-client"
-
-helm: {
- "oauth2-client": {
- chart: charts.oauth2Client
- info: "Creating OAuth2 client"
- // TODO(gio): remove once hydra maester is installed as part of dodo itself
- dependsOn: [{
- name: "auth"
- namespace: "\(global.namespacePrefix)core-auth"
- }]
- values: {
- name: "\(release.namespace)-zot"
- secretName: _oauth2ClientSecretName
- grantTypes: ["authorization_code"]
- responseTypes: ["code"]
- scope: "openid profile email groups"
- redirectUris: ["https://\(_domain)/zot/auth/callback/oidc"]
- hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
+ // TODO(gio): configure busybox
+ images: {
+ zot: {
+ registry: "ghcr.io"
+ repository: "project-zot"
+ name: "zot-linux-amd64"
+ tag: "v2.0.3"
+ pullPolicy: "IfNotPresent"
}
}
- "config-renderer": {
- chart: charts.resourceRenderer
- info: "Generating Zot configuration"
- values: {
- name: "config-renderer"
- secretName: _oauth2ClientSecretName
- resourceTemplate: yaml.Marshal({
- apiVersion: "v1"
- kind: "ConfigMap"
- metadata: {
- name: _zotConfigMapName
- namespace: "\(release.namespace)"
- }
- data: {
- "config.json": json.Marshal({
- storage: rootDirectory: "/var/lib/registry"
- http: {
- address: "0.0.0.0"
- port: "5000"
- externalUrl: url
- auth: openid: providers: oidc: {
- name: "dodo:"
- issuer: "https://hydra.\(networks.public.domain)"
- clientid: "{{ .client_id }}"
- clientsecret: "{{ .client_secret }}"
- keypath: ""
- scopes: ["openid", "profile", "email", "groups"]
- }
- accessControl: {
- repositories: {
- "**": {
- defaultPolicy: ["read", "create", "update", "delete"]
- anonymousPolicy: ["read"]
+
+ charts: {
+ zot: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/zot"
+ }
+ oauth2Client: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/oauth2-client"
+ }
+ resourceRenderer: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/resource-renderer"
+ }
+ }
+
+ volumes: zot: size: "100Gi"
+
+ _httpPort: 80
+ _oauth2ClientSecretName: "oauth2-client"
+
+ helm: {
+ "oauth2-client": {
+ chart: charts.oauth2Client
+ info: "Creating OAuth2 client"
+ // TODO(gio): remove once hydra maester is installed as part of dodo itself
+ dependsOn: [{
+ name: "auth"
+ namespace: "\(global.namespacePrefix)core-auth"
+ }]
+ values: {
+ name: "\(release.namespace)-zot"
+ secretName: _oauth2ClientSecretName
+ grantTypes: ["authorization_code"]
+ responseTypes: ["code"]
+ scope: "openid profile email groups"
+ redirectUris: ["https://\(_domain)/zot/auth/callback/oidc"]
+ hydraAdmin: "http://hydra-admin.\(global.namespacePrefix)core-auth.svc.cluster.local"
+ }
+ }
+ "config-renderer": {
+ chart: charts.resourceRenderer
+ info: "Generating Zot configuration"
+ values: {
+ name: "config-renderer"
+ secretName: _oauth2ClientSecretName
+ resourceTemplate: yaml.Marshal({
+ apiVersion: "v1"
+ kind: "ConfigMap"
+ metadata: {
+ name: _zotConfigMapName
+ namespace: "\(release.namespace)"
+ }
+ data: {
+ "config.json": json.Marshal({
+ storage: rootDirectory: "/var/lib/registry"
+ http: {
+ address: "0.0.0.0"
+ port: "5000"
+ externalUrl: url
+ auth: openid: providers: oidc: {
+ name: "dodo:"
+ issuer: "https://hydra.\(networks.public.domain)"
+ clientid: "{{ .client_id }}"
+ clientsecret: "{{ .client_secret }}"
+ keypath: ""
+ scopes: ["openid", "profile", "email", "groups"]
+ }
+ accessControl: {
+ repositories: {
+ "**": {
+ defaultPolicy: ["read", "create", "update", "delete"]
+ anonymousPolicy: ["read"]
+ }
}
}
}
- }
- log: level: "debug"
- extensions: {
- ui: enable: true
- search: enable: true
- }
- })
- }
- })
+ log: level: "debug"
+ extensions: {
+ ui: enable: true
+ search: enable: true
+ }
+ })
+ }
+ })
+ }
}
- }
- zot: {
- chart: charts.zot
- info: "Installing Zot server"
- values: {
- image: {
- repository: images.zot.fullName
- tag: images.zot.tag
- pullPolicy: images.zot.pullPolicy
- }
- service: {
- type: "ClusterIP"
- additionalAnnotations: {
- "metallb.universe.tf/address-pool": global.id
+ zot: {
+ chart: charts.zot
+ info: "Installing Zot server"
+ values: {
+ image: {
+ repository: images.zot.fullName
+ tag: images.zot.tag
+ pullPolicy: images.zot.pullPolicy
}
- port: _httpPort
+ service: {
+ type: "ClusterIP"
+ additionalAnnotations: {
+ "metallb.universe.tf/address-pool": global.id
+ }
+ port: _httpPort
+ }
+ ingress: enabled: false
+ mountConfig: false
+ persistence: true
+ pvc: {
+ create: false
+ name: volumes.zot.name
+ }
+ extraVolumes: [{
+ name: "config"
+ configMap: name: _zotConfigMapName
+ }]
+ extraVolumeMounts: [{
+ name: "config"
+ mountPath: "/etc/zot"
+ }]
+ startupProbe: {}
}
- ingress: enabled: false
- mountConfig: false
- persistence: true
- pvc: {
- create: false
- name: volumes.zot.name
- }
- extraVolumes: [{
- name: "config"
- configMap: name: _zotConfigMapName
- }]
- extraVolumeMounts: [{
- name: "config"
- mountPath: "/etc/zot"
- }]
- startupProbe: {}
}
}
}
diff --git a/core/installer/welcome/app_tmpl.go b/core/installer/welcome/app_tmpl.go
index 33f8d8d..fb512fa 100644
--- a/core/installer/welcome/app_tmpl.go
+++ b/core/installer/welcome/app_tmpl.go
@@ -1,15 +1,14 @@
package welcome
import (
+ "bytes"
"fmt"
- "io"
"io/fs"
"sort"
"strings"
"text/template"
"github.com/giolekva/pcloud/core/installer"
- "github.com/giolekva/pcloud/core/installer/soft"
)
const tmplSuffix = ".gotmpl"
@@ -69,7 +68,7 @@
}
type AppTmpl interface {
- Render(network installer.Network, subdomain string, out soft.RepoFS) error
+ Render(network installer.Network, subdomain string) (map[string][]byte, error)
}
type appTmplFS struct {
@@ -109,29 +108,20 @@
return &appTmplFS{files, tmpls}, nil
}
-func (a *appTmplFS) Render(network installer.Network, subdomain string, out soft.RepoFS) error {
+func (a *appTmplFS) Render(network installer.Network, subdomain string) (map[string][]byte, error) {
+ ret := map[string][]byte{}
+ for path, contents := range a.files {
+ ret[path] = contents
+ }
for path, tmpl := range a.tmpls {
- f, err := out.Writer(path)
- if err != nil {
- return err
- }
- defer f.Close()
- if err := tmpl.Execute(f, map[string]any{
+ var buf bytes.Buffer
+ if err := tmpl.Execute(&buf, map[string]any{
"Network": network,
"Subdomain": subdomain,
}); err != nil {
- return err
+ return nil, err
}
+ ret[path] = buf.Bytes()
}
- for path, contents := range a.files {
- f, err := out.Writer(path)
- if err != nil {
- return err
- }
- defer f.Close()
- if _, err := io.WriteString(f, string(contents)); err != nil {
- return err
- }
- }
- return nil
+ return ret, nil
}
diff --git a/core/installer/welcome/app_tmpl_test.go b/core/installer/welcome/app_tmpl_test.go
index daaf4c8..00e5a3c 100644
--- a/core/installer/welcome/app_tmpl_test.go
+++ b/core/installer/welcome/app_tmpl_test.go
@@ -6,10 +6,7 @@
"io/fs"
"testing"
- "github.com/go-git/go-billy/v5/memfs"
-
"github.com/giolekva/pcloud/core/installer"
- "github.com/giolekva/pcloud/core/installer/soft"
)
//go:embed app-tmpl
@@ -38,8 +35,7 @@
if err != nil {
t.Fatal(err)
}
- out := soft.NewBillyRepoFS(memfs.New())
- if err := a.Render(network, "testapp", out); err != nil {
+ if _, err := a.Render(network, "testapp"); err != nil {
t.Fatal(err)
}
}
@@ -57,8 +53,7 @@
if err != nil {
t.Fatal(err)
}
- out := soft.NewBillyRepoFS(memfs.New())
- if err := a.Render(network, "testapp", out); err != nil {
+ if _, err := a.Render(network, "testapp"); err != nil {
t.Fatal(err)
}
}
@@ -76,8 +71,7 @@
if err != nil {
t.Fatal(err)
}
- out := soft.NewBillyRepoFS(memfs.New())
- if err := a.Render(network, "testapp", out); err != nil {
+ if _, err := a.Render(network, "testapp"); err != nil {
t.Fatal(err)
}
}
diff --git a/core/installer/welcome/appmanager-tmpl/app.html b/core/installer/welcome/appmanager-tmpl/app.html
index b25f5b1..c6874cb 100644
--- a/core/installer/welcome/appmanager-tmpl/app.html
+++ b/core/installer/welcome/appmanager-tmpl/app.html
@@ -31,9 +31,9 @@
{{ else if eq $schema.Kind 1 }}
<label {{ if $schema.Advanced }}hidden{{ end }}>
{{ $schema.Name }}
- <input type="text" name="{{ $name }}" oninput="valueChanged({{ $name }}, this.value)" {{ if $readonly }}disabled{{ end }} value="{{ index $data $name }}" />
+ <input type="text" name="{{ $name }}" oninput="valueChanged({{ $name }}, this.value)" {{ if $readonly }}disabled{{ end }} value="{{ index $data $name }}" />
+ </label>
{{ else if eq $schema.Kind 4 }}
- </label>
<label {{ if $schema.Advanced }}hidden{{ end }}>
{{ $schema.Name }}
<input type="text" name="{{ $name }}" oninput="valueChanged({{ $name }}, this.value)" {{ if $readonly }}disabled{{ end }} value="{{ index $data $name }}" />
diff --git a/core/installer/welcome/appmanager.go b/core/installer/welcome/appmanager.go
index 82421e9..7f168dc 100644
--- a/core/installer/welcome/appmanager.go
+++ b/core/installer/welcome/appmanager.go
@@ -163,7 +163,7 @@
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
- instances, err := s.m.FindAllAppInstances(slug)
+ instances, err := s.m.GetAllAppInstances(slug)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -182,7 +182,7 @@
http.Error(w, "empty slug", http.StatusBadRequest)
return
}
- instance, err := s.m.FindInstance(slug)
+ instance, err := s.m.GetInstance(slug)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -339,7 +339,7 @@
}
resp := make([]app, 0)
for _, a := range apps {
- instances, err := s.m.FindAllAppInstances(a.Slug())
+ instances, err := s.m.GetAllAppInstances(a.Slug())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -393,7 +393,7 @@
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
- instances, err := s.m.FindAllAppInstances(slug)
+ instances, err := s.m.GetAllAppInstances(slug)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -427,7 +427,7 @@
return
}
t, ok := s.tasks[slug]
- instance, err := s.m.FindInstance(slug)
+ instance, err := s.m.GetInstance(slug)
if err != nil && !ok {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -446,7 +446,7 @@
panic("MUST NOT REACH!")
}
}
- instances, err := s.m.FindAllAppInstances(a.Slug())
+ instances, err := s.m.GetAllAppInstances(a.Slug())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
diff --git a/core/installer/welcome/dodo-app-tmpl/app_status.html b/core/installer/welcome/dodo-app-tmpl/app_status.html
index e96b801..916525e 100644
--- a/core/installer/welcome/dodo-app-tmpl/app_status.html
+++ b/core/installer/welcome/dodo-app-tmpl/app_status.html
@@ -3,11 +3,23 @@
{{ end }}
{{- define "content" -}}
{{ .GitCloneCommand }}<br/>
+<form action="/{{ .Name }}/dev-branch/create" method="POST">
+ <fieldset class="grid">
+ <input type="text" name="branch" placeholder="branch" />
+ <button id="create-dev-branch-button" aria-busy="false" type="submit" name="create-dev-branch">create dev branch</button>
+ </fieldset>
+</form>
<a href="/{{ .Name }}/logs">Logs</a>
<hr class="divider">
{{- template "resources" .LastCommit -}}
<hr class="divider">
+<h3>Commit History</h3>
{{- range .Commits -}}
{{if eq .Status "OK" }}<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="black" d="M21 7L9 19l-5.5-5.5l1.41-1.41L9 16.17L19.59 5.59z"/></svg>{{ else }}<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 48 48"><path fill="black" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="4" d="M6 11L11 6L24 19L37 6L42 11L29 24L42 37L37 42L24 29L11 42L6 37L19 24L6 11Z" clip-rule="evenodd"/></svg>{{ end }} <a href="/{{ $.Name }}/{{ .Hash }}">{{ .Hash }}</a> {{ .Message }}<br/>
{{- end -}}
+<hr class="divider">
+<h3>Branches</h3>
+{{- range .Branches -}}
+<a href="/{{ $.Name }}/branch/{{ . }}">{{ . }}</a><br/>
+{{- end -}}
{{- end -}}
diff --git a/core/installer/welcome/dodo-app-tmpl/base.html b/core/installer/welcome/dodo-app-tmpl/base.html
index 644ff41..4e9401b 100644
--- a/core/installer/welcome/dodo-app-tmpl/base.html
+++ b/core/installer/welcome/dodo-app-tmpl/base.html
@@ -20,11 +20,20 @@
</body>
</html>
{{ define "resources" }}
-{{- if gt (len .Volume) 0 -}}
-<h3>Volumes</h3>
-{{- range $v := .Volume -}}
-Name: {{ $v.Name }}<br/>
-Size: {{ $v.Size }}<br/>
+{{- if gt (len .Ingress) 0 -}}
+<h3>Ingress</h3>
+{{- range $i := .Ingress -}}
+Host: <a href="{{ $i.Host }}">{{ $i.Host }}</a><br/>
+<br/>
+{{- end -}}
+{{- end -}}
+{{- if gt (len .VirtualMachine) 0 -}}
+<h3>Virtual Machine</h3>
+{{- range $i := .VirtualMachine -}}
+Name: {{ $i.Name }}<br/>
+User: {{ $i.User }}<br/>
+CPU Cores: {{ $i.CPUCores }}<br/>
+Memory: {{ $i.Memory }}<br/>
<br/>
{{- end -}}
{{- end -}}
@@ -37,10 +46,11 @@
<br/>
{{- end -}}
{{- end -}}
-{{- if gt (len .Ingress) 0 -}}
-<h3>Ingress</h3>
-{{- range $i := .Ingress -}}
-Host: {{ $i.Host }}<br/>
+{{- if gt (len .Volume) 0 -}}
+<h3>Volumes</h3>
+{{- range $v := .Volume -}}
+Name: {{ $v.Name }}<br/>
+Size: {{ $v.Size }}<br/>
<br/>
{{- end -}}
{{- end -}}
diff --git a/core/installer/welcome/dodo_app.go b/core/installer/welcome/dodo_app.go
index bd72aef..57de8b2 100644
--- a/core/installer/welcome/dodo_app.go
+++ b/core/installer/welcome/dodo_app.go
@@ -12,6 +12,7 @@
"io/fs"
"net/http"
"slices"
+ "strconv"
"strings"
"sync"
"time"
@@ -23,6 +24,7 @@
"github.com/giolekva/pcloud/core/installer/soft"
"github.com/giolekva/pcloud/core/installer/tasks"
+ "cuelang.org/go/cue"
"github.com/gorilla/mux"
"github.com/gorilla/securecookie"
)
@@ -194,7 +196,21 @@
return s, nil
}
+func (s *DodoAppServer) getAppConfig(app, branch string) appConfig {
+ return s.appConfigs[fmt.Sprintf("%s-%s", app, branch)]
+}
+
+func (s *DodoAppServer) setAppConfig(app, branch string, cfg appConfig) {
+ s.appConfigs[fmt.Sprintf("%s-%s", app, branch)] = cfg
+}
+
func (s *DodoAppServer) Start() error {
+ // if err := s.client.DisableKeyless(); err != nil {
+ // return err
+ // }
+ // if err := s.client.DisableAnonAccess(); err != nil {
+ // return err
+ // }
e := make(chan error)
go func() {
r := mux.NewRouter()
@@ -207,6 +223,8 @@
r.HandleFunc("/{app-name}"+loginPath, s.handleLogin).Methods(http.MethodPost)
r.HandleFunc("/{app-name}/logs", s.handleAppLogs).Methods(http.MethodGet)
r.HandleFunc("/{app-name}/{hash}", s.handleAppCommit).Methods(http.MethodGet)
+ r.HandleFunc("/{app-name}/dev-branch/create", s.handleCreateDevBranch).Methods(http.MethodPost)
+ r.HandleFunc("/{app-name}/branch/{branch}", s.handleAppStatus).Methods(http.MethodGet)
r.HandleFunc("/{app-name}", s.handleAppStatus).Methods(http.MethodGet)
r.HandleFunc("/", s.handleStatus).Methods(http.MethodGet)
r.HandleFunc("/", s.handleCreateApp).Methods(http.MethodPost)
@@ -216,7 +234,7 @@
r := mux.NewRouter()
r.HandleFunc("/update", s.handleAPIUpdate)
r.HandleFunc("/api/apps/{app-name}/workers", s.handleAPIRegisterWorker).Methods(http.MethodPost)
- r.HandleFunc("/api/add-admin-key", s.handleAPIAddAdminKey).Methods(http.MethodPost)
+ r.HandleFunc("/api/add-public-key", s.handleAPIAddPublicKey).Methods(http.MethodPost)
if !s.external {
r.HandleFunc("/api/sync-users", s.handleAPISyncUsers).Methods(http.MethodGet)
}
@@ -224,7 +242,6 @@
}()
if !s.external {
go func() {
- rand.Seed(uint64(time.Now().UnixNano()))
s.syncUsers()
for {
delay := time.Duration(rand.Intn(60)+60) * time.Second
@@ -434,6 +451,7 @@
GitCloneCommand string
Commits []CommitMeta
LastCommit resourceData
+ Branches []string
}
func (s *DodoAppServer) handleAppStatus(w http.ResponseWriter, r *http.Request) {
@@ -443,6 +461,10 @@
http.Error(w, "missing app-name", http.StatusBadRequest)
return
}
+ branch, ok := vars["branch"]
+ if !ok || branch == "" {
+ branch = "master"
+ }
u := r.Context().Value(userCtx)
if u == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
@@ -462,7 +484,7 @@
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
- commits, err := s.st.GetCommitHistory(appName)
+ commits, err := s.st.GetCommitHistory(appName, branch)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -481,6 +503,11 @@
}
lastCommitResources = r
}
+ branches, err := s.st.GetBranches(appName)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
data := appStatusData{
Navigation: []navItem{
navItem{"Home", "/"},
@@ -490,6 +517,10 @@
GitCloneCommand: fmt.Sprintf("git clone %s/%s\n\n\n", s.repoPublicAddr, appName),
Commits: commits,
LastCommit: lastCommitResources,
+ Branches: branches,
+ }
+ if branch != "master" {
+ data.Navigation = append(data.Navigation, navItem{branch, fmt.Sprintf("/%s/branch/%s", appName, branch)})
}
if err := s.tmplts.appStatus.Execute(w, data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -512,10 +543,18 @@
Host string
}
+type vm struct {
+ Name string
+ User string
+ CPUCores int
+ Memory string
+}
+
type resourceData struct {
- Volume []volume
- PostgreSQL []postgresql
- Ingress []ingress
+ Volume []volume
+ PostgreSQL []postgresql
+ Ingress []ingress
+ VirtualMachine []vm
}
type commitStatusData struct {
@@ -659,7 +698,12 @@
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
- if req.Ref != "refs/heads/master" || req.Repository.Name == ConfigRepoName {
+ if strings.HasPrefix(req.Ref, "refs/heads/dodo_") || req.Repository.Name == ConfigRepoName {
+ return
+ }
+ branch, ok := strings.CutPrefix(req.Ref, "refs/heads/")
+ if !ok {
+ http.Error(w, "invalid branch", http.StatusBadRequest)
return
}
// TODO(gio): Create commit record on app init as well
@@ -690,8 +734,10 @@
fmt.Printf("Error: could not find commit message")
return
}
- resources, err := s.updateDodoApp(instanceAppStatus, req.Repository.Name, s.appConfigs[req.Repository.Name].Namespace, networks)
- if err = s.createCommit(req.Repository.Name, req.After, commitMsg, err, resources); err != nil {
+ s.l.Lock()
+ defer s.l.Unlock()
+ resources, err := s.updateDodoApp(instanceAppStatus, req.Repository.Name, branch, s.getAppConfig(req.Repository.Name, branch).Namespace, networks, owner)
+ if err = s.createCommit(req.Repository.Name, branch, req.After, commitMsg, err, resources); err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
@@ -710,6 +756,7 @@
}
func (s *DodoAppServer) handleAPIRegisterWorker(w http.ResponseWriter, r *http.Request) {
+ // TODO(gio): lock
vars := mux.Vars(r)
appName, ok := vars["app-name"]
if !ok || appName == "" {
@@ -782,6 +829,35 @@
http.Redirect(w, r, fmt.Sprintf("/%s", appName), http.StatusSeeOther)
}
+func (s *DodoAppServer) handleCreateDevBranch(w http.ResponseWriter, r *http.Request) {
+ u := r.Context().Value(userCtx)
+ if u == nil {
+ http.Error(w, "unauthorized", http.StatusUnauthorized)
+ return
+ }
+ user, ok := u.(string)
+ if !ok {
+ http.Error(w, "could not get user", http.StatusInternalServerError)
+ return
+ }
+ vars := mux.Vars(r)
+ appName, ok := vars["app-name"]
+ if !ok || appName == "" {
+ http.Error(w, "missing app-name", http.StatusBadRequest)
+ return
+ }
+ branch := r.FormValue("branch")
+ if branch == "" {
+ http.Error(w, "missing network", http.StatusBadRequest)
+ return
+ }
+ if err := s.createDevBranch(appName, "master", branch, user); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ http.Redirect(w, r, fmt.Sprintf("/%s/branch/%s", appName, branch), http.StatusSeeOther)
+}
+
type apiCreateAppReq struct {
AppType string `json:"type"`
AdminPublicKey string `json:"adminPublicKey"`
@@ -889,7 +965,52 @@
if err != nil {
return err
}
- commit, err := s.initRepo(appRepo, appType, n, subdomain)
+ files, err := s.renderAppConfigTemplate(appType, n, subdomain)
+ if err != nil {
+ return err
+ }
+ return s.createAppForBranch(appRepo, appName, "master", user, network, files)
+}
+
+func (s *DodoAppServer) createDevBranch(appName, fromBranch, toBranch, user string) error {
+ s.l.Lock()
+ defer s.l.Unlock()
+ fmt.Printf("Creating dev branch app: %s %s %s\n", appName, fromBranch, toBranch)
+ appRepo, err := s.client.GetRepoBranch(appName, fromBranch)
+ if err != nil {
+ return err
+ }
+ appCfg, err := soft.ReadFile(appRepo, "app.cue")
+ if err != nil {
+ return err
+ }
+ network, branchCfg, err := createDevBranchAppConfig(appCfg, toBranch, user)
+ if err != nil {
+ return err
+ }
+ return s.createAppForBranch(appRepo, appName, toBranch, user, network, map[string][]byte{"app.cue": branchCfg})
+}
+
+func (s *DodoAppServer) createAppForBranch(
+ repo soft.RepoIO,
+ appName string,
+ branch string,
+ user string,
+ network string,
+ files map[string][]byte,
+) error {
+ commit, err := repo.Do(func(fs soft.RepoFS) (string, error) {
+ for path, contents := range files {
+ if err := soft.WriteFile(fs, path, string(contents)); err != nil {
+ return "", err
+ }
+ }
+ return "init", nil
+ }, soft.WithCommitToBranch(branch))
+ if err != nil {
+ return err
+ }
+ networks, err := s.getNetworks(user)
if err != nil {
return err
}
@@ -908,12 +1029,13 @@
return err
}
namespace := fmt.Sprintf("%s%s%s", s.env.NamespacePrefix, instanceApp.Namespace(), suffix)
- s.appConfigs[appName] = appConfig{namespace, network}
- resources, err := s.updateDodoApp(instanceAppStatus, appName, namespace, networks)
+ s.setAppConfig(appName, branch, appConfig{namespace, network})
+ resources, err := s.updateDodoApp(instanceAppStatus, appName, branch, namespace, networks, user)
if err != nil {
+ fmt.Printf("Error: %s\n", err.Error())
return err
}
- if err = s.createCommit(appName, commit, initCommitMsg, err, resources); err != nil {
+ if err = s.createCommit(appName, branch, commit, initCommitMsg, err, resources); err != nil {
fmt.Printf("Error: %s\n", err.Error())
return err
}
@@ -926,6 +1048,7 @@
if err != nil {
return err
}
+ appPath := fmt.Sprintf("/%s/%s", appName, branch)
_, err = configRepo.Do(func(fs soft.RepoFS) (string, error) {
w, err := fs.Writer(appConfigsFile)
if err != nil {
@@ -938,11 +1061,12 @@
if _, err := m.Install(
instanceApp,
appName,
- "/"+appName,
+ appPath,
namespace,
map[string]any{
"repoAddr": s.client.GetRepoAddress(appName),
"repoHost": strings.Split(s.client.Address(), ":")[0],
+ "branch": fmt.Sprintf("dodo_%s", branch),
"gitRepoPublicKey": s.gitRepoPublicKey,
},
installer.WithConfig(&s.env),
@@ -957,7 +1081,11 @@
if err != nil {
return err
}
- cfg, err := m.FindInstance(appName)
+ return s.initAppACLs(m, appPath, appName, branch, user)
+}
+
+func (s *DodoAppServer) initAppACLs(m *installer.AppManager, path, appName, branch, user string) error {
+ cfg, err := m.GetInstance(path)
if err != nil {
return err
}
@@ -980,13 +1108,16 @@
return err
}
}
+ if branch != "master" {
+ return nil
+ }
if err := s.client.AddReadOnlyCollaborator(appName, "fluxcd"); err != nil {
return err
}
- if err := s.client.AddWebhook(appName, fmt.Sprintf("http://%s/update", s.self), "--active=true", "--events=push", "--content-type=json"); err != nil {
+ if err := s.client.AddReadWriteCollaborator(appName, user); err != nil {
return err
}
- if err := s.client.AddReadWriteCollaborator(appName, user); err != nil {
+ if err := s.client.AddWebhook(appName, fmt.Sprintf("http://%s/update", s.self), "--active=true", "--events=push", "--content-type=json"); err != nil {
return err
}
if !s.external {
@@ -1010,16 +1141,25 @@
}
type apiAddAdminKeyReq struct {
- Public string `json:"public"`
+ User string `json:"user"`
+ PublicKey string `json:"publicKey"`
}
-func (s *DodoAppServer) handleAPIAddAdminKey(w http.ResponseWriter, r *http.Request) {
+func (s *DodoAppServer) handleAPIAddPublicKey(w http.ResponseWriter, r *http.Request) {
var req apiAddAdminKeyReq
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
- if err := s.client.AddPublicKey("admin", req.Public); err != nil {
+ if req.User == "" {
+ http.Error(w, "invalid user", http.StatusBadRequest)
+ return
+ }
+ if req.PublicKey == "" {
+ http.Error(w, "invalid public key", http.StatusBadRequest)
+ return
+ }
+ if err := s.client.AddPublicKey(req.User, req.PublicKey); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@@ -1037,12 +1177,16 @@
} `json:"input"`
}
+// TODO(gio): must not require owner, now we need it to bootstrap dev vm.
func (s *DodoAppServer) updateDodoApp(
appStatus installer.EnvApp,
- name, namespace string,
+ name string,
+ branch string,
+ namespace string,
networks []installer.Network,
+ owner string,
) (installer.ReleaseResources, error) {
- repo, err := s.client.GetRepo(name)
+ repo, err := s.client.GetRepoBranch(name, branch)
if err != nil {
return installer.ReleaseResources{}, err
}
@@ -1068,10 +1212,13 @@
"/.dodo/app",
namespace,
map[string]any{
- "repoAddr": repo.FullAddress(),
- "managerAddr": fmt.Sprintf("http://%s", s.self),
- "appId": name,
- "sshPrivateKey": s.sshKey,
+ "repoAddr": repo.FullAddress(),
+ "repoPublicAddr": s.repoPublicAddr,
+ "managerAddr": fmt.Sprintf("http://%s", s.self),
+ "appId": name,
+ "branch": branch,
+ "sshPrivateKey": s.sshKey,
+ "username": owner,
},
installer.WithNoPull(),
installer.WithNoPublish(),
@@ -1108,7 +1255,7 @@
}
return "install app", nil
},
- soft.WithCommitToBranch("dodo"),
+ soft.WithCommitToBranch(fmt.Sprintf("dodo_%s", branch)),
soft.WithForce(),
); err != nil {
return installer.ReleaseResources{}, err
@@ -1118,18 +1265,13 @@
return ret, nil
}
-func (s *DodoAppServer) initRepo(repo soft.RepoIO, appType string, network installer.Network, subdomain string) (string, error) {
+func (s *DodoAppServer) renderAppConfigTemplate(appType string, network installer.Network, subdomain string) (map[string][]byte, error) {
appType = strings.Replace(appType, ":", "-", 1)
appTmpl, err := s.appTmpls.Find(appType)
if err != nil {
- return "", err
+ return nil, err
}
- return repo.Do(func(fs soft.RepoFS) (string, error) {
- if err := appTmpl.Render(network, subdomain, repo); err != nil {
- return "", err
- }
- return initCommitMsg, nil
- })
+ return appTmpl.Render(network, subdomain)
}
func generatePassword() string {
@@ -1183,10 +1325,10 @@
}
}
-func (s *DodoAppServer) createCommit(name, hash, message string, err error, resources installer.ReleaseResources) error {
+func (s *DodoAppServer) createCommit(name, branch, hash, message string, err error, resources installer.ReleaseResources) error {
if err != nil {
fmt.Printf("Error: %s\n", err.Error())
- if err := s.st.CreateCommit(name, hash, message, "FAILED", err.Error(), nil); err != nil {
+ if err := s.st.CreateCommit(name, branch, hash, message, "FAILED", err.Error(), nil); err != nil {
fmt.Printf("Error: %s\n", err.Error())
return err
}
@@ -1194,13 +1336,13 @@
}
var resB bytes.Buffer
if err := json.NewEncoder(&resB).Encode(resources); err != nil {
- if err := s.st.CreateCommit(name, hash, message, "FAILED", err.Error(), nil); err != nil {
+ if err := s.st.CreateCommit(name, branch, hash, message, "FAILED", err.Error(), nil); err != nil {
fmt.Printf("Error: %s\n", err.Error())
return err
}
return err
}
- if err := s.st.CreateCommit(name, hash, message, "OK", "", resB.Bytes()); err != nil {
+ if err := s.st.CreateCommit(name, branch, hash, message, "OK", "", resB.Bytes()); err != nil {
fmt.Printf("Error: %s\n", err.Error())
return err
}
@@ -1446,9 +1588,75 @@
return resourceData{}, fmt.Errorf("no host")
}
ret.Ingress = append(ret.Ingress, ingress{host})
+ case "virtual-machine":
+ name, ok := r.Annotations["dodo.cloud/resource.virtual-machine.name"]
+ if !ok {
+ return resourceData{}, fmt.Errorf("no name")
+ }
+ user, ok := r.Annotations["dodo.cloud/resource.virtual-machine.user"]
+ if !ok {
+ return resourceData{}, fmt.Errorf("no user")
+ }
+ cpuCoresS, ok := r.Annotations["dodo.cloud/resource.virtual-machine.cpu-cores"]
+ if !ok {
+ return resourceData{}, fmt.Errorf("no cpu cores")
+ }
+ cpuCores, err := strconv.Atoi(cpuCoresS)
+ if err != nil {
+ return resourceData{}, fmt.Errorf("invalid cpu cores: %s", cpuCoresS)
+ }
+ memory, ok := r.Annotations["dodo.cloud/resource.virtual-machine.memory"]
+ if !ok {
+ return resourceData{}, fmt.Errorf("no memory")
+ }
+ ret.VirtualMachine = append(ret.VirtualMachine, vm{name, user, cpuCores, memory})
default:
fmt.Printf("Unknown resource: %+v\n", r.Annotations)
}
}
return ret, nil
}
+
+func createDevBranchAppConfig(from []byte, branch, username string) (string, []byte, error) {
+ cfg, err := installer.ParseCueAppConfig(installer.CueAppData{"app.cue": from})
+ if err != nil {
+ return "", nil, err
+ }
+ if err := cfg.Err(); err != nil {
+ return "", nil, err
+ }
+ if err := cfg.Validate(); err != nil {
+ return "", nil, err
+ }
+ subdomain := cfg.LookupPath(cue.ParsePath("app.ingress.subdomain"))
+ if err := subdomain.Err(); err != nil {
+ return "", nil, err
+ }
+ subdomainStr, err := subdomain.String()
+ network := cfg.LookupPath(cue.ParsePath("app.ingress.network"))
+ if err := network.Err(); err != nil {
+ return "", nil, err
+ }
+ networkStr, err := network.String()
+ if err != nil {
+ return "", nil, err
+ }
+ newCfg := map[string]any{}
+ if err := cfg.Decode(&newCfg); err != nil {
+ return "", nil, err
+ }
+ app, ok := newCfg["app"].(map[string]any)
+ if !ok {
+ return "", nil, fmt.Errorf("not a map")
+ }
+ app["ingress"].(map[string]any)["subdomain"] = fmt.Sprintf("%s-%s", branch, subdomainStr)
+ app["dev"] = map[string]any{
+ "enabled": true,
+ "username": username,
+ }
+ buf, err := json.MarshalIndent(newCfg, "", "\t")
+ if err != nil {
+ return "", nil, err
+ }
+ return networkStr, buf, nil
+}
diff --git a/core/installer/welcome/dodo_app_test.go b/core/installer/welcome/dodo_app_test.go
new file mode 100644
index 0000000..0f0f526
--- /dev/null
+++ b/core/installer/welcome/dodo_app_test.go
@@ -0,0 +1,24 @@
+package welcome
+
+import (
+ "testing"
+)
+
+func TestCreateDevBranch(t *testing.T) {
+ cfg := []byte(`
+app: {
+ type: "golang:1.22.0"
+ run: "main.go"
+ ingress: {
+ network: "private"
+ subdomain: "testapp"
+ auth: enabled: false
+ }
+}`)
+ network, newCfg, err := createDevBranchAppConfig(cfg, "foo", "bar")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Log(network)
+ t.Log(string(newCfg))
+}
diff --git a/core/installer/welcome/env_test.go b/core/installer/welcome/env_test.go
index f41110d..ee80e4e 100644
--- a/core/installer/welcome/env_test.go
+++ b/core/installer/welcome/env_test.go
@@ -15,6 +15,7 @@
"golang.org/x/crypto/ssh"
+ "cuelang.org/go/cue/errors"
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/memfs"
"github.com/go-git/go-billy/v5/util"
@@ -117,6 +118,10 @@
return mockRepoIO{soft.NewBillyRepoFS(f.envFS), "foo.bar", f.t, &l}, nil
}
+func (f fakeSoftServeClient) GetRepoBranch(name, branch string) (soft.RepoIO, error) {
+ return f.GetRepo(name)
+}
+
func (f fakeSoftServeClient) GetAllRepos() ([]string, error) {
return []string{}, nil
}
@@ -176,6 +181,14 @@
return nil
}
+func (f fakeSoftServeClient) DisableAnonAccess() error {
+ return nil
+}
+
+func (f fakeSoftServeClient) DisableKeyless() error {
+ return nil
+}
+
type fakeClientGetter struct {
t *testing.T
envFS billy.Filesystem
@@ -279,6 +292,9 @@
if _, err := infraMgr.Install(app, "/infrastructure/dns-gateway", "dns-gateway", map[string]any{
"servers": []installer.EnvDNS{},
}); err != nil {
+ for _, e := range errors.Errors(err) {
+ t.Log(e)
+ }
t.Fatal(err)
}
}
diff --git a/core/installer/welcome/launcher.go b/core/installer/welcome/launcher.go
index a828f1a..88047d8 100644
--- a/core/installer/welcome/launcher.go
+++ b/core/installer/welcome/launcher.go
@@ -42,7 +42,7 @@
}
func (d *AppManagerDirectory) GetAllApps() ([]AppLauncherInfo, error) {
- all, err := d.AppManager.FindAllInstances()
+ all, err := d.AppManager.GetAllInstances()
if err != nil {
return nil, err
}
diff --git a/core/installer/welcome/store.go b/core/installer/welcome/store.go
index 06be06a..3f8428d 100644
--- a/core/installer/welcome/store.go
+++ b/core/installer/welcome/store.go
@@ -40,9 +40,10 @@
GetUserApps(username string) ([]string, error)
CreateApp(name, username string) error
GetAppOwner(name string) (string, error)
- CreateCommit(name, hash, message, status, error string, resources []byte) error
- GetCommitHistory(name string) ([]CommitMeta, error)
+ CreateCommit(name, branch, hash, message, status, error string, resources []byte) error
+ GetCommitHistory(name, branch string) ([]CommitMeta, error)
GetCommit(hash string) (Commit, error)
+ GetBranches(name string) ([]string, error)
}
func NewStore(cf soft.RepoIO, db *sql.DB) (Store, error) {
@@ -71,6 +72,7 @@
);
CREATE TABLE IF NOT EXISTS commits (
app_name TEXT,
+ branch TEXT,
hash TEXT,
message TEXT,
status TEXT,
@@ -186,15 +188,15 @@
return ret, nil
}
-func (s *storeImpl) CreateCommit(name, hash, message, status, error string, resources []byte) error {
- query := `INSERT INTO commits (app_name, hash, message, status, error, resources) VALUES (?, ?, ?, ?, ?, ?)`
- _, err := s.db.Exec(query, name, hash, message, status, error, resources)
+func (s *storeImpl) CreateCommit(name, branch, hash, message, status, error string, resources []byte) error {
+ query := `INSERT INTO commits (app_name, branch, hash, message, status, error, resources) VALUES (?, ?, ?, ?, ?, ?, ?)`
+ _, err := s.db.Exec(query, name, branch, hash, message, status, error, resources)
return err
}
-func (s *storeImpl) GetCommitHistory(name string) ([]CommitMeta, error) {
- query := `SELECT hash, message, status, error FROM commits WHERE app_name = ?`
- rows, err := s.db.Query(query, name)
+func (s *storeImpl) GetCommitHistory(name, branch string) ([]CommitMeta, error) {
+ query := `SELECT hash, message, status, error FROM commits WHERE app_name = ? AND branch = ?`
+ rows, err := s.db.Query(query, name, branch)
if err != nil {
return nil, err
}
@@ -231,3 +233,25 @@
}
return ret, nil
}
+
+func (s *storeImpl) GetBranches(name string) ([]string, error) {
+ query := `SELECT DISTINCT branch FROM commits WHERE app_name = ?`
+ rows, err := s.db.Query(query, name)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ ret := []string{}
+ for rows.Next() {
+ if err := rows.Err(); err != nil {
+ return nil, err
+ }
+ var b string
+ if err := rows.Scan(&b); err != nil {
+ return nil, err
+ }
+ ret = append(ret, b)
+
+ }
+ return ret, nil
+}