Skip to content

Commit 425440d

Browse files
Merge pull request #166 from srl-labs/feat/ui
Feat/UI
2 parents bf8e8ed + 88feea6 commit 425440d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+25515
-7
lines changed

.develop/devspace.yaml

+43-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ vars:
1616
MANAGER_IMAGE: ${REGISTRY}/${CLABERNETES}-manager
1717
MANAGER_DEV_IMAGE: ${MANAGER_IMAGE}-dev
1818
LAUNCHER_IMAGE: ${REGISTRY}/${CLABERNETES}-launcher
19+
UI_IMAGE: ${REGISTRY}/${CLABERNETES}-ui
1920
CLABVERTER_IMAGE: ${REGISTRY}/clabverter
2021

2122
# always build w/ 0.0.0 -- overridden for actual releases by release profile. for "normal" builds
@@ -26,6 +27,10 @@ vars:
2627
# to be set in ci
2728
RELEASE_VERSION: ""
2829

30+
CLABERNETES_DEV_DOMAIN:
31+
source: env
32+
default: containerlab.dev
33+
2934
localRegistry:
3035
enabled: false
3136

@@ -37,7 +42,7 @@ images:
3742
dockerfile: dev.Dockerfile
3843
rebuildStrategy: ignoreContextChanges
3944
tags:
40-
- $(git describe --always --abbrev=8)
45+
- ${COMMIT_HASH}
4146

4247
clabernetes:
4348
createPullSecret: false
@@ -49,7 +54,7 @@ images:
4954
VERSION: ${VERSION}-${COMMIT_HASH}
5055
tags:
5156
- dev-latest
52-
- $(git describe --always --abbrev=8)
57+
- ${COMMIT_HASH}
5358

5459
clabernetes-launcher:
5560
createPullSecret: false
@@ -63,6 +68,20 @@ images:
6368
- dev-latest
6469
- ${COMMIT_HASH}
6570

71+
clabernetes-ui:
72+
createPullSecret: false
73+
image: ${UI_IMAGE}
74+
context: ../ui/
75+
dockerfile: ../build/ui.Dockerfile
76+
rebuildStrategy: ignoreContextChanges
77+
buildArgs:
78+
VERSION: ${VERSION}-${COMMIT_HASH}
79+
# seems node things dont wanna ever build w/out buildkit?
80+
buildKit: {}
81+
tags:
82+
- dev-latest
83+
- ${COMMIT_HASH}
84+
6685
clabverter:
6786
createPullSecret: false
6887
image: ${CLABVERTER_IMAGE}
@@ -85,6 +104,9 @@ deployments:
85104
manager:
86105
image: ${MANAGER_IMAGE}
87106
imagePullPolicy: ${PULL_POLICY}
107+
ui:
108+
image: ${UI_IMAGE}
109+
imagePullPolicy: ${PULL_POLICY}
88110
globalConfig:
89111
deployment:
90112
launcherImage: ${LAUNCHER_IMAGE}
@@ -110,6 +132,16 @@ dev:
110132
command: .develop/start.sh
111133

112134
profiles:
135+
- name: dev
136+
patches:
137+
- op: add
138+
path: deployments.clabernetes.helm.values.ui
139+
value:
140+
enabled: true
141+
ingress:
142+
enabled: true
143+
host: ui.clabernetes.${CLABERNETES_DEV_DOMAIN}
144+
113145
- name: debug
114146
patches:
115147
- op: add
@@ -128,6 +160,12 @@ profiles:
128160
path: deployments.clabernetes.helm.values.manager.replicaCount
129161
value: 1
130162

