Skip to content

Commit f3611ab

Browse files
committed
Merge branch 'main' of github.com:kubero-dev/kubero
2 parents 8bc99f6 + e639ce6 commit f3611ab

File tree

12 files changed

+224
-91
lines changed

12 files changed

+224
-91
lines changed

.env.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ KUBERO_WEBHOOK_SECRET=mysecret
88
KUBERO_WEBHOOK_URL=https://kuberoXXXXXXXXXXXXX.loca.lt/api/repo/webhooks
99

1010
KUBECONFIG_PATH=./kubeconfig
11+
#KUBECONFIG_BASE64=$(cat ./kubeconfig | base64 -w 0)
12+
1113
KUBERO_CONFIG_PATH=./config.yaml
1214
KUBERO_CONTEXT=kind-kubero-001
1315
KUBERO_NAMESPACE=kubero-dev # needs to be created manually in the cluster, since the in cluster default is "kubero"

client/src/App.vue

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ export default {
149149
isAuthenticated: false,
150150
templatesEnabled: true,
151151
version: "dev",
152+
kubernetesVersion: "unknown",
152153
banner: {
153154
show: false,
154155
message: "",
@@ -205,15 +206,32 @@ export default {
205206
this.session = result.data.isAuthenticated;
206207
this.version = result.data.version;
207208
this.templatesEnabled = result.data.templatesEnabled;
209+
this.kubernetesVersion = result.data.kubernetesVersion;
208210
209211
// safe version to vuetufy gloabl scope for use in components
210212
this.$vuetify.version = this.version;
213+
this.$vuetify.kubernetesVersion = this.kubernetesVersion;
211214
this.$vuetify.isAuthenticated = result.data.isAuthenticated;
212215
this.$vuetify.buildPipeline = result.data.buildPipeline;
213216
214217
if (result.status === 200) {
215218
this.isAuthenticated = true;
216219
}
220+
221+
if (result.data.kubernetesVersion === "unknown") {
222+
//this.$router.push('/setup')
223+
console.log("kubernetesVersion: " + result.data.kubernetesVersion);
224+
this.banner.show = true;
225+
this.banner.message = "Kubernetes not reachable";
226+
this.banner.bgcolor = "red";
227+
this.banner.fontcolor = "white";
228+
229+
// TODO: use Pinia to maintain a global state
230+
// https://pinia.vuejs.org/introduction.html
231+
// https://vuex.vuejs.org/
232+
// https://vuex.vuejs.org/api/
233+
//this.$store.dispatch('setKubernetesVersion', result.data.kubernetesVersion);
234+
}
217235
})
218236
.catch((err) => {
219237
if (err.response.status === 401) {

client/src/components/apps/detail.vue

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,49 @@
99
<v-tab class="background">Vulnerabilities</v-tab>
1010
<v-spacer class="background"></v-spacer>
1111
</v-tabs>
12-
<v-btn
13-
elevation="2"
12+
13+
14+
<v-menu offset-y>
15+
<template v-slot:activator="{ on, attrs }">
16+
<v-btn
1417
color="primary"
15-
:href="`#/pipeline/${this.pipeline}/${this.phase}/${this.app}`"
16-
>Edit App
17-
</v-btn>
18+
dark
19+
v-bind="attrs"
20+
v-on="on"
21+
>
22+
<v-icon color="white">mdi-menu-open</v-icon>
23+
Actions
24+
</v-btn>
25+
</template>
26+
<v-list>
27+
<v-list-item-group>
28+
<v-list-item
29+
@click="ActionEditApp">
30+
<v-list-item-icon>
31+
<v-icon small>mdi-pencil</v-icon>
32+
</v-list-item-icon>
33+
<v-list-item-content>
34+
<v-list-item-title>Edit App</v-list-item-title>
35+
</v-list-item-content>
36+
</v-list-item>
37+
<v-list-item
38+
@click="ActionOpenApp">
39+
<v-list-item-icon>
40+
<v-icon small>mdi-open-in-new</v-icon>
41+
</v-list-item-icon>
42+
<v-list-item-title>Open App</v-list-item-title>
43+
</v-list-item>
44+
<v-list-item
45+
disabled
46+
@click="ActionStartDownload">
47+
<v-list-item-icon>
48+
<v-icon small>mdi-download</v-icon>
49+
</v-list-item-icon>
50+
<v-list-item-title>Download Config</v-list-item-title>
51+
</v-list-item>
52+
</v-list-item-group>
53+
</v-list>
54+
</v-menu>
1855
</v-container>
1956

2057
<v-tabs-items v-model="tab">
@@ -92,6 +129,15 @@ export default {
92129
this.appData = response.data;
93130
});
94131
},
132+
ActionOpenApp() {
133+
window.open(`https://app.${this.appData.spec.domain}`, '_blank');
134+
},
135+
ActionEditApp() {
136+
this.$router.push(`/pipeline/${this.pipeline}/${this.phase}/${this.app}`);
137+
},
138+
ActionStartDownload() {
139+
console.log("ActionStartDownload");
140+
}
95141
},
96142
97143
components: {
@@ -115,4 +161,14 @@ export default {
115161
}
116162
},
117163
}
118-
</script>
164+
</script>
165+
166+
<style scoped>
167+
.v-list-item__icon:first-child {
168+
margin-right: 0px;
169+
margin: 10px
170+
}
171+
.v-list-item {
172+
min-height: 32px;
173+
}
174+
</style>

