Skip to content

Commit 1042292

Browse files
authored
Merge branch 'semaphoreui:develop' into fix-PAASCOMMON-39
2 parents b7c525f + 3177149 commit 1042292

20 files changed

+676
-394
lines changed

README.md

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ Semaphore UI allows you to:
3333

3434
## Key Concepts
3535

36-
1. **Projects** is a collection of related resources, configurations, and tasks. Each project allows you to organize and manage your automation efforts in one place, defining the scope of tasks such as deploying applications, running scripts, or orchestrating cloud resources. Projects help group resources, inventories, task templates, and environments for streamlined automation workflows.
37-
2. **Task Templates** are reusable definitions of tasks that can be executed on demand or scheduled. A template specifies what actions should be performed, such as running Ansible playbooks, Terraform configurations, or other automation tasks. By using templates, you can standardize tasks and easily re-execute them with minimal effort, ensuring consistent results across different environments.
38-
3. **Task** is a specific instance of a job or operation executed by Semaphore. It refers to running a predefined action (like an Ansible playbook or a script) using a task template. Tasks can be initiated manually or automatically through schedules and are tracked to give you detailed feedback on the execution, including success, failure, and logs.
39-
4. **Schedules** allow you to automate task execution at specified times or intervals. This feature is useful for running periodic maintenance tasks, backups, or deployments without manual intervention. You can configure recurring schedules to ensure important automation tasks are performed regularly and on time.
40-
5. **Inventory** is a collection of target hosts (servers, virtual machines, containers, etc.) on which tasks will be executed. The inventory includes details about the managed nodes such as IP addresses, SSH credentials, and grouping information. It allows for dynamic control over which environments and hosts your automation will interact with.
41-
6. **Environment** refers to a configuration context that holds sensitive information such as environment variables and secrets used by tasks during execution. It separates sensitive data from task templates and allows you to switch between different setups while running the same task template across different environments securely.
36+
1. **Projects** is a collection of related resources, configurations, and tasks.
37+
2. **Task Templates** are reusable definitions of tasks that can be executed on demand or scheduled.
38+
3. **Task** is a specific instance of a job or operation executed by Semaphore.
39+
4. **Schedules** allow you to automate task execution at specified times or intervals.
40+
5. **Inventory** is a collection of target hosts (servers, virtual machines, containers, etc.) on which tasks will be executed.
41+
6. **Variable Group** refers to a configuration context that holds sensitive information such as environment variables and secrets used by tasks during execution.
4242

4343
## Getting Started
4444