163+
- name: single-ui
164+
patches:
165+
- op: add
166+
path: deployments.clabernetes.helm.values.ui.replicaCount
167+
value: 1
168+
131169
# for development using devspace on "non-local" clusters (meaning *not* kind/docker-desktop/
132170
# minikube/maybe others) you will want to have Always for image pull so launcher and clicker pick
133171
# up the new image -- you may even want always pull on manager so the manager dev image is pulled;
@@ -209,12 +247,12 @@ pipelines:
209247
build:
210248
# override the default build pipeline so we don't bother building dev image in ci
211249
run: |
212-
build_images clabernetes clabernetes-launcher clabverter
250+
build_images clabernetes clabernetes-launcher clabernetes-ui clabverter
213251
214252
dev:
215253
# override the default dev pipeline to not bother building clabverter while doing dev things
216254
run: |
217-
build_images clabernetes-dev clabernetes clabernetes-launcher
255+
build_images clabernetes-dev clabernetes clabernetes-launcher clabernetes-ui
218256
create_deployments --all
219257
start_dev --all
220258
@@ -223,7 +261,7 @@ pipelines:
223261
# deploy pipeline
224262
run: |
225263
run_dependencies --all
226-
build_images clabernetes clabernetes-launcher
264+
build_images clabernetes clabernetes-launcher clabernetes-ui
227265
create_deployments --all
228266
229267
purge:

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,6 @@ cover.out
4343

4444
# build files
4545
cmd/clabverter/build/
46+
47+
# for crd -> openapi gen
48+
venv

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ run-openapi-gen: ## Run openapi-gen
5757
--output-file openapi_generated.go \
5858
--output-pkg github.com/srl-labs/clabernetes/generated/openapi \
5959
github.com/srl-labs/clabernetes/apis/...
60+
venv/bin/python build/crds-to-openapi/crds-to-openapi.py && \
61+
cp generated/openapi/openapi.json ui/clabernetes-openapi.json
6062

6163
run-client-gen: ## Run client-gen
6264
client-gen \

build/crds-to-openapi/crds-to-openapi.py

+1,322
Large diffs are not rendered by default.
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ruamel.yaml==0.17.28

build/ui.Dockerfile

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
FROM node:22.6.0-bookworm AS deps
2+
3+
WORKDIR /clabernetes
4+
5+
COPY package.json package-lock.json /clabernetes/
6+
7+
RUN npm ci && npm cache clean --force
8+
9+
10+
FROM node:22.6.0-bookworm AS builder
11+
12+
ENV NODE_ENV=production
13+
14+
WORKDIR /clabernetes
15+
16+
COPY --from=deps /clabernetes/node_modules ./node_modules
17+
18+
COPY . .
19+
20+
RUN npm run build
21+
22+
23+
FROM --platform=linux/amd64 gcr.io/distroless/nodejs22-debian12:nonroot
24+
25+
EXPOSE 3000
26+
ENV PORT=3000
27+
ENV NODE_ENV=production
28+
29+
WORKDIR /clabernetes
30+
31+
COPY --from=builder --chown=nonroot:nonroot /clabernetes/.next/standalone ./
32+
COPY --from=builder --chown=nonroot:nonroot /clabernetes/.next/static ./.next/static
33+
34+
CMD ["server.js"]

charts/clabernetes/templates/deployment.yaml

