Skip to content

Commit 7426fa1

Browse files
authored
Merge pull request #69 from kubero-dev/feature/make-pipelines-editable
make pipelines editable
2 parents 141ac68 + d8b98bc commit 7426fa1

File tree

7 files changed

+153
-12
lines changed

7 files changed

+153
-12
lines changed

client/src/components/pipelines/list.vue

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,27 @@
5858
<v-btn
5959
elevation="2"
6060
fab
61+
small
62+
class="ma-2"
63+
color="grey lighten-2"
6164
@click="deletePipeline(item.name)"
6265
>
6366
<v-icon dark>
6467
mdi-delete
6568
</v-icon>
6669
</v-btn>
70+
<v-btn
71+
elevation="2"
72+
fab
73+
small
74+
class="ma-2"
75+
color="grey lighten-2"
76+
:href="'#/pipeline/'+item.name"
77+
>
78+
<v-icon dark>
79+
mdi-pencil
80+
</v-icon>
81+
</v-btn>
6782
</v-col>
6883

6984
</v-row>
@@ -112,6 +127,9 @@ export default {
112127
console.log(error);
113128
});
114129
},
130+
editPipeline(app) {
131+
this.$router.push({ name: 'Edit Pipeline', params: { name: app } });
132+
},
115133
},
116134
}
117135
</script>

