diff --git a/.dockerignore b/.dockerignore index e2727550..dc0c6d99 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,4 @@ -**/node_modules_AAAA +**/node_modules Dockerfile .dockerignore .git @@ -9,4 +9,4 @@ docker-compose.* kind.* .eslintrc.js README.md -**/dist_AAAAA \ No newline at end of file +**/dist \ No newline at end of file diff --git a/.github/workflows/stargazers.yaml b/.github/workflows/stargazers.yaml index d7662237..67858c98 100644 --- a/.github/workflows/stargazers.yaml +++ b/.github/workflows/stargazers.yaml @@ -8,14 +8,21 @@ jobs: name: 'stargazers' runs-on: ubuntu-latest steps: - - name: 💌 Send email, you star + - name: Send email uses: dawidd6/action-send-mail@v1.3.0 with: server_address: smtp.gmail.com server_port: 465 username: ${{ secrets.GMAIL_USER }} password: ${{ secrets.GMAIL_PASS }} - subject: Your a star ✨ - body: ${{ github.actor }} just starred your mail-on-star repo!!! ${{ github.repository }} + subject: ${{ github.event.repository.stargazers_count }} ✨ ${{ github.actor }} stared ${{ github.repository }} + body: | + ${{ github.actor }} just starred your mail-on-star repo!!! + ${{ github.event.repository.html_url }} + Forks: ${{ github.event.repository.forks_count }} + Stars: ${{ github.event.repository.stargazers_count }} + Issues: ${{ github.event.repository.open_issues_count }} + + ${{ github.repository }} to: ${{ secrets.GMAIL_ADDRESS }} from: ${{ secrets.GMAIL_ADDRESS }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 0ba5f3dc..07b2f795 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,12 +4,11 @@ ENV NODE_ENV=development WORKDIR /build ## Server -COPY server ./server +COPY server-refactored-v3 ./server RUN cd /build/server && \ yarn install RUN cd /build/server && \ - yarn build && \ - yarn swaggergen + yarn build ## Client COPY client ./client @@ -30,13 +29,15 @@ WORKDIR /app/ COPY --from=build /build/server/dist /app/server COPY --from=build /build/server/package.json /app/server/package.json -COPY --from=build /build/server/src/modules/templates /app/server/modules/templates +COPY --from=build /build/server/src/deployments/templates /app/server/deployments/templates COPY --from=build /build/server/node_modules /app/server/node_modules -COPY --from=build /build/server/swagger.json /app/swagger.json + +# temporary fix for the public folder +COPY --from=build /build/server-refactored-v3/dist/public /app/server/public RUN echo -n $VERSION > /app/server/VERSION WORKDIR /app/server -CMD [ "node", "index.js" ] \ No newline at end of file +CMD [ "node", "main" ] \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md index e7b33dd4..66751aaa 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -5,6 +5,7 @@ | Version | Supported | | ------- | ------------------ | | 2.X.X | :white_check_mark: | +| 2.X.X | EOL 31.03.2025 | | 1.X.X | EOL 28.09.2024 | | 0.X.X | | diff --git a/client/package.json b/client/package.json index 5ef8a6b4..ec71afe8 100644 --- a/client/package.json +++ b/client/package.json @@ -3,8 +3,8 @@ "private": true, "license": "GPL-3.0", "scripts": { - "dev": "vite", - "watch": "vue-tsc --noEmit && vite build --watch", + "run": "vite", + "dev": "vue-tsc --noEmit && vite build --watch", "build": "vue-tsc --noEmit && vite build", "preview": "vite preview", "lint": "eslint . --fix --ignore-path .gitignore" diff --git a/client/src/components/apps/addons.vue b/client/src/components/apps/addons.vue index 19e65868..bdc66d2f 100644 --- a/client/src/components/apps/addons.vue +++ b/client/src/components/apps/addons.vue @@ -281,7 +281,7 @@ export default defineComponent({ this.dialog = true; }, loadStorageClasses() { - axios.get(`/api/config/storageclasses`) + axios.get(`/api/kubernetes/storageclasses`) .then(response => { for (let storageClass of response.data) { this.availableStorageClasses.push({ diff --git a/client/src/components/apps/alerts.vue b/client/src/components/apps/alerts.vue index 3e08132e..82494f73 100644 --- a/client/src/components/apps/alerts.vue +++ b/client/src/components/apps/alerts.vue @@ -84,7 +84,7 @@ export default { }, 10000); }, loadRules() { - axios.get(`/api/rules/${this.pipeline}/${this.phase}/${this.app}`) + axios.get(`/api/metrics/rules/${this.pipeline}/${this.phase}/${this.app}`) .then(response => { this.rules = response.data }) diff --git a/client/src/components/apps/appstats.vue b/client/src/components/apps/appstats.vue index e8d2bfea..3def6891 100644 --- a/client/src/components/apps/appstats.vue +++ b/client/src/components/apps/appstats.vue @@ -480,7 +480,7 @@ export default defineComponent({ }, methods: { loadUptimes() { - axios.get(`/api/uptimes/${this.pipeline}/${this.phase}`) + axios.get(`/api/metrics/uptimes/${this.pipeline}/${this.phase}`) .then(response => { this.uptimes = response.data; this.loadMetrics(); @@ -491,7 +491,7 @@ export default defineComponent({ }, loadMetrics() { - axios.get(`/api/metrics/${this.pipeline}/${this.phase}/${this.app}`) + axios.get(`/api/metrics/resources/${this.pipeline}/${this.phase}/${this.app}`) .then(response => { for (var i = 0; i < response.data.length; i++) { if (response.data[i].cpu.percentage != null && response.data[i].memory.percentage != null) { diff --git a/client/src/components/apps/buildsform.vue b/client/src/components/apps/buildsform.vue index 380741dc..018a8fff 100644 --- a/client/src/components/apps/buildsform.vue +++ b/client/src/components/apps/buildsform.vue @@ -137,7 +137,7 @@ export default defineComponent({ const repoB64 = btoa(this.appData?.spec.gitrepo.ssh_url) //const provider = this.appData?.spec.gitrepo.provider const provider = "github" // TODO: FIX: get provider from appData - axios.get(`/api/repo/${provider}/${repoB64}/references/list`) + axios.get(`/api/repo/${provider}/${repoB64}/references`) .then(response => { this.references = response.data }) diff --git a/client/src/components/apps/console.vue b/client/src/components/apps/console.vue index 37c7981e..6d5e5808 100644 --- a/client/src/components/apps/console.vue +++ b/client/src/components/apps/console.vue @@ -109,7 +109,7 @@ export default defineComponent({ }), methods: { loadPods() { - axios.get(`/api/status/pods/${this.pipeline}/${this.phase}/${this.app}`).then((response) => { + axios.get(`/api/apps/${this.pipeline}/${this.phase}/${this.app}/pods`).then((response) => { //this.loadContainers(); for (let pod of response.data) { const p = {name: pod.name, containers: pod.containers.map((c: any) => c.name)} as Pod; @@ -258,7 +258,7 @@ export default defineComponent({ }); }, execInContainer(){ - axios.post(`/api/console/${this.pipeline}/${this.phase}/${this.app}/exec`, { + axios.post(`/api/apps/${this.pipeline}/${this.phase}/${this.app}/console`, { podName: this.pod.name, containerName: this.container, command: this.command, diff --git a/client/src/components/apps/detail.vue b/client/src/components/apps/detail.vue index 2df38c49..d05a6a2f 100644 --- a/client/src/components/apps/detail.vue +++ b/client/src/components/apps/detail.vue @@ -160,7 +160,7 @@ export default defineComponent({ }); }, loadApp() { - axios.get('/api/pipelines/'+this.pipeline+'/'+this.phase+'/'+this.app).then(response => { + axios.get('/api/apps/'+this.pipeline+'/'+this.phase+'/'+this.app).then(response => { this.appData = response.data; //console.log(this.appData); }); @@ -172,7 +172,7 @@ export default defineComponent({ this.$router.push(`/pipeline/${this.pipeline}/${this.phase}/apps/${this.app}`); }, ActionStartDownload() { - axios.get('/api/pipelines/'+this.pipeline+'/'+this.phase+'/'+this.app+'/download').then(response => { + axios.get('/api/apps/'+this.pipeline+'/'+this.phase+'/'+this.app+'/download').then(response => { //console.log(response.data); const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); @@ -197,7 +197,7 @@ export default defineComponent({ }) .then((result) => { if (result.isConfirmed) { - axios.delete(`/api/pipelines/${this.pipeline}/${this.phase}/${this.app}`) + axios.delete(`/api/apps/${this.pipeline}/${this.phase}/${this.app}`) .then(response => { // sleep 1 second setTimeout(() => { @@ -213,7 +213,7 @@ export default defineComponent({ }); }, async restartApp() { - axios.get(`/api/pipelines/${this.pipeline}/${this.phase}/${this.app}/restart`) + axios.get(`/api/apps/${this.pipeline}/${this.phase}/${this.app}/restart`) .then(response => { //console.log(response); this.loadingState = true; diff --git a/client/src/components/apps/events.vue b/client/src/components/apps/events.vue index 67998405..9d51b6dd 100644 --- a/client/src/components/apps/events.vue +++ b/client/src/components/apps/events.vue @@ -139,7 +139,7 @@ export default defineComponent({ const namespace = this.pipeline + "-" + this.phase; //axios.get(`/api/events?namespace=${this.$route.query.namespace}`) //console.log("loadEvents", namespace); - axios.get(`/api/events?namespace=${namespace}`) + axios.get(`/api/kubernetes/events?namespace=${namespace}`) .then(response => { // sort by creationTimestamp response.data.sort((a: any, b: any) => { diff --git a/client/src/components/apps/form.vue b/client/src/components/apps/form.vue index 153fd4df..db796f60 100644 --- a/client/src/components/apps/form.vue +++ b/client/src/components/apps/form.vue @@ -51,12 +51,12 @@ md="6" > @@ -64,6 +64,7 @@ cols="12" md="2" > + @@ -566,7 +568,7 @@ md="6" > @@ -881,7 +883,7 @@ Environment Variables - +
Addons
- + @@ -1307,6 +1309,7 @@ :disabled="!valid" >Update
+
@@ -1490,7 +1494,7 @@ export default defineComponent({ return { breadcrumbItems: [ { - title: 'dashboard.-', + title: 'dashboard.pipelines', disabled: false, to: { name: 'Pipelines', params: {}} }, @@ -1609,7 +1613,7 @@ export default defineComponent({ deploymentstrategy: 'docker', phases: [] as Phase[], }, - appname: '', + name: '', resourceVersion: '', /* phases: [ @@ -1643,7 +1647,7 @@ export default defineComponent({ }, autodeploy: true, sslIndex: [] as (boolean|undefined)[], - envvars: [ + envVars: [ //{ name: '', value: '' }, ] as EnvVar[], sAAnnotations: [ @@ -1711,7 +1715,6 @@ export default defineComponent({ letsecryptClusterIssuer: 'letsencrypt-prod', // deprecated in version 1.11.0 security: { - vulnerabilityScans: false, allowPrivilegeEscalation: false, runAsNonRoot: false, readOnlyRootFilesystem: true, @@ -1789,6 +1792,14 @@ export default defineComponent({ 'SYSLOG', 'WAKE_ALARM', ], + vulnerabilityscan: { + enabled: false, + schedule: "0 0 * * *", + image: { + repository: 'aquasec/trivy', + tag: 'latest', + }, + }, healthcheck: { enabled: true, path: '/', @@ -1877,7 +1888,7 @@ export default defineComponent({ return domainsList; }, getDomains() { - axios.get('/api/domains').then(response => { + axios.get('/api/kubernetes/domains').then(response => { this.takenDomains = this.whiteListDomains(response.data); }); }, @@ -1896,21 +1907,21 @@ export default defineComponent({ } }, loadClusterIssuers(){ - axios.get('/api/config/clusterissuers').then(response => { - this.letsecryptClusterIssuer = response.data.id; + axios.get('/api/config/clusterissuer').then(response => { + this.letsecryptClusterIssuer = response.data.clusterissuer; }); }, loadTemplate(template: string) { axios.get('/api/templates/'+template).then(response => { - this.appname = response.data.name; + this.name = response.data.name; this.containerPort = response.data.image.containerPort; this.deploymentstrategy = response.data.deploymentstrategy; this.docker.image = response.data.image.repository; this.docker.tag = response.data.image.tag; - this.envvars = response.data.envVars; + this.envVars = response.data.envVars; if (response.data.serviceAccount && response.data.serviceAccount.annotations) { this.sAAnnotations = Object.entries(response.data.serviceAccount.annotations).map(([key, value]) => ({annotation: key, value: value as string})); } @@ -1932,7 +1943,7 @@ export default defineComponent({ } // Open Panel if there is some data to show - if (this.envvars.length > 0) { + if (this.envVars.length > 0) { this.panel.push(6) } if (Object.keys(this.sAAnnotations).length > 0) { @@ -1989,12 +2000,12 @@ export default defineComponent({ // extract defaultEnvvars from pipeline phase for (let i = 0; i < this.pipelineData.phases.length; i++) { if (this.pipelineData.phases[i].name == this.phase) { - this.envvars = this.pipelineData.phases[i].defaultEnvvars; + this.envVars = this.pipelineData.phases[i].defaultEnvvars; } } // Open Panel if there is some data to show - if (this.envvars.length > 0) { + if (this.envVars.length > 0) { this.panel.push(6) } @@ -2032,7 +2043,7 @@ export default defineComponent({ }); }, loadStorageClasses() { - axios.get('/api/config/storageclasses').then(response => { + axios.get('/api/kubernetes/storageclasses').then(response => { for (let i = 0; i < response.data.length; i++) { this.storageclasses.push(response.data[i].name); } @@ -2049,7 +2060,7 @@ export default defineComponent({ const gitrepoB64 = btoa(this.pipelineData.git.repository.ssh_url); const gitprovider = this.pipelineData.git.provider; - axios.get('/api/repo/'+gitprovider+"/"+gitrepoB64+"/branches/list").then(response => { + axios.get('/api/repo/'+gitprovider+"/"+gitrepoB64+"/branches").then(response => { if (response.data.length === 0) { return; } @@ -2070,7 +2081,7 @@ export default defineComponent({ loadPodsizeList() { - axios.get('/api/config/podsize').then(response => { + axios.get('/api/config/podsizes').then(response => { if (response.data.length > 0 && this.app == 'new') { this.podsize = response.data[0]; } @@ -2089,7 +2100,7 @@ export default defineComponent({ }, loadBuildpacks() { - axios.get('/api/config/buildpacks').then(response => { + axios.get('/api/config/runpacks').then(response => { for (let i = 0; i < response.data.length; i++) { this.buildpacks.push({ text: response.data[i].name, @@ -2104,7 +2115,7 @@ export default defineComponent({ }, deleteApp() { - axios.delete(`/api/pipelines/${this.pipeline}/${this.phase}/${this.app}`) + axios.delete(`/api/apps/${this.pipeline}/${this.phase}/${this.app}`) .then(() => { // wait for 1 second and redirect to apps page // this avoids a race condition with the backend @@ -2118,8 +2129,8 @@ export default defineComponent({ }, loadApp() { if (this.app !== 'new') { - axios.get(`/api/pipelines/${this.pipeline}/${this.phase}/${this.app}`).then(response => { - this.resourceVersion = response.data.resourceVersion; + axios.get(`/api/apps/${this.pipeline}/${this.phase}/${this.app}`).then(response => { + this.resourceVersion = response.data.metadata.resourceVersion; // Open Panel if there is some data to show if (response.data.spec.envVars.length > 0) { @@ -2144,7 +2155,7 @@ export default defineComponent({ this.deploymentstrategy = response.data.spec.deploymentstrategy; this.buildstrategy = response.data.spec.buildstrategy || 'plain'; - this.appname = response.data.spec.name; + this.name = response.data.spec.name; this.sleep = response.data.spec.sleep; this.basicAuth = response.data.spec.basicAuth || { enabled: false, realm: 'Authentication required', accounts: [] }; this.buildpack = { @@ -2159,7 +2170,7 @@ export default defineComponent({ this.docker.tag = response.data.spec.image.tag || 'latest'; this.docker.command = command; this.autodeploy = response.data.spec.autodeploy; - this.envvars = response.data.spec.envVars; + this.envVars = response.data.spec.envVars; this.serviceAccount = response.data.spec.serviceAccount; if (response.data.spec.serviceAccount && response.data.spec.serviceAccount.annotations) { this.sAAnnotations = Object.entries(response.data.spec.serviceAccount.annotations).map(([key, value]) => ({annotation: key, value: value as string})); @@ -2174,7 +2185,7 @@ export default defineComponent({ this.workerreplicasrange = [response.data.spec.worker.autoscaling.minReplicas, response.data.spec.worker.autoscaling.maxReplicas]; this.cronjobs = this.cronjobUnformat(response.data.spec.cronjobs) || []; this.addons= response.data.spec.addons || []; - this.security.vulnerabilityScans = response.data.spec.vulnerabilityscan.enabled; + this.vulnerabilityscan = response.data.spec.vulnerabilityscan; this.ingress = response.data.spec.ingress || {}; this.healthcheck = response.data.spec.healthcheck || { enabled: true, path: '/', startupSeconds: 90, timeoutSeconds: 30, periodSeconds: 10 }; @@ -2195,10 +2206,10 @@ export default defineComponent({ }, setSSL() { if (this.ingress.tls?.length == 0) { - this.ingress.tls = [{ hosts: [], secretName: this.appname+'-tls' }]; + this.ingress.tls = [{ hosts: [], secretName: this.name+'-tls' }]; } this.ingress.tls[0].hosts = []; - this.ingress.tls[0].secretName = this.appname+'-tls'; + this.ingress.tls[0].secretName = this.name+'-tls'; this.ingress.hosts.forEach((host, index) => { if (this.sslIndex[index]) { this.ingress.tls[0].hosts.push(host.host); @@ -2266,9 +2277,11 @@ export default defineComponent({ } let postdata = { + pipeline: this.pipeline, + phase: this.phase, resourceVersion: this.resourceVersion, buildpack: this.buildpack, - appname: this.appname, + name: this.name, sleep: this.sleep, basicAuth: this.basicAuth, gitrepo: this.gitrepo, @@ -2276,7 +2289,7 @@ export default defineComponent({ deploymentstrategy: this.deploymentstrategy, buildstrategy: this.buildstrategy, image : { - containerport: this.containerPort, + containerPort: this.containerPort, repository: this.docker.image, tag: this.docker.tag, command: command, @@ -2285,7 +2298,7 @@ export default defineComponent({ run: this.buildpack?.run, }, autodeploy: this.autodeploy, - envvars: this.envvars, + envVars: this.envVars, // loop through serviceaccount annotations and convert to object serviceAccount: { annotations: this.sAAnnotations.reduce((acc, cur) => { @@ -2318,6 +2331,7 @@ export default defineComponent({ addons: this.addons, security: this.security, ingress: this.ingress, + vulnerabilityscan: this.vulnerabilityscan, healthcheck: this.healthcheck, } @@ -2328,7 +2342,7 @@ export default defineComponent({ postdata.image.run.securityContext.runAsGroup = parseInt(postdata.image.run.securityContext.runAsGroup); } - axios.put(`/api/pipelines/${this.pipeline}/${this.phase}/${this.app}`, postdata + axios.put(`/api/apps/${this.pipeline}/${this.phase}/${this.app}/${this.resourceVersion}`, postdata // eslint-disable-next-line no-unused-vars ).then(response => { this.$router.push(`/pipeline/${this.pipeline}/apps`); @@ -2369,7 +2383,7 @@ export default defineComponent({ pipeline: this.pipeline, buildpack: this.buildpack, phase: this.phase, - appname: this.appname.toLowerCase(), + name: this.name.toLowerCase(), sleep: this.sleep, basicAuth: this.basicAuth, gitrepo: this.gitrepo, @@ -2377,7 +2391,7 @@ export default defineComponent({ deploymentstrategy: this.deploymentstrategy, buildstrategy: this.buildstrategy, image : { - containerport: this.containerPort, + containerPort: this.containerPort, repository: this.docker.image, tag: this.docker.tag, fetch: this.buildpack?.fetch, @@ -2385,7 +2399,7 @@ export default defineComponent({ run: this.buildpack?.run, }, autodeploy: this.autodeploy, - envvars: this.envvars, + envVars: this.envVars, serviceAccount: { annotations: this.sAAnnotations.reduce((acc, cur) => { acc[cur.annotation] = cur.value; @@ -2417,6 +2431,7 @@ export default defineComponent({ addons: this.addons, security: this.security, ingress: this.ingress, + vulnerabilityscan: this.vulnerabilityscan, healthcheck: this.healthcheck, } @@ -2442,10 +2457,10 @@ export default defineComponent({ }, } */ - axios.post(`/api/apps`, postdata) + axios.post(`/api/apps/${this.pipeline}/${this.phase}/${this.app}`, postdata) // eslint-disable-next-line no-unused-vars .then(response => { - this.appname = ''; + this.name = ''; //console.log(response); this.$router.push({path: '/pipeline/' + this.pipeline + '/apps'}); }) @@ -2467,15 +2482,15 @@ export default defineComponent({ } }, addEnvLine() { - this.envvars.push({ + this.envVars.push({ name: '', value: '', }); }, removeEnvLine(index: string) { - for (let i = 0; i < this.envvars.length; i++) { - if (this.envvars[i].name === index) { - this.envvars.splice(i, 1); + for (let i = 0; i < this.envVars.length; i++) { + if (this.envVars[i].name === index) { + this.envVars.splice(i, 1); } } }, @@ -2512,8 +2527,8 @@ export default defineComponent({ const [name, value] = line.split('='); // check if name isn't commented out if (name && !name.startsWith('#') && value) { - if (!this.envvars.some(envvar => envvar.name === name.trim())) { - this.envvars.push({ name: name.trim(), value: value.trim() }); + if (!this.envVars.some(envVars => envVars.name === name.trim())) { + this.envVars.push({ name: name.trim(), value: value.trim() }); } } } diff --git a/client/src/components/apps/metrics.vue b/client/src/components/apps/metrics.vue index 53c1f814..39f7ac59 100644 --- a/client/src/components/apps/metrics.vue +++ b/client/src/components/apps/metrics.vue @@ -655,7 +655,7 @@ export default defineComponent({ }, getMemoryMetrics() { - axios.get(`/api/longtermmetrics/memory/${this.pipeline}/${this.phase}/${this.app}`, { + axios.get(`/api/metrics/timeseries/memory/${this.pipeline}/${this.phase}/${this.app}`, { params: { scale: this.scale } @@ -668,7 +668,7 @@ export default defineComponent({ }); }, getLoadMetrics() { - axios.get(`/api/longtermmetrics/load/${this.pipeline}/${this.phase}/${this.app}`, { + axios.get(`/api/metrics/timeseries/load/${this.pipeline}/${this.phase}/${this.app}`, { params: { scale: this.scale } @@ -681,9 +681,11 @@ export default defineComponent({ }); }, getHttpStatusCodeMetrics() { - axios.get(`/api/longtermmetrics/httpstatuscodes/${this.pipeline}/${this.phase}/${this.host}/rate`, { + axios.get(`/api/metrics/timeseries/httpstatuscodes/${this.pipeline}/${this.phase}/${this.app}`, { params: { - scale: this.scale + scale: this.scale, + host: this.host, + calc: 'rate' } }) .then((response) => { @@ -694,9 +696,11 @@ export default defineComponent({ }); }, getHttpStatusCodeIncreaseMetrics() { - axios.get(`/api/longtermmetrics/httpstatuscodes/${this.pipeline}/${this.phase}/${this.host}/increase`, { + axios.get(`/api/metrics/timeseries/httpstatuscodes/${this.pipeline}/${this.phase}/${this.app}`, { params: { - scale: this.scale + scale: this.scale, + host: this.host, + calc: 'rate' } }) .then((response) => { @@ -707,9 +711,11 @@ export default defineComponent({ }); }, getResponseTimeMetrics() { - axios.get(`/api/longtermmetrics/responsetime/${this.pipeline}/${this.phase}/${this.host}/increase`, { + axios.get(`/api/metrics/timeseries/responsetime/${this.pipeline}/${this.phase}/${this.app}`, { params: { - scale: this.scale + scale: this.scale, + host: this.host, + calc: 'rate' } }) .then((response) => { @@ -720,9 +726,11 @@ export default defineComponent({ }); }, getResponseTrafficMetrics() { - axios.get(`/api/longtermmetrics/traffic/${this.pipeline}/${this.phase}/${this.host}/increase`, { + axios.get(`/api/metrics/timeseries/traffic/${this.pipeline}/${this.phase}/${this.app}`, { params: { - scale: this.scale + scale: this.scale, + host: this.host, + calc: 'rate' } }) .then((response) => { @@ -734,9 +742,10 @@ export default defineComponent({ }, getCpuMetrics() { // use 'rate' instead of 'increase' when comparing to limit and request - axios.get(`/api/longtermmetrics/cpu/${this.pipeline}/${this.phase}/${this.app}/increase`, { + axios.get(`/api/metrics/timeseries/cpu/${this.pipeline}/${this.phase}/${this.app}`, { params: { - scale: this.scale + scale: this.scale, + calc: 'rate' } }) .then((response) => { @@ -748,9 +757,10 @@ export default defineComponent({ }, getCpuMetricsRate() { // use 'rate' instead of 'increase' when comparing to limit and request - axios.get(`/api/longtermmetrics/cpu/${this.pipeline}/${this.phase}/${this.app}/rate`, { + axios.get(`/api/metrics/timeseries/cpu/${this.pipeline}/${this.phase}/${this.app}`, { params: { - scale: this.scale + scale: this.scale, + calc: 'rate' } }) .then((response) => { diff --git a/client/src/components/loginprompt.vue b/client/src/components/loginprompt.vue index 121e090d..c7bd4269 100644 --- a/client/src/components/loginprompt.vue +++ b/client/src/components/loginprompt.vue @@ -86,6 +86,9 @@ import router from "../router" import axios from "axios" import { defineComponent } from 'vue' +import { useCookies } from "vue3-cookies"; +const { cookies } = useCookies(); + export default defineComponent({ name: "Login", data: () => ({ @@ -120,10 +123,15 @@ export default defineComponent({ username: username, password: password } - axios.post("/api/login", data) + axios.post("/api/auth/login", data) .then((response) => { //console.log("Logged in"+response) - router.push("/") + + // Save topen token in local storage + //localStorage.setItem("kubero.JWT_TOKEN", response.data.access_token); + + const token = cookies.set("kubero.JWT_TOKEN", response.data.access_token); + window.location.href = "/" }) .catch((errors) => { this.error = true; @@ -131,6 +139,22 @@ export default defineComponent({ }) } login() + }, + github() { + axios.get("/api/auth/github") + .then((response) => { + //console.log("Logged in"+response) + + // Save topen token in local storage + //localStorage.setItem("kubero.JWT_TOKEN", response.data.access_token); + + const token = cookies.set("kubero.JWT_TOKEN", response.data.access_token); + window.location.href = "/" + }) + .catch((errors) => { + this.error = true; + console.log("Cannot log in"+errors) + }) } } }); diff --git a/client/src/components/pipelines/appcard.vue b/client/src/components/pipelines/appcard.vue index d10e252b..448141a6 100644 --- a/client/src/components/pipelines/appcard.vue +++ b/client/src/components/pipelines/appcard.vue @@ -254,7 +254,7 @@ export default defineComponent({ }) .then((result) => { if (result.isConfirmed) { - axios.delete(`/api/pipelines/${this.pipeline}/${this.phase}/${this.app.name}`) + axios.delete(`/api/apps/${this.pipeline}/${this.phase}/${this.app.name}`) .then(response => { //this.$router.push(`/pipeline/${this.pipeline}/apps`); //console.log("deleteApp"); @@ -269,7 +269,7 @@ export default defineComponent({ }); }, async restartApp() { - axios.get(`/api/pipelines/${this.pipeline}/${this.phase}/${this.app.name}/restart`) + axios.get(`/api/apps/${this.pipeline}/${this.phase}/${this.app.name}/restart`) .then(response => { //console.log(response); this.loadingState = true; @@ -283,7 +283,7 @@ export default defineComponent({ this.loadingState = false; }, loadMetrics() { - axios.get(`/api/metrics/${this.pipeline}/${this.phase}/${this.app.name}`) + axios.get(`/api/metrics/resources/${this.pipeline}/${this.phase}/${this.app.name}`) .then(response => { for (var i = 0; i < response.data.length; i++) { if (response.data[i].cpu.percentage != null && response.data[i].memory.percentage != null) { diff --git a/client/src/components/pipelines/detail.vue b/client/src/components/pipelines/detail.vue index 88e5edbb..54b7845c 100644 --- a/client/src/components/pipelines/detail.vue +++ b/client/src/components/pipelines/detail.vue @@ -136,6 +136,7 @@ async function loadPullrequests() { response.data.forEach((pr: Pullrequest) => { let found = false; phases.value[0].apps.forEach((app: App) => { + console.log(app.name, pr.branch); if (app.name == pr.branch) { found = true; } diff --git a/client/src/components/pipelines/form.vue b/client/src/components/pipelines/form.vue index 7a3badb2..6a3146d5 100644 --- a/client/src/components/pipelines/form.vue +++ b/client/src/components/pipelines/form.vue @@ -713,7 +713,7 @@ export default defineComponent({ this.buildpack = buildpack; }, getContextList() { - axios.get('/api/config/k8s/context').then(response => { + axios.get('/api/kubernetes/contexts').then(response => { for (let i = 0; i < response.data.length; i++) { this.contextList.push(response.data[i].name); } @@ -726,12 +726,12 @@ export default defineComponent({ }); }, listRepositories() { - axios.get('/api/config/repositories').then(response => { + axios.get('/api/repo/providers').then(response => { this.repositoriesList = response.data }); }, listBuildpacks() { - axios.get('/api/config/buildpacks').then(response => { + axios.get('/api/config/runpacks').then(response => { for (let i = 0; i < response.data.length; i++) { this.buildpackList.push({ text: response.data[i].name, @@ -805,7 +805,7 @@ export default defineComponent({ }, loadRepository() { - axios.get(`/api/repo/${this.repotab}/list`) + axios.get(`/api/repo/${this.repotab}/repositories`) .then(response => { this.gitrepoItems = response.data; }).catch(error => { @@ -939,7 +939,7 @@ export default defineComponent({ this.buildpack = this.buildpackList[0].value; } - axios.post(`/api/pipelines`, { + axios.post(`/api/pipelines/${this.pipeline}`, { pipelineName: this.pipelineName, domain: this.domain, gitrepo: this.gitrepo, diff --git a/client/src/components/pipelines/list.vue b/client/src/components/pipelines/list.vue index 59572957..76f82cff 100644 --- a/client/src/components/pipelines/list.vue +++ b/client/src/components/pipelines/list.vue @@ -146,7 +146,7 @@ type Pipeline = { const socket = useKuberoStore().kubero.socket as any; -socket.on('updatedPipelines', (instances: any) => { +socket.on('updatePipeline', (instances: any) => { //console.log("updatedPipelines", instances); loadPipelinesList(); }); diff --git a/client/src/components/pipelines/prcard.vue b/client/src/components/pipelines/prcard.vue index 938eec2b..1e34d8a7 100644 --- a/client/src/components/pipelines/prcard.vue +++ b/client/src/components/pipelines/prcard.vue @@ -95,7 +95,7 @@ export default defineComponent({ //console.log("startReviewApp", this.pullrequest.number); this.loadingState = true; - axios.post("/api/repo/pullrequest/start", { + axios.post("/api/apps/pullrequest", { branch: this.pullrequest.branch, title: this.pullrequest.title, ssh_url: this.pullrequest.ssh_url, diff --git a/client/src/components/settings/form-general.vue b/client/src/components/settings/form-general.vue index ea6b6984..81fef60a 100644 --- a/client/src/components/settings/form-general.vue +++ b/client/src/components/settings/form-general.vue @@ -380,7 +380,7 @@ export default defineComponent({ }, methods: { loadStorageClasses() { - axios.get('/api/config/storageclasses').then(response => { + axios.get('/api/kubernetes/storageclasses').then(response => { for (let i = 0; i < response.data.length; i++) { this.storageclasses.push(response.data[i].name); } diff --git a/client/src/components/settings/form.vue b/client/src/components/settings/form.vue index 1db734b2..46885328 100644 --- a/client/src/components/settings/form.vue +++ b/client/src/components/settings/form.vue @@ -527,7 +527,7 @@ export default defineComponent({ delete buildpack.advanced; }); - axios.post(`/api/settings`, self.settings) + axios.post(`/api/config`, self.settings) .then(response => { console.log('saveSettings', response); }) @@ -537,7 +537,7 @@ export default defineComponent({ }, async loadSettings() { const self = this; - axios.get(`/api/settings`) + axios.get(`/api/config`) .then(response => { self.settings = response.data; }) diff --git a/client/src/components/setup/index.vue b/client/src/components/setup/index.vue index a92e5fe4..08e45a39 100644 --- a/client/src/components/setup/index.vue +++ b/client/src/components/setup/index.vue @@ -422,7 +422,7 @@ users: save(obj: any) { axios.post('/api/config/setup/save', obj) .then((response) => { - if (response.status === 200 && response.data.status === 'ok') { + if (response.status === 201 && response.data.status === 'ok') { this.saveSuccess = 'ok' this.saveErrorMessage = '' this.checkInstalled('operator') @@ -503,12 +503,14 @@ users: return false } - const response = await axios.post('/api/config/k8s/kubeconfig/validate', { + const response = await axios.post('/api/config/setup/kubeconfig/validate', { kubeconfig: this.kubeConfig, context: this.kubeContext }) - if (response.status === 200) { + console.log(response.data) + + if (response.status === 201) { if (response.data.valid) { this.kubeconfigError = '' this.kubeconfigValid = true diff --git a/client/src/components/templates/index.vue b/client/src/components/templates/index.vue index 8a833640..7e3afeb5 100644 --- a/client/src/components/templates/index.vue +++ b/client/src/components/templates/index.vue @@ -245,6 +245,10 @@ type TemplatesList = { // }[] } +//Axios instance without Auth headers to load templates +const templates = axios.create(); +templates.defaults.headers.common = {}; + export default defineComponent({ sockets: { }, @@ -305,7 +309,7 @@ export default defineComponent({ }, loadCatalogs(catalogId: number) { const self = this; - axios.get(`/api/config/catalogs`) + axios.get(`/api/config/templates`) .then(response => { self.templates = response.data as Templates; if (self.templates.catalogs.length > 0 && self.templates.enabled == true) { @@ -338,7 +342,8 @@ export default defineComponent({ }, async loadTemplates(indexUrl: string) { const self = this; - axios.get(indexUrl) + + templates.get(indexUrl) .then(response => { self.templatesList = response.data; forEach(self.templatesList.categories, (value, key) => { diff --git a/client/src/layouts/default/AppBar.vue b/client/src/layouts/default/AppBar.vue index 7c2626b0..feeb1db0 100644 --- a/client/src/layouts/default/AppBar.vue +++ b/client/src/layouts/default/AppBar.vue @@ -25,7 +25,7 @@ export default defineComponent({ methods: { getBanner() { - axios.get('/api/banner').then((response: any) => { + axios.get('/api/config/banner').then((response: any) => { this.banner.show = response.data.show; this.banner.message = response.data.message; this.banner.bgcolor = response.data.bgcolor; diff --git a/client/src/layouts/default/NavDrawer.vue b/client/src/layouts/default/NavDrawer.vue index 51e82aac..f2c85234 100644 --- a/client/src/layouts/default/NavDrawer.vue +++ b/client/src/layouts/default/NavDrawer.vue @@ -196,11 +196,14 @@ theme.global.name.value = localStorage.getItem("theme") || 'light';