+119
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,122 @@ spec:
138138
failureThreshold: 2
139139
periodSeconds: 30
140140
timeoutSeconds: 5
141+
142+
{{- if $.Values.ui.enabled }}
143+
---
144+
apiVersion: apps/v1
145+
kind: Deployment
146+
metadata:
147+
name: {{ $.Values.appName }}-ui
148+
namespace: {{ .Release.Namespace }}
149+
labels:
150+
chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
151+
release: {{ .Release.Name }}
152+
heritage: {{ .Release.Service }}
153+
revision: "{{ .Release.Revision }}"
154+
app.kubernetes.io/name: "{{ $.Values.appName }}-ui"
155+
clabernetes/app: {{ $.Values.appName }}
156+
clabernetes/name: "{{ $.Values.appName }}-ui"
157+
clabernetes/component: ui
158+
{{- $labels := merge $.Values.globalLabels $.Values.ui.deploymentLabels }}
159+
{{- if $labels }}
160+
{{ toYaml $labels | indent 4 }}
161+
{{- end }}
162+
{{- $annotations := merge $.Values.globalAnnotations $.Values.ui.deploymentAnnotations }}
163+
{{- if $annotations }}
164+
annotations:
165+
{{ toYaml $annotations | indent 4 }}
166+
{{- end }}
167+
spec:
168+
selector:
169+
matchLabels:
170+
clabernetes/app: {{ $.Values.appName }}
171+
release: {{ .Release.Name }}
172+
replicas: {{ $.Values.ui.replicaCount }}
173+
strategy:
174+
rollingUpdate:
175+
maxSurge: 1
176+
{{- if (eq (int $.Values.ui.replicaCount) 1) }}
177+
maxUnavailable: 0
178+
{{- else }}
179+
maxUnavailable: 1
180+
{{- end }}
181+
type: RollingUpdate
182+
template:
183+
metadata:
184+
labels:
185+
chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
186+
release: {{ .Release.Name }}
187+
heritage: {{ .Release.Service }}
188+
revision: "{{ .Release.Revision }}"
189+
app.kubernetes.io/name: "{{ $.Values.appName }}-ui"
190+
clabernetes/app: {{ $.Values.appName }}
191+
clabernetes/name: "{{ $.Values.appName }}-ui"
192+
clabernetes/component: ui
193+
{{- $podLabels := merge $.Values.globalLabels $.Values.ui.podLabels }}
194+
{{- if $podLabels }}
195+
{{ toYaml $podLabels | indent 8 }}
196+
{{- end }}
197+
{{- $podAnnotations := merge $.Values.globalAnnotations $.Values.ui.podAnnotations }}
198+
{{- if $podAnnotations }}
199+
annotations:
200+
{{ toYaml $podAnnotations | indent 8 }}
201+
{{- end }}
202+
spec:
203+
{{- if $.Values.ui.affinity }}
204+
affinity:
205+
{{ toYaml $.Values.ui.affinity | indent 8 }}
206+
{{- else if (ge (int $.Values.ui.replicaCount) 2) }}
207+
affinity:
208+
podAntiAffinity:
209+
preferredDuringSchedulingIgnoredDuringExecution:
210+
- weight: 100
211+
podAffinityTerm:
212+
labelSelector:
213+
matchLabels:
214+
clabernetes/app: {{ $.Values.appName }}
215+
clabernetes/name: "{{ $.Values.appName }}-ui"
216+
clabernetes/component: ui
217+
topologyKey: kubernetes.io/hostname
218+
- weight: 50
219+
podAffinityTerm:
220+
labelSelector:
221+
matchLabels:
222+
clabernetes/app: {{ $.Values.appName }}
223+
clabernetes/name: "{{ $.Values.appName }}-ui"
224+
clabernetes/component: ui
225+
topologyKey: topology.kubernetes.io/zone
226+
{{- end }}
227+
terminationGracePeriodSeconds: 10
228+
serviceAccountName: "{{ $.Values.appName }}-service-account"
229+
containers:
230+
- name: ui
231+
{{- if .Values.ui.image }}
232+
image: {{ .Values.ui.image }}
233+
{{- else if eq .Chart.Version "0.0.0" }}
234+
image: "ghcr.io/srl-labs/clabernetes/clabernetes-ui:dev-latest"
235+
{{- else }}
236+
image: "ghcr.io/srl-labs/clabernetes/clabernetes-ui:{{ .Chart.Version }}"
237+
{{- end }}
238+
imagePullPolicy: {{ $.Values.ui.imagePullPolicy }}
239+
resources:
240+
requests:
241+
memory: {{ $.Values.ui.resources.requests.memory }}
242+
cpu: {{ $.Values.ui.resources.requests.cpu }}
243+
{{- if $.Values.ui.resources.limits }}
244+
limits:
245+
{{ toYaml $.Values.ui.resources.limits | indent 14 }}
246+
{{- end }}
247+
ports:
248+
- name: http
249+
containerPort: 3000
250+
livenessProbe:
251+
httpGet:
252+
path: /alive
253+
port: http
254+
scheme: HTTP
255+
successThreshold: 1
256+
failureThreshold: 2
257+
periodSeconds: 30
258+
timeoutSeconds: 5
259+
{{- end }}
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{{- if and $.Values.ui.enabled $.Values.ui.ingress.enabled }}
2+
---
3+
apiVersion: networking.k8s.io/v1
4+
kind: Ingress
5+
metadata:
6+
name: {{ $.Values.appName }}-ui
7+
namespace: {{ .Release.Namespace }}
8+
labels:
9+
chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
10+
release: {{ .Release.Name }}
11+
heritage: {{ .Release.Service }}
12+
revision: "{{ .Release.Revision }}"
13+
app.kubernetes.io/name: "{{ $.Values.appName }}-ui"
14+
clabernetes/app: {{ $.Values.appName }}
15+
clabernetes/name: "{{ $.Values.appName }}-ui"
16+
clabernetes/component: ui
17+
{{- $labels := merge $.Values.globalLabels $.Values.ui.deploymentLabels }}
18+
{{- if $labels }}
19+
{{ toYaml $labels | indent 4 }}
20+
{{- end }}
21+
{{- $annotations := merge $.Values.globalAnnotations $.Values.ui.deploymentAnnotations }}
22+
{{- if $annotations }}
23+
annotations:
24+
kubernetes.io/ingress.class: {{ .Values.ui.ingress.ingressClass }}
25+
{{ toYaml $annotations | indent 4 }}
26+
{{- end }}
27+
spec:
28+
ingressClassName: {{ .Values.ui.ingress.ingressClass }}
29+
rules:
30+
- host: {{ .Values.ui.ingress.host }}
31+
http:
32+
paths:
33+
- backend:
34+
service:
35+
name: {{ .Values.appName }}-ui
36+
port:
37+
number: 443
38+
path: /
39+
pathType: ImplementationSpecific
40+
{{- end }}