@@ -70,14 +70,6 @@ We recommend using the [Container Configurator](https://semaphoreui.com/install/
7070

7171
We offer a SaaS solution for using Semaphore UI without installation. Check it out at [Semaphore Cloud](https://portal.semaphoreui.com).
7272

73-
### Deploy VM from Marketplace
74-
75-
Supported cloud providers:
76-
* [Semaphore Run](https://cloud.semaphore.run/servers/new/semaphore)
77-
* [AWS](https://aws.amazon.com/marketplace/pp/prodview-5noeat2jipwca)
78-
* [Yandex Cloud](https://yandex.cloud/en-ru/marketplace/products/fastlix/semaphore)
79-
* DigitalOcean (coming soon)
80-
8173
### Other Installation Methods
8274

8375
For more installation options, visit our [Installation page](https://semaphoreui.com/install).

api/router.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ func Route() *mux.Router {
221221
projectUserAPI.Path("/tasks").HandlerFunc(projects.GetAllTasks).Methods("GET", "HEAD")
222222
projectUserAPI.HandleFunc("/tasks/last", projects.GetLastTasks).Methods("GET", "HEAD")
223223

224+
projectUserAPI.Path("/stats").HandlerFunc(projects.GetTaskStats).Methods("GET", "HEAD")
225+
224226
projectUserAPI.Path("/templates").HandlerFunc(projects.GetTemplates).Methods("GET", "HEAD")
225227
projectUserAPI.Path("/templates").HandlerFunc(projects.AddTemplate).Methods("POST")
226228

db/Template.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@ const (
6262
)
6363

6464
type AnsibleTemplateParams struct {
65+
AllowDebug bool `json:"allow_debug"`
6566
AllowOverrideInventory bool `json:"allow_override_inventory"`
6667
AllowOverrideLimit bool `json:"allow_override_limit"`
6768
Limit []string `json:"limit"`
69+
Tags []string `json:"tags"`
70+
SkipTags []string `json:"skip_tags"`
6871
}
6972

7073
type TerraformTemplateParams struct {
@@ -156,9 +159,9 @@ func (tpl *Template) FillParams(target interface{}) error {
156159

157160
func (tpl *Template) CanOverrideInventory() (ok bool, err error) {
158161
switch tpl.App {
159-
case AppAnsible:
162+
case AppAnsible, "":
160163
var params AnsibleTemplateParams
161-
err = tpl.FillParams(params)
164+
err = tpl.FillParams(&params)
162165
if err != nil {
163166
return
164167
}

db/sql/SqlDb.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,10 @@ func (d *SqlDb) GetTaskStats(projectID int, templateID *int, unit db.TaskStatUni
806806
q = q.Where("template_id=?", *templateID)
807807
}
808808

809+
if filter.UserID != nil {
810+
q = q.Where("user_id=?", *filter.UserID)
811+
}
812+
809813
if filter.Start != nil {
810814
q = q.Where("start>=?", *filter.Start)
811815
}

services/tasks/LocalJob.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ func (t *LocalJob) getPlaybookArgs(username string, incomingVersion *string) (ar
343343
return
344344
}
345345

346-
if params.Debug {
346+
if tplParams.AllowDebug && params.Debug {
347347
args = append(args, "-vvvv")
348348
}
349349

@@ -401,6 +401,14 @@ func (t *LocalJob) getPlaybookArgs(username string, incomingVersion *string) (ar
401401
templateArgs = append(templateArgs, "--limit="+limit)
402402
}
403403

404+
if len(tplParams.Tags) > 0 {
405+
templateArgs = append(templateArgs, "--tags="+strings.Join(tplParams.Tags, ","))
406+
}
407+
408+
if len(tplParams.SkipTags) > 0 {
409+
templateArgs = append(templateArgs, "--skip-tags="+strings.Join(tplParams.SkipTags, ","))
410+
}
411+
404412
args = append(args, templateArgs...)
405413
args = append(args, taskArgs...)
406414
args = append(args, playbookName)

services/tasks/TaskRunner_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ func TestPopulateDetailsInventory(t *testing.T) {
305305
RepositoryID: repo.ID,
306306
InventoryID: &inv.ID,
307307
EnvironmentID: &env.ID,
308+
TaskParams: map[string]interface{}{
309+
"allow_override_inventory": true,
310+
},
308311
})
309312

310313
if err != nil {

web/src/App.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,10 @@
718718
margin-left: 10px !important;
719719
}
720720
721+
.v-slide-group__prev--disabled {
722+
display: none !important;
723+
}
724+
721725
@media (min-width: 960px) {
722726
.v-app-bar__nav-icon {
723727
display: none !important;

web/src/components/DashboardMenu.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
<template>
22
<div>
3-
<v-tabs show-arrows class="pl-4">
3+
<v-tabs class="pl-4">
44
<v-tab
55
v-if="projectType === ''"
66
key="history"
77
:to="`/project/${projectId}/history`"
88
>{{ $t('history') }}
99
</v-tab>
1010

11+
<v-tab key="stats" :to="`/project/${projectId}/stats`">{{ $t('stats') }}</v-tab>
12+
1113
<v-tab key="activity" :to="`/project/${projectId}/activity`">{{ $t('activity') }}</v-tab>
1214

1315
<v-tab
@@ -31,12 +33,9 @@
3133
</div>
3234
</template>
3335
<script>
34-
import PermissionsCheck from '@/components/PermissionsCheck';
3536
3637
export default {
3738
38-
mixins: [PermissionsCheck],
39-
4039
props: {
4140
projectId: Number,
4241
projectType: String,
@@ -48,5 +47,6 @@ export default {
4847
id: null,
4948
};
5049
},
50+
5151
};
5252
</script>

web/src/components/EditDialog.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Can use used in tandem with ItemFormBase.js. See KeyForm.vue for example.
1010
persistent
1111
:fullscreen="expandable && fullscreen"
1212
:transition="false"
13-
:content-class="'item-dialog item-dialog--' + position"
13+
:content-class="`item-dialog item-dialog item-dialog--${position} ${contentClass}`"
1414
>
1515
<v-card>
1616
<v-card-title>
@@ -45,7 +45,9 @@ Can use used in tandem with ItemFormBase.js. See KeyForm.vue for example.
4545
'pb-0': !hideButtons,
4646
'pa-0': noBodyPaddings,
4747
}"
48-
:style="{minHeight: minContentHeight + 'px'}"
48+
:style="{
49+
minHeight: minContentHeight + 'px'
50+
}"
4951
>
5052
<slot
5153
name="form"
@@ -93,6 +95,7 @@ import EventBus from '@/event-bus';
9395

9496
export default {
9597
props: {
98+
contentClass: String,
9699
position: String,
97100
title: String,
98101
icon: String,

web/src/components/EditTemplateDialog.vue

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<EditDialog
33
v-if="isAppsLoaded"
4-
:max-width="700"
4+
:max-width="1200"
55
:min-content-height="457"
66
v-model="dialog"
77
:save-button-text="itemId === 'new' ? $t('create') : $t('save')"
@@ -10,6 +10,7 @@
1010
:title="(itemId === 'new' ? $t('newTemplate') : $t('editTemplate')) +
1111
' \'' + getAppTitle(itemApp) + '\''"
1212
@save="onSave"
13+
:content-class="`EditTemplateDialog EditTemplateDialog--${id}`"
1314
>
1415
<template v-slot:form="{ onSave, onError, needSave, needReset }">
1516
<TemplateForm
@@ -21,10 +22,27 @@
2122
:need-reset="needReset"
2223
:source-item-id="sourceItemId"
2324
:app="itemApp"
25+
@resize="onFormResize"
2426
/>
2527
</template>
2628
</EditDialog>
2729
</template>
30+
31+
<style lang="scss">
32+
.EditTemplateDialog {
33+
width: auto;
34+
.v-card__text {
35+
overflow-x: auto;
36+
}
37+
}
38+
39+
@media #{map-get($display-breakpoints, 'sm-and-down')} {
40+
.EditTemplateDialog {
41+
width: auto !important;
42+
}
43+
}
44+
</style>
45+
2846
<script>
2947
3048
import TemplateForm from './TemplateForm.vue';
@@ -49,6 +67,7 @@ export default {
4967
5068
data() {
5169
return {
70+
id: Math.round(Math.random() * 1000000),
5271
dialog: false,
5372
};
5473
},
@@ -64,6 +83,11 @@ export default {
6483
},
6584
6685
methods: {
86+
onFormResize(e) {
87+
const contentEl = document.querySelector(`.EditTemplateDialog--${this.id}`);
88+
contentEl.style.width = `${e.width + 50}px`;
89+
},
90+
6791
onSave(e) {
6892
this.$emit('save', e);
6993
},

web/src/components/EnvironmentForm.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ export default {
487487
operation = 'create';
488488
} else if (s.remove) {
489489
operation = 'delete';
490-
} else if (s.value !== '') {
490+
} else {
491491
operation = 'update';
492492
}
493493
return {

web/src/components/TaskForm.vue

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,19 @@
108108
hide-details
109109
></v-select>
110110

111-
<TaskParamsForm v-if="template.app === 'ansible'" v-model="item.params" :app="template.app" />
112-
<TaskParamsForm v-else v-model="item.params" :app="template.app" />
111+
<TaskParamsForm
112+
v-if="template.app === 'ansible'"
113+
v-model="item.params"
114+
:app="template.app"
115+
:template-params="template.task_params"
116+
/>
117+
118+
<TaskParamsForm
119+
v-else
120+
v-model="item.params"
121+
:app="template.app"
122+
:template-params="template.task_params"
123+
/>
113124

114125
<ArgsPicker
115126
v-if="template.allow_override_args_in_task"

web/src/components/TaskParamsForm.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div v-if="app === 'ansible'">
33
<v-row no-gutters class="mt-6">
4-
<v-col cols="12" sm="6">
4+
<v-col cols="12" sm="6" v-if="templateParams.allow_debug">
55
<v-checkbox
66
class="mt-0"
77
:input-value="params.debug"
@@ -118,6 +118,7 @@ export default {
118118
props: {
119119
value: Object,
120120
app: String,
121+
templateParams: Object,
121122
},
122123
123124
watch: {

0 commit comments

Comments
 (0)