client/src/components/apps/new.vue

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,17 +1011,17 @@ export default {
10111011
{
10121012
text: 'PIPELINE:'+this.pipeline,
10131013
disabled: false,
1014-
href: '#/pipeline/'+this.pipeline+'/apps',
1014+
href: `#/pipeline/${this.pipeline}/apps`,
10151015
},
10161016
{
10171017
text: 'PHASE:'+this.phase,
10181018
disabled: false,
1019-
href: `#/pipeline/${this.pipeline}/${this.phase}/${this.app}/detail`,
1019+
href: this.getAppBreadcrumbLink(),
10201020
},
10211021
{
10221022
text: 'APP:'+this.app,
10231023
disabled: false,
1024-
href: `#/pipeline/${this.pipeline}/${this.phase}/${this.app}/detail`,
1024+
href: this.getAppBreadcrumbLink(),
10251025
}
10261026
],
10271027
advanced: false,
@@ -1290,6 +1290,13 @@ export default {
12901290
breadcrumbs: () => import('../breadcrumbs.vue'),
12911291
},
12921292
methods: {
1293+
getAppBreadcrumbLink() {
1294+
if (this.app == 'new') {
1295+
return `#/pipeline/${this.pipeline}/apps`;
1296+
} else {
1297+
return `#/pipeline/${this.pipeline}/${this.phase}/${this.app}/detail`;
1298+
}
1299+
},
12931300
loadClusterIssuers(){
12941301
axios.get('/api/config/clusterissuers').then(response => {
12951302
this.letsecryptClusterIssuer = response.data.id;

client/src/components/pipelines/list.vue

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,20 @@ export default {
103103
},
104104
mounted() {
105105
this.loadPipelinesList();
106+
107+
// sleep for 1 second till session is loaded
108+
setTimeout(() => {
109+
if (this.$vuetify.kubernetesVersion === "unknown") {
110+
// TODO: use Pinia to maintain a global state
111+
// https://pinia.vuejs.org/introduction.html
112+
// https://vuex.vuejs.org/
113+
// https://vuex.vuejs.org/api/
114+
console.log("cant reach kubernetes");
115+
}
116+
}, 1000);
117+
106118
},
119+
107120
components: {
108121
breadcrumbs: () => import('../breadcrumbs.vue'),
109122
},

docker-compose.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ services:
1212
# change the KUBERO_CONTEXT to the name of your local kind cluster context
1313
# you can find the name by running `kubectl config get-contexts`
1414
# Must be the same as the context name in the kubeconfig file !
15+
#- KUBECONFIG_BASE64=
1516
- KUBECONFIG_PATH=./kubeconfig
16-
- KUBERO_CONTEXT=kind-kubero-001
17+
- KUBERO_CONTEXT=inClusterContext
1718
- KUBERO_NAMESPACE=kubero
1819
- KUBERO_SESSION_KEY=randomString
1920
ports:
@@ -27,5 +28,5 @@ services:
2728
volumes:
2829
# run `kind get kubeconfig --internal --name kubero-001 > ./kubeconfig-docker` to get the right config
2930
# modify the server in the config to use the external kubernetes port from your host machine
30-
- ./kubeconfig-002-docker:/app/server/kubeconfig
31+
- ./kubeconfig:/app/server/kubeconfig
3132
- ./config.yaml:/app/server/config.yaml

src/configure.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ import * as fs from 'fs';
2323

2424
const { KUBERO_SESSION_KEY = crypto.randomBytes(20).toString('hex') } = process.env;
2525

26-
export const before = (app: Express) => {
27-
26+
export const configure = async (app: Express, server: Server) => {
2827
// Load Version from File
2928
process.env.npm_package_version = fs.readFileSync('./VERSION','utf8');;
3029

@@ -42,13 +41,27 @@ export const before = (app: Express) => {
4241
app.use(auth.passport.initialize());
4342
app.use(auth.passport.session());
4443
}
45-
}
4644

47-
export const after = (app: Express, server: Server) => {
45+
app.use('/api', RouterAddons);
46+
app.use('/api', RouterAuth);
47+
app.use('/api', RouterConfig);
48+
app.use('/api', RouterApps);
49+
app.use('/api', RouterLogs);
50+
app.use('/api', RouterPipelines);
51+
app.use('/api', RouterRepo);
52+
app.use('/api', RouterSettings);
53+
app.use('/api', RouterServices);
54+
app.use('/api', RouterSecurity);
55+
const swagger = SwaggerUi.setup(require('../swagger.json'));
56+
app.use('/api/docs', SwaggerUi.serve, swagger);
4857

4958
// Attache socket.io to server
5059
let sockets = init(server);
5160
const kubero = new Kubero(sockets);
61+
62+
// sleep 5 seconds to wait for kubernetes availability test
63+
await new Promise(resolve => setTimeout(resolve, 1000));
64+
5265
kubero.updateState();
5366
app.locals.kubero = kubero;
5467

@@ -62,17 +75,4 @@ export const after = (app: Express, server: Server) => {
6275
kubectl: kubero.kubectl
6376
});
6477
app.locals.settings = settings;
65-
66-
app.use('/api', RouterAddons);
67-
app.use('/api', RouterAuth);
68-
app.use('/api', RouterConfig);
69-
app.use('/api', RouterApps);
70-
app.use('/api', RouterLogs);
71-
app.use('/api', RouterPipelines);
72-
app.use('/api', RouterRepo);
73-
app.use('/api', RouterSettings);
74-
app.use('/api', RouterServices);
75-
app.use('/api', RouterSecurity);
76-
const swagger = SwaggerUi.setup(require('../swagger.json'));
77-
app.use('/api/docs', SwaggerUi.serve, swagger);
7878
}

src/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import dotenv from 'dotenv';
55
import debug from 'debug';
66
import http from 'http';
77
dotenv.config();
8-
import {before, after} from './configure';
8+
import {configure} from './configure';
99

1010
debug('app:server')
1111

@@ -15,8 +15,7 @@ const server = http.createServer(app)
1515
const port: String = process.env.PORT || "2000";
1616

1717
// API
18-
before(app);
19-
after(app, server);
18+
configure(app, server);
2019

2120
const maxAge = process.env.NODE_ENV === 'development' ? '1s' : '1h';
2221

src/kubero.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ export class Kubero {
4747
debug.debug('Kubero Config: '+JSON.stringify(this.config));
4848
}
4949

50+
public getKubernetesVersion() {
51+
if (this.kubectl.kubeVersion) {
52+
return this.kubectl.kubeVersion.gitVersion;
53+
} else {
54+
return 'unknown';
55+
}
56+
}
57+
5058
public updateState() {
5159
this.pipelineStateList = [];
5260
this.appStateList = [];

0 commit comments

Comments
 (0)