charts/clabernetes/templates/service.yaml

+40
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,43 @@ spec:
2424
clabernetes/app: {{ .Values.appName }}
2525
clabernetes/name: "{{ .Values.appName }}-manager"
2626
clabernetes/component: manager
27+
28+
{{- if $.Values.ui.enabled }}
29+
---
30+
apiVersion: v1
31+
kind: Service
32+
metadata:
33+
name: {{ $.Values.appName }}-ui
34+
namespace: {{ .Release.Namespace }}
35+
labels:
36+
chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
37+
release: {{ .Release.Name }}
38+
heritage: {{ .Release.Service }}
39+
revision: "{{ .Release.Revision }}"
40+
app.kubernetes.io/name: "{{ $.Values.appName }}-ui"
41+
clabernetes/app: {{ $.Values.appName }}
42+
clabernetes/name: "{{ $.Values.appName }}-ui"
43+
clabernetes/component: ui
44+
{{- $labels := merge $.Values.globalLabels $.Values.ui.deploymentLabels }}
45+
{{- if $labels }}
46+
{{ toYaml $labels | indent 4 }}
47+
{{- end }}
48+
{{- $annotations := merge $.Values.globalAnnotations $.Values.ui.deploymentAnnotations }}
49+
{{- if $annotations }}
50+
annotations:
51+
kubernetes.io/ingress.class: {{ .Values.ui.ingress.ingressClass }}
52+
{{ toYaml $annotations | indent 4 }}
53+
{{- end }}
54+
spec:
55+
type: ClusterIP
56+
sessionAffinity: None
57+
ports:
58+
- name: https
59+
port: 443
60+
protocol: TCP
61+
targetPort: 3000
62+
selector:
63+
clabernetes/app: {{ $.Values.appName }}
64+
clabernetes/name: "{{ $.Values.appName }}-ui"
65+
clabernetes/component: ui
66+
{{- end }}

0 commit comments

Comments
 (0)