client/src/components/pipelines/new.vue

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
:rules="nameRules"
2222
:counter="60"
2323
label="Pipeline name *"
24+
:disabled="!newPipeline"
2425
required
2526
></v-text-field>
2627
</v-col>
@@ -43,12 +44,12 @@
4344
md="8"
4445
>
4546
<v-tabs icons-and-text v-model="repotab" color="#8560A9" @change="loadRepository">
46-
<v-tab href="#github" :disabled="this.repositoriesList.github == false">Github <v-icon>mdi-github</v-icon> </v-tab>
47-
<v-tab href="#gitea" :disabled="this.repositoriesList.gitea == false">Gitea <v-icon class="gitea"></v-icon></v-tab>
48-
<v-tab href="#gitlab" :disabled="this.repositoriesList.gitlab == false">Gitlab <v-icon>mdi-gitlab</v-icon></v-tab>
47+
<v-tab href="#github" :disabled="this.repositoriesList.github == false || !newPipeline">Github <v-icon>mdi-github</v-icon> </v-tab>
48+
<v-tab href="#gitea" :disabled="this.repositoriesList.gitea == false || !newPipeline">Gitea <v-icon class="gitea"></v-icon></v-tab>
49+
<v-tab href="#gitlab" :disabled="this.repositoriesList.gitlab == false || !newPipeline">Gitlab <v-icon>mdi-gitlab</v-icon></v-tab>
4950
<!--<v-tab href="#onedev" disabled>oneDev <v-icon class="onedev"></v-icon></v-tab>-->
50-
<v-tab href="#gogs" :disabled="this.repositoriesList.gogs == false">Gogs <v-icon class="gogs"></v-icon></v-tab>
51-
<v-tab href="#bitbucket" :disabled="this.repositoriesList.bitbucket == false">Bitbucket <v-icon>mdi-bitbucket</v-icon></v-tab>
51+
<v-tab href="#gogs" :disabled="this.repositoriesList.gogs == false || !newPipeline">Gogs <v-icon class="gogs"></v-icon></v-tab>
52+
<v-tab href="#bitbucket" :disabled="this.repositoriesList.bitbucket == false || !newPipeline">Bitbucket <v-icon>mdi-bitbucket</v-icon></v-tab>
5253
</v-tabs>
5354
</v-col>
5455
</v-row>
@@ -64,7 +65,7 @@
6465
:counter="60"
6566
:items="gitrepoItems"
6667
label="Repository *"
67-
:disabled="repository_status.connected"
68+
:disabled="repository_status.connected || !newPipeline"
6869
required
6970
></v-combobox>
7071
</v-col>
@@ -160,12 +161,22 @@
160161
>
161162
<v-btn
162163
color="primary"
164+
v-if="newPipeline"
163165
elevation="2"
164-
@click="saveForm()"
166+
@click="createPipeline()"
165167
:disabled="!valid
166168
|| !gitrepo
167169
|| !buildpack"
168-
>Sumbit</v-btn>
170+
>Create</v-btn>
171+
<v-btn
172+
color="primary"
173+
v-if="!newPipeline"
174+
elevation="2"
175+
@click="updatePipeline()"
176+
:disabled="!valid
177+
|| !gitrepo
178+
|| !buildpack"
179+
>Update</v-btn>
169180
</v-col>
170181
</v-row>
171182
</v-container>
@@ -175,7 +186,15 @@
175186
<script>
176187
import axios from "axios";
177188
export default {
189+
props: {
190+
pipeline: {
191+
type: String,
192+
default: "new"
193+
}
194+
},
178195
data: () => ({
196+
newPipeline: true,
197+
resourceVersion: undefined,
179198
repotab: 'github', //selected tab
180199
buildpack: undefined,
181200
buildpackList: [],
@@ -270,6 +289,7 @@ export default {
270289
this.listRepositories();
271290
this.listBuildpacks();
272291
this.loadRepository();
292+
this.loadPipeline();
273293
},
274294
methods: {
275295
updateBuildpack(buildpack) {
@@ -412,7 +432,29 @@ export default {
412432
this.repository_status.statusTxt = "Failed to connect to repository API";
413433
});
414434
},
415-
saveForm() {
435+
loadPipeline() {
436+
if (this.pipeline !== 'new') {
437+
axios.get(`/api/pipelines/${this.pipeline}`)
438+
.then(response => {
439+
this.newPipeline = false;
440+
const p = response.data;
441+
442+
this.resourceVersion = p.resourceVersion;
443+
this.pipelineName = p.name;
444+
this.domain = p.domain;
445+
this.gitrepo = p.git.repository.ssh_url;
446+
this.phases = p.phases;
447+
this.reviewapps = p.reviewapps;
448+
this.git = p.git;
449+
this.dockerimage = p.dockerimage;
450+
this.deploymentstrategy = p.deploymentstrategy;
451+
this.buildpack = p.buildpack;
452+
}).catch(error => {
453+
console.log(error);
454+
});
455+
}
456+
},
457+
createPipeline() {
416458
417459
// fake the minimal requirements to create a pipeline if the repo is not connectedd
418460
if (!this.repository_status.connected) {
@@ -448,7 +490,29 @@ export default {
448490
.catch(error => {
449491
console.log(error);
450492
});
451-
}
493+
},
494+
updatePipeline() {
495+
axios.put(`/api/pipelines/${this.pipeline}`, {
496+
resourceVersion: this.resourceVersion,
497+
pipelineName: this.pipelineName,
498+
domain: this.domain,
499+
gitrepo: this.gitrepo,
500+
phases: this.phases,
501+
reviewapps: this.reviewapps,
502+
git: this.git,
503+
dockerimage: '',
504+
deploymentstrategy: "git",
505+
buildpack: this.buildpack,
506+
})
507+
.then(response => {
508+
this.pipelineName = '';
509+
console.log(response);
510+
this.$router.push({path: '/'});
511+
})
512+
.catch(error => {
513+
console.log(error);
514+
});
515+
},
452516
},
453517
}
454518
</script>

client/src/router/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ export default new VueRouter({
3333
component: AppsNew,
3434
props: true
3535
},
36+
{
37+
path: "/pipeline/:pipeline",
38+
name: "Edit Pipeline",
39+
component: PipelineNew,
40+
props: true
41+
},
3642
{
3743
path: "/pipeline/:pipeline/:phase/:app",
3844
name: "Edit App",

src/kubero.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export class Kubero {
128128

129129
// creates a new pipeline in the same namespace as the kubero app
130130
public async newPipeline(pipeline: IPipeline) {
131-
debug.debug('create newPipeline: '+pipeline.name);
131+
debug.debug('create Pipeline: '+pipeline.name);
132132

133133
// Create the Pipeline CRD
134134
await this.kubectl.createPipeline(pipeline);
@@ -140,6 +140,21 @@ export class Kubero {
140140
this._io.emit('updatedPipelines', "created");
141141
}
142142

143+
// updates a new pipeline in the same namespace as the kubero app
144+
public async updatePipeline(pipeline: IPipeline, resourceVersion: string) {
145+
debug.debug('update Pipeline: '+pipeline.name);
146+
147+
// Create the Pipeline CRD
148+
await this.kubectl.updatePipeline(pipeline, resourceVersion);
149+
this.updateState();
150+
151+
this.kubectl.createEvent('Normal', 'Updated', 'pipeline.updated', 'updated pipeline: '+pipeline.name);
152+
153+
// update agents
154+
this._io.emit('updatedPipelines', "updated");
155+
}
156+
157+
143158
public async listPipelines(): Promise<IPipelineList> {
144159
debug.debug('listPipelines');
145160
let pipelines = await this.kubectl.getPipelinesList();
@@ -162,6 +177,7 @@ export class Kubero {
162177
});
163178

164179
if (pipeline) {
180+
pipeline.spec.resourceVersion = pipeline.metadata.resourceVersion;
165181
return pipeline.spec;
166182
}
167183
}

src/modules/kubectl.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ export class Kubectl {
103103
return pipelines.body as IKubectlPipelineList;
104104
}
105105

106-
107106
public async createPipeline(pl: IPipeline) {
108107
debug.log("create pipeline: " + pl.name);
109108
let pipeline = new KubectlPipeline(pl);
@@ -120,6 +119,24 @@ export class Kubectl {
120119
});
121120
}
122121

122+
public async updatePipeline(pl: IPipeline, resourceVersion: string ) {
123+
debug.log("update pipeline: " + pl.name);
124+
let pipeline = new KubectlPipeline(pl);
125+
pipeline.metadata.resourceVersion = resourceVersion;
126+
127+
this.kc.setCurrentContext(process.env.KUBERO_CONTEXT || 'default');
128+
await this.customObjectsApi.replaceNamespacedCustomObject(
129+
"application.kubero.dev",
130+
"v1alpha1",
131+
process.env.KUBERO_NAMESPACE || 'kubero',
132+
"kuberopipelines",
133+
pl.name,
134+
pipeline
135+
).catch(error => {
136+
debug.log(error);
137+
});
138+
}
139+
123140
public async deletePipeline(pipelineName: string) {
124141
debug.log("delete pipeline: " + pipelineName);
125142
this.kc.setCurrentContext(process.env.KUBERO_CONTEXT || 'default');

src/routes/pipelines.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,25 @@ Router.post('/pipelines',authMiddleware, async function (req: Request, res: Resp
6767
res.send("new");
6868
});
6969

70+
71+
Router.put('/pipelines/:pipeline',authMiddleware, async function (req: Request, res: Response) {
72+
// #swagger.tags = ['UI']
73+
// #swagger.summary = 'Edit a pipeline'
74+
// #swagger.parameters['body'] = { in: 'body', description: 'Pipeline object', required: true, type: 'object' }
75+
let pipeline: IPipeline = {
76+
name: req.body.pipelineName,
77+
domain: req.body.domain,
78+
phases: req.body.phases,
79+
buildpack: req.body.buildpack,
80+
reviewapps: req.body.reviewapps,
81+
git: req.body.git,
82+
dockerimage: req.body.dockerimage,
83+
deploymentstrategy: req.body.deploymentstrategy,
84+
};
85+
req.app.locals.kubero.updatePipeline(pipeline, req.body.resourceVersion);
86+
res.send("new");
87+
});
88+
7089
Router.get('/cli/pipelines', bearerMiddleware, async function (req: Request, res: Response) {
7190
// #swagger.tags = ['Pipeline']
7291
// #swagger.summary = 'Get a list of available pipelines'

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ export interface IPipeline {
145145
};
146146
dockerimage: string;
147147
deploymentstrategy: 'git' | 'docker',
148+
resourceVersion?: string; // required to update resource, not part of spec
148149
}
149150

150151
export interface IPipelineList {

0 commit comments

Comments
 (0)