mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-07-27 07:54:52 +00:00

Most of the time this isn't an issue for job edits, but here we have two "enable" checkboxes that control enabling newly synced users and enabling the job itself, try to be absolutely clear on both to avoid potential confusion. Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
422 lines
9.4 KiB
JavaScript
422 lines
9.4 KiB
JavaScript
Ext.define('PVE.dc.RealmSyncJobView', {
|
|
extend: 'Ext.grid.Panel',
|
|
alias: 'widget.pveRealmSyncJobView',
|
|
|
|
stateful: true,
|
|
stateId: 'grid-realmsyncjobs',
|
|
|
|
emptyText: Ext.String.format(gettext('No {0} configured'), gettext('Realm Sync Job')),
|
|
|
|
controller: {
|
|
xclass: 'Ext.app.ViewController',
|
|
|
|
addRealmSyncJob: function(button) {
|
|
let me = this;
|
|
Ext.create(`PVE.dc.RealmSyncJobEdit`, {
|
|
autoShow: true,
|
|
listeners: {
|
|
destroy: () => me.reload(),
|
|
},
|
|
});
|
|
},
|
|
|
|
editRealmSyncJob: function() {
|
|
let me = this;
|
|
let view = me.getView();
|
|
let selection = view.getSelection();
|
|
if (!selection || selection.length < 1) {
|
|
return;
|
|
}
|
|
|
|
Ext.create(`PVE.dc.RealmSyncJobEdit`, {
|
|
jobid: selection[0].data.id,
|
|
autoShow: true,
|
|
listeners: {
|
|
destroy: () => me.reload(),
|
|
},
|
|
});
|
|
},
|
|
|
|
runNow: function() {
|
|
let me = this;
|
|
let view = me.getView();
|
|
let selection = view.getSelection();
|
|
if (!selection || selection.length < 1) {
|
|
return;
|
|
}
|
|
|
|
let params = selection[0].data;
|
|
let realm = params.realm;
|
|
|
|
let propertiesToDelete = ['comment', 'realm', 'id', 'type', 'schedule', 'last-run', 'next-run', 'enabled'];
|
|
for (const prop of propertiesToDelete) {
|
|
delete params[prop];
|
|
}
|
|
|
|
Proxmox.Utils.API2Request({
|
|
url: `/access/domains/${realm}/sync`,
|
|
params,
|
|
waitMsgTarget: view,
|
|
method: 'POST',
|
|
success: function(response, options) {
|
|
let upid = response.result.data;
|
|
let win = Ext.create('Proxmox.window.TaskProgress', {
|
|
upid: upid,
|
|
taskDone: () => { me.reload(); },
|
|
});
|
|
win.show();
|
|
},
|
|
failure: function(response, opts) {
|
|
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
|
|
},
|
|
});
|
|
},
|
|
|
|
reload: function() {
|
|
this.getView().getStore().load();
|
|
},
|
|
},
|
|
|
|
store: {
|
|
autoLoad: true,
|
|
id: 'realm-syncs',
|
|
proxy: {
|
|
type: 'proxmox',
|
|
url: '/api2/json/cluster/jobs/realm-sync',
|
|
},
|
|
},
|
|
|
|
viewConfig: {
|
|
getRowClass: (record, _index) => record.get('enabled') ? '' : 'proxmox-disabled-row',
|
|
},
|
|
|
|
columns: [
|
|
{
|
|
header: gettext('Enabled'),
|
|
width: 80,
|
|
dataIndex: 'enabled',
|
|
sortable: true,
|
|
align: 'center',
|
|
stopSelection: false,
|
|
renderer: Proxmox.Utils.renderEnabledIcon,
|
|
},
|
|
{
|
|
text: gettext('Name'),
|
|
flex: 1,
|
|
dataIndex: 'id',
|
|
hidden: true,
|
|
},
|
|
{
|
|
text: gettext('Realm'),
|
|
width: 200,
|
|
dataIndex: 'realm',
|
|
},
|
|
{
|
|
header: gettext('Schedule'),
|
|
width: 150,
|
|
dataIndex: 'schedule',
|
|
},
|
|
{
|
|
text: gettext('Next Run'),
|
|
dataIndex: 'next-run',
|
|
width: 150,
|
|
renderer: PVE.Utils.render_next_event,
|
|
},
|
|
{
|
|
header: gettext('Comment'),
|
|
dataIndex: 'comment',
|
|
renderer: Ext.htmlEncode,
|
|
sorter: (a, b) => (a.data.comment || '').localeCompare(b.data.comment || ''),
|
|
flex: 1,
|
|
},
|
|
],
|
|
|
|
tbar: [
|
|
{
|
|
text: gettext('Add'),
|
|
handler: 'addRealmSyncJob',
|
|
},
|
|
{
|
|
text: gettext('Edit'),
|
|
xtype: 'proxmoxButton',
|
|
handler: 'editRealmSyncJob',
|
|
disabled: true,
|
|
},
|
|
{
|
|
xtype: 'proxmoxStdRemoveButton',
|
|
baseurl: `/api2/extjs/cluster/jobs/realm-sync`,
|
|
callback: 'reload',
|
|
},
|
|
{
|
|
xtype: 'proxmoxButton',
|
|
handler: 'runNow',
|
|
disabled: true,
|
|
text: gettext('Run Now'),
|
|
},
|
|
],
|
|
|
|
listeners: {
|
|
itemdblclick: 'editRealmSyncJob',
|
|
},
|
|
|
|
initComponent: function() {
|
|
var me = this;
|
|
|
|
me.callParent();
|
|
|
|
Proxmox.Utils.monStoreErrors(me, me.getStore());
|
|
},
|
|
});
|
|
|
|
Ext.define('PVE.dc.RealmSyncJobEdit', {
|
|
extend: 'Proxmox.window.Edit',
|
|
mixins: ['Proxmox.Mixin.CBind'],
|
|
|
|
subject: gettext('Realm Sync Job'),
|
|
onlineHelp: 'pveum_ldap_sync',
|
|
|
|
// don't focus the schedule field on edit
|
|
defaultFocus: 'field[name=id]',
|
|
|
|
cbindData: function() {
|
|
let me = this;
|
|
me.isCreate = !me.jobid;
|
|
me.jobid = me.jobid || "";
|
|
let url = '/api2/extjs/cluster/jobs/realm-sync';
|
|
me.url = me.jobid ? `${url}/${me.jobid}` : url;
|
|
me.method = me.isCreate ? 'POST' : 'PUT';
|
|
if (!me.isCreate) {
|
|
me.subject = `${me.subject}: ${me.jobid}`;
|
|
}
|
|
return {};
|
|
},
|
|
|
|
submitUrl: function(url, values) {
|
|
return this.isCreate ? `${url}/${values.id}` : url;
|
|
},
|
|
|
|
controller: {
|
|
xclass: 'Ext.app.ViewController',
|
|
|
|
updateDefaults: function(_field, newValue) {
|
|
let me = this;
|
|
|
|
['scope', 'enable-new', 'schedule'].forEach((reference) => {
|
|
me.lookup(reference)?.setDisabled(false);
|
|
});
|
|
|
|
// only update on create
|
|
if (!me.getView().isCreate) {
|
|
return;
|
|
}
|
|
Proxmox.Utils.API2Request({
|
|
url: `/access/domains/${newValue}`,
|
|
success: function(response) {
|
|
// first reset the fields to their default
|
|
['acl', 'entry', 'properties'].forEach(opt => {
|
|
me.lookup(`remove-vanished-${opt}`)?.setValue(false);
|
|
});
|
|
me.lookup('enable-new')?.setValue('1');
|
|
me.lookup('scope')?.setValue(undefined);
|
|
|
|
let options = response?.result?.data?.['sync-defaults-options'];
|
|
if (options) {
|
|
let parsed = PVE.Parser.parsePropertyString(options);
|
|
if (parsed['remove-vanished']) {
|
|
let opts = parsed['remove-vanished'].split(';');
|
|
for (const opt of opts) {
|
|
me.lookup(`remove-vanished-${opt}`)?.setValue(true);
|
|
}
|
|
delete parsed['remove-vanished'];
|
|
}
|
|
for (const [name, value] of Object.entries(parsed)) {
|
|
me.lookup(name)?.setValue(value);
|
|
}
|
|
}
|
|
},
|
|
});
|
|
},
|
|
},
|
|
|
|
items: [
|
|
{
|
|
xtype: 'inputpanel',
|
|
|
|
cbind: {
|
|
isCreate: '{isCreate}',
|
|
},
|
|
|
|
onGetValues: function(values) {
|
|
let me = this;
|
|
|
|
let vanished_opts = [];
|
|
['acl', 'entry', 'properties'].forEach((prop) => {
|
|
if (values[`remove-vanished-${prop}`]) {
|
|
vanished_opts.push(prop);
|
|
}
|
|
delete values[`remove-vanished-${prop}`];
|
|
});
|
|
|
|
if (!values.id && me.isCreate) {
|
|
values.id = 'realmsync-' + Ext.data.identifier.Uuid.Global.generate().slice(0, 13);
|
|
}
|
|
|
|
if (vanished_opts.length > 0) {
|
|
values['remove-vanished'] = vanished_opts.join(';');
|
|
} else {
|
|
values['remove-vanished'] = 'none';
|
|
}
|
|
|
|
PVE.Utils.delete_if_default(values, 'node', '');
|
|
|
|
if (me.isCreate) {
|
|
delete values.delete; // on create we cannot delete values
|
|
}
|
|
|
|
return values;
|
|
},
|
|
|
|
column1: [
|
|
{
|
|
xtype: 'pmxDisplayEditField',
|
|
editConfig: {
|
|
xtype: 'pmxRealmComboBox',
|
|
storeFilter: rec => rec.data.type === 'ldap' || rec.data.type === 'ad',
|
|
},
|
|
listConfig: {
|
|
emptyText: `<div class="x-grid-empty">${gettext('No LDAP/AD Realm found')}</div>`,
|
|
},
|
|
cbind: {
|
|
editable: '{isCreate}',
|
|
},
|
|
listeners: {
|
|
change: 'updateDefaults',
|
|
},
|
|
fieldLabel: gettext('Realm'),
|
|
name: 'realm',
|
|
reference: 'realm',
|
|
},
|
|
{
|
|
xtype: 'pveCalendarEvent',
|
|
fieldLabel: gettext('Schedule'),
|
|
disabled: true,
|
|
allowBlank: false,
|
|
name: 'schedule',
|
|
reference: 'schedule',
|
|
},
|
|
{
|
|
xtype: 'proxmoxcheckbox',
|
|
fieldLabel: gettext('Enable Job'),
|
|
name: 'enabled',
|
|
reference: 'enabled',
|
|
uncheckedValue: 0,
|
|
defaultValue: 1,
|
|
checked: true,
|
|
},
|
|
],
|
|
|
|
column2: [
|
|
{
|
|
xtype: 'proxmoxKVComboBox',
|
|
name: 'scope',
|
|
reference: 'scope',
|
|
disabled: true,
|
|
fieldLabel: gettext('Scope'),
|
|
value: '',
|
|
emptyText: gettext('No default available'),
|
|
deleteEmpty: false,
|
|
allowBlank: false,
|
|
comboItems: [
|
|
['users', gettext('Users')],
|
|
['groups', gettext('Groups')],
|
|
['both', gettext('Users and Groups')],
|
|
],
|
|
},
|
|
{
|
|
xtype: 'proxmoxKVComboBox',
|
|
value: '1',
|
|
deleteEmpty: false,
|
|
disabled: true,
|
|
allowBlank: false,
|
|
comboItems: [
|
|
['1', Proxmox.Utils.yesText],
|
|
['0', Proxmox.Utils.noText],
|
|
],
|
|
name: 'enable-new',
|
|
reference: 'enable-new',
|
|
fieldLabel: gettext('Enable New'),
|
|
},
|
|
],
|
|
|
|
columnB: [
|
|
{
|
|
xtype: 'fieldset',
|
|
title: gettext('Remove Vanished Options'),
|
|
items: [
|
|
{
|
|
xtype: 'proxmoxcheckbox',
|
|
fieldLabel: gettext('ACL'),
|
|
name: 'remove-vanished-acl',
|
|
reference: 'remove-vanished-acl',
|
|
boxLabel: gettext('Remove ACLs of vanished users and groups.'),
|
|
},
|
|
{
|
|
xtype: 'proxmoxcheckbox',
|
|
fieldLabel: gettext('Entry'),
|
|
name: 'remove-vanished-entry',
|
|
reference: 'remove-vanished-entry',
|
|
boxLabel: gettext('Remove vanished user and group entries.'),
|
|
},
|
|
{
|
|
xtype: 'proxmoxcheckbox',
|
|
fieldLabel: gettext('Properties'),
|
|
name: 'remove-vanished-properties',
|
|
reference: 'remove-vanished-properties',
|
|
boxLabel: gettext('Remove vanished properties from synced users.'),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
xtype: 'proxmoxtextfield',
|
|
name: 'comment',
|
|
fieldLabel: gettext('Job Comment'),
|
|
cbind: {
|
|
deleteEmpty: '{!isCreate}',
|
|
},
|
|
autoEl: {
|
|
tag: 'div',
|
|
'data-qtip': gettext('Description of the job'),
|
|
},
|
|
},
|
|
{
|
|
xtype: 'displayfield',
|
|
reference: 'defaulthint',
|
|
value: gettext('Default sync options can be set by editing the realm.'),
|
|
userCls: 'pmx-hint',
|
|
hidden: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
|
|
initComponent: function() {
|
|
let me = this;
|
|
me.callParent();
|
|
if (me.jobid) {
|
|
me.load({
|
|
success: function(response, options) {
|
|
let values = response.result.data;
|
|
|
|
if (values['remove-vanished']) {
|
|
let opts = values['remove-vanished'].split(';');
|
|
for (const opt of opts) {
|
|
values[`remove-vanished-${opt}`] = 1;
|
|
}
|
|
}
|
|
me.down('inputpanel').setValues(values);
|
|
},
|
|
});
|
|
}
|
|
},
|
|
});
|