mirror of https://github.com/rancher/ui.git
552 lines
15 KiB
JavaScript
552 lines
15 KiB
JavaScript
import Component from '@ember/component';
|
|
import { inject as service } from '@ember/service';
|
|
import {
|
|
get, set, observer, setProperties, computed
|
|
} from '@ember/object';
|
|
import { reads } from '@ember/object/computed';
|
|
import NewOrEdit from 'ui/mixins/new-or-edit';
|
|
import parseUri from 'shared/utils/parse-uri';
|
|
import { resolve } from 'rsvp';
|
|
import { next, later } from '@ember/runloop';
|
|
import C from 'ui/utils/constants';
|
|
|
|
const INVALID_PREFIX_CHAR = ['\\', '/', '*', '?', '"', '<', '>', '|', ` `, ',', '#'];
|
|
|
|
export default Component.extend(NewOrEdit, {
|
|
scope: service(),
|
|
globalStore: service(),
|
|
intl: service(),
|
|
// input
|
|
errors: null,
|
|
targetType: null,
|
|
configMap: null,
|
|
esEndpointValidate: true,
|
|
fluentdEndpointValidate: true,
|
|
esErrors: [],
|
|
pasteOrUpload: false,
|
|
testing: false,
|
|
testOk: true,
|
|
tested: false,
|
|
|
|
pageScope: reads('scope.currentPageScope'),
|
|
cluster: reads('scope.currentCluster'),
|
|
project: reads('scope.currentProject'),
|
|
clusterTargetType: reads('clusterLogging.targetType'),
|
|
originalModelTargetType: reads('originalModel.targetType'),
|
|
|
|
init() {
|
|
this._super(...arguments)
|
|
this.initCustomContent()
|
|
},
|
|
|
|
actions: {
|
|
test() {
|
|
if (get(this, 'testing') || get(this, 'tested')) {
|
|
return resolve();
|
|
}
|
|
const clone = get(this, 'model').clone()
|
|
|
|
const ok = this.willSave();
|
|
|
|
if (!ok) {
|
|
return resolve();
|
|
}
|
|
|
|
const data = get(this, 'model');
|
|
const gs = get(this, 'globalStore');
|
|
const pageScope = this.get('pageScope');
|
|
|
|
set(this, 'testing', true);
|
|
|
|
let url = `${ pageScope }loggings?action=test`
|
|
|
|
if (get(this, 'targetType') === 'customTarget') {
|
|
url = `${ pageScope }loggings?action=dryRun`
|
|
}
|
|
|
|
return gs.rawRequest({
|
|
url,
|
|
method: 'POST',
|
|
data,
|
|
}).then(() => {
|
|
setProperties(this, {
|
|
testOk: true,
|
|
errors: null,
|
|
});
|
|
}).catch((xhr) => {
|
|
setProperties(this, {
|
|
testOk: false,
|
|
errors: [xhr.body.message || xhr.body.code],
|
|
});
|
|
}).finally(() => {
|
|
setProperties(this, {
|
|
tested: true,
|
|
testing: false,
|
|
model: clone,
|
|
})
|
|
|
|
next(() => {
|
|
later(() => {
|
|
set(this, 'tested', false);
|
|
}, 3000);
|
|
});
|
|
});
|
|
},
|
|
cancel() {
|
|
setProperties(this, {
|
|
targetType: get(this, 'preTargetType'),
|
|
pasteOrUpload: false,
|
|
})
|
|
},
|
|
|
|
showPaste() {
|
|
setProperties(this, {
|
|
preTargetType: get(this, 'targetType'),
|
|
targetType: 'customTarget',
|
|
pasteOrUpload: true,
|
|
})
|
|
},
|
|
},
|
|
|
|
targetTypeChange: observer('targetType', function() {
|
|
set(this, 'errors', [])
|
|
}),
|
|
|
|
pasteOrUploadChange: observer('pasteOrUpload', function() {
|
|
const { fileObj, deepStrs = [] } = get(this, 'parseValue')
|
|
const preTargetType = get(this, 'preTargetType')
|
|
|
|
if (!get(this, 'pasteOrUpload')) {
|
|
const type = fileObj['@type']
|
|
let targetType = type
|
|
|
|
switch (type) {
|
|
case 'splunk_hec':
|
|
targetType = 'splunk'
|
|
break;
|
|
case 'remote_syslog':
|
|
targetType = 'syslog'
|
|
break;
|
|
case 'kafka_buffered':
|
|
targetType = 'kafka'
|
|
break;
|
|
case 'forward':
|
|
targetType = 'fluentForwarder'
|
|
break;
|
|
}
|
|
set(this, 'targetType', targetType)
|
|
} else {
|
|
let type = preTargetType
|
|
|
|
switch (preTargetType) {
|
|
case 'splunk':
|
|
type = 'splunk_hec'
|
|
break;
|
|
case 'syslog':
|
|
type = 'remote_syslog'
|
|
break;
|
|
case 'kafka':
|
|
type = 'kafka_buffered'
|
|
break;
|
|
case 'fluentForwarder':
|
|
type = 'forward'
|
|
break;
|
|
}
|
|
set(fileObj, '@type', type)
|
|
let body = ''
|
|
let str = ''
|
|
|
|
deepStrs.map((s) => {
|
|
str += s
|
|
})
|
|
|
|
for (let key in fileObj) {
|
|
body += `${ key } ${ fileObj[key] }
|
|
`
|
|
}
|
|
const out = `<match *>
|
|
${ body }${ str }
|
|
</match>`
|
|
|
|
set(this, 'customContent', out)
|
|
}
|
|
}),
|
|
|
|
headerLabel: computed('pageScope', function() {
|
|
const ps = get(this, 'pageScope');
|
|
|
|
if (ps === 'cluster') {
|
|
return 'loggingPage.clusterHeader';
|
|
} else {
|
|
return 'loggingPage.projectHeader';
|
|
}
|
|
}),
|
|
|
|
isClusterLevel: computed('pageScope', function() {
|
|
return get(this, 'pageScope') === 'cluster';
|
|
}),
|
|
|
|
saveDisabled: computed('originalModel.{id,targetType}', 'targetType', 'pasteOrUpload', function() {
|
|
return get(this, 'originalModel.targetType') === 'none'
|
|
&& get(this, 'targetType') === 'none'
|
|
&& !get(this, 'pasteOrUpload');
|
|
}),
|
|
|
|
parseValue: computed('customContent', function() {
|
|
let fileObj = {}
|
|
const removeMacth = get(this, 'customContent').replace(/.*<match.*>.*(\r\n|\n|\r) {2}/ig, '').replace(/(\r\n|\n|\r).*<\/match.*>/ig, '')
|
|
const deepStrs = removeMacth.match(/<(.|\r\n|\n|\r)*<\/.*>/ig, '') || []
|
|
const removedDeep = removeMacth.replace(/<(.|\r\n|\n|\r)*<\/.*>/ig, '')
|
|
|
|
const myString = removedDeep.replace(/(\r\n|\n|\r)/gm, '<br />');
|
|
const keyAndValue = myString.split('<br />').filter((f) => f !== '<br />').filter((f = '') => !f.startsWith('#') && !f.startsWith('<'))
|
|
|
|
keyAndValue.map((item = '') => {
|
|
const arr = item.split(' ').filter((f) => f !== '')
|
|
|
|
if (arr[0] && arr[1]) {
|
|
set(fileObj, arr[0], arr[1])
|
|
}
|
|
})
|
|
|
|
return {
|
|
fileObj,
|
|
deepStrs
|
|
}
|
|
}),
|
|
|
|
willSave() {
|
|
const {
|
|
targetType, pageScope, model, intl
|
|
} = this
|
|
|
|
set(model, 'clusterId', get(this, 'cluster.id'));
|
|
if (pageScope === 'project') {
|
|
set(model, 'projectId', get(this, 'project.id'));
|
|
}
|
|
|
|
setProperties(model, {
|
|
elasticsearchConfig: null,
|
|
splunkConfig: null,
|
|
kafkaConfig: null,
|
|
syslogConfig: null,
|
|
fluentForwarderConfig: null,
|
|
customTargetConfig: null,
|
|
});
|
|
|
|
if (targetType === 'none') {
|
|
return true;
|
|
}
|
|
|
|
const errors = set(this, 'errors', [])
|
|
|
|
if (get(this, 'pasteOrUpload')) {
|
|
const { fileObj } = get(this, 'parseValue')
|
|
|
|
const targetType = fileObj['@type']
|
|
const types = Object.keys(C.LOGGING_TPYE_TO_CONFIG) || []
|
|
|
|
if (!types.includes(targetType)) {
|
|
errors.pushObject(intl.t('loggingPage.customTarget.type.error'))
|
|
}
|
|
|
|
setProperties(model, {
|
|
customTargetConfig: {
|
|
clientKey: get(this, 'model.customTarget.config.clientKey'),
|
|
clientCert: get(this, 'model.customTarget.config.clientCert'),
|
|
certificate: get(this, 'model.customTarget.config.certificate'),
|
|
content: (get(this, 'customContent') || '').replace(/.*<match.*>.*(\r\n|\n|\r) {2}/ig, '').replace(/(\r\n|\n|\r).*<\/match.*>/ig, ''),
|
|
}
|
|
})
|
|
|
|
const {
|
|
outputFlushInterval, outputTags, dockerRoot, includeSystemComponent
|
|
} = get(this, 'model.customTarget');
|
|
|
|
setProperties(model, {
|
|
outputFlushInterval,
|
|
outputTags,
|
|
dockerRoot,
|
|
includeSystemComponent,
|
|
})
|
|
} else {
|
|
if (targetType === 'fluentForwarder') {
|
|
const fluentServers = get(model, 'fluentForwarder.config.fluentServers') || [];
|
|
let filter = fluentServers.filter((f) => !f.endpoint)
|
|
|
|
if (filter.length > 0) {
|
|
errors.pushObject(intl.t('loggingPage.fluentd.endpoint.required'))
|
|
} else {
|
|
if (!get(this, 'endpointValidate')) {
|
|
errors.pushObject(intl.t('loggingPage.fluentd.endpoint.invalid'))
|
|
}
|
|
}
|
|
|
|
filter = fluentServers.filter((f) => !f.standby)
|
|
if (filter.length === 0) {
|
|
errors.pushObject(intl.t('loggingPage.fluentd.standby.none'))
|
|
}
|
|
|
|
if (errors.length === 0) {
|
|
const enableTls = get(model, 'fluentForwarder.config.enableTls')
|
|
|
|
if (!enableTls) {
|
|
set(model, 'fluentForwarder.config.certificate', null)
|
|
}
|
|
}
|
|
}
|
|
|
|
let formatConfig = get(model, `${ targetType }.config`)
|
|
|
|
setProperties(model, {
|
|
outputFlushInterval: get(model, `${ targetType }.outputFlushInterval`),
|
|
outputTags: get(model, `${ targetType }.outputTags`),
|
|
dockerRoot: get(model, `${ targetType }.dockerRoot`),
|
|
[`${ targetType }Config`]: formatConfig,
|
|
includeSystemComponent: get(model, `${ targetType }.includeSystemComponent`),
|
|
})
|
|
|
|
if (targetType === 'elasticsearch') {
|
|
const elasticsearchErrors = this.elasticsearchWillSave()
|
|
|
|
errors.pushObjects(elasticsearchErrors)
|
|
}
|
|
|
|
if (targetType === 'splunk') {
|
|
const splunkErrors = this.splunkWillSave()
|
|
|
|
errors.pushObjects(splunkErrors)
|
|
}
|
|
|
|
if (targetType === 'kafka') {
|
|
const kafkaErrors = this.kafkaWillSave()
|
|
|
|
errors.pushObjects(kafkaErrors)
|
|
}
|
|
|
|
if (targetType === 'syslog') {
|
|
const syslogErrors = this.syslogWillSave()
|
|
|
|
errors.pushObjects(syslogErrors)
|
|
}
|
|
}
|
|
|
|
if (errors.length > 0) {
|
|
return false
|
|
}
|
|
|
|
return this._super(...arguments);
|
|
},
|
|
|
|
formatUrl(url) {
|
|
const urlParser = parseUri(url) || {}
|
|
|
|
if (!urlParser.port) {
|
|
if (urlParser.protocol === 'http') {
|
|
return `${ urlParser.protocol }://${ urlParser.host }:80`
|
|
}
|
|
if (urlParser.protocol === 'https') {
|
|
return `${ urlParser.protocol }://${ urlParser.host }:443`
|
|
}
|
|
}
|
|
|
|
return url
|
|
},
|
|
|
|
doneSaving() {
|
|
if (get(this, 'targetType') !== 'customTarget') {
|
|
set(this, 'customContent', `<match *>\n</match>`)
|
|
}
|
|
this.sendAction('refreshModel');
|
|
},
|
|
|
|
initCustomContent() {
|
|
if (get(this, 'originalModelTargetType') === 'customTarget') {
|
|
setProperties(this, {
|
|
pasteOrUpload: true,
|
|
customContent: `<match *>\n ${ get(this, 'model.customTargetConfig.content') }\n</match>`,
|
|
})
|
|
} else {
|
|
set(this, 'customContent', get(this, 'model.customTarget.config.content'))
|
|
}
|
|
},
|
|
|
|
kafkaWillSave() {
|
|
const { model, intl } = this
|
|
const errors = []
|
|
let kt;
|
|
const brokerEndpoints = get(model, 'kafka.config.brokerEndpoints');
|
|
const zookeeperEndpoint = get(model, 'kafka.config.zookeeperEndpoint');
|
|
const kafkaConfig = get(model, 'kafkaConfig') || {}
|
|
|
|
if (brokerEndpoints && brokerEndpoints.length > 0) {
|
|
kt = 'broker';
|
|
} else if (zookeeperEndpoint) {
|
|
kt = 'zookeeper';
|
|
} else {
|
|
errors.pushObject(intl.t('loggingPage.kafka.endpoint.required'))
|
|
}
|
|
|
|
if (kt === 'broker') {
|
|
if (get(kafkaConfig, 'saslUsername') && get(kafkaConfig, 'saslPassword')) {
|
|
if ( get(kafkaConfig, 'saslType') === 'plain' ) {
|
|
set(kafkaConfig, 'saslScramMechanism', null)
|
|
}
|
|
} else {
|
|
setProperties(kafkaConfig, {
|
|
saslType: null,
|
|
saslScramMechanism: null,
|
|
})
|
|
}
|
|
|
|
setProperties(kafkaConfig, {
|
|
zookeeperEndpoint: null,
|
|
brokerEndpoints,
|
|
});
|
|
} else if (kt === 'zookeeper') {
|
|
setProperties(kafkaConfig, {
|
|
zookeeperEndpoint,
|
|
brokerEndpoints: null,
|
|
saslScramMechanism: null,
|
|
saslPassword: null,
|
|
saslType: null,
|
|
saslUsername: null,
|
|
clientKey: null,
|
|
clientCert: null,
|
|
certificate: null,
|
|
});
|
|
}
|
|
|
|
if (!get(kafkaConfig, 'topic')) {
|
|
errors.pushObject(intl.t('loggingPage.kafka.topic.required'))
|
|
}
|
|
|
|
return errors
|
|
},
|
|
|
|
syslogWillSave() {
|
|
const { model = {}, intl } = this
|
|
const errors = []
|
|
const config = get(model, 'syslog.config') || {}
|
|
const {
|
|
endpoint, protocol, enableTls, sslVerify
|
|
} = config
|
|
const syslogConfig = get(model, 'syslogConfig') || {}
|
|
|
|
if (!endpoint) {
|
|
errors.pushObject(intl.t('loggingPage.syslog.endpoint.required'))
|
|
}
|
|
|
|
if (protocol === 'udp') {
|
|
setProperties(syslogConfig, {
|
|
certificate: null,
|
|
clientKey: null,
|
|
clientCert: null,
|
|
sslVerify: null,
|
|
enableTls: null,
|
|
})
|
|
}
|
|
|
|
if (protocol === 'tcp') {
|
|
if (!enableTls) {
|
|
setProperties(syslogConfig, {
|
|
certificate: null,
|
|
clientKey: null,
|
|
clientCert: null,
|
|
sslVerify: null,
|
|
})
|
|
} else {
|
|
if (!sslVerify) {
|
|
set(syslogConfig, 'certificate', null)
|
|
}
|
|
}
|
|
}
|
|
|
|
return errors
|
|
},
|
|
|
|
splunkWillSave() {
|
|
const { model = {}, intl } = this
|
|
const errors = []
|
|
|
|
if (!get(model, 'splunk.config.endpoint')) {
|
|
errors.pushObject(intl.t('loggingPage.splunk.endpointRequired'))
|
|
}
|
|
if (!get(model, 'splunk.config.token')) {
|
|
errors.pushObject(intl.t('loggingPage.splunk.tokenRequired'))
|
|
}
|
|
|
|
const config = get(model, 'splunk.config') || {}
|
|
const { endpoint = '', sslVerify } = config
|
|
const splunkConfig = get(model, 'splunkConfig') || {}
|
|
|
|
if (endpoint.startsWith('https')) {
|
|
if (!sslVerify) {
|
|
set(splunkConfig, 'certificate', null)
|
|
}
|
|
} else {
|
|
setProperties(splunkConfig, {
|
|
certificate: null,
|
|
clientKey: null,
|
|
clientCert: null,
|
|
clientKeyPass: null,
|
|
sslVerify: false,
|
|
})
|
|
}
|
|
|
|
return errors
|
|
},
|
|
|
|
elasticsearchWillSave() {
|
|
const { model = {}, intl } = this
|
|
const errors = []
|
|
const config = get(model, 'elasticsearch.config') || {}
|
|
|
|
const elasticsearchConfig = get(model, 'elasticsearchConfig') || {}
|
|
|
|
set(elasticsearchConfig, 'indexPrefix', get(elasticsearchConfig, 'indexPrefix').toLowerCase());
|
|
const indexPrefix = get(elasticsearchConfig, 'indexPrefix');
|
|
|
|
if ( !indexPrefix ) {
|
|
errors.pushObject(intl.t('loggingPage.elasticsearch.indexPatterns.errors.required'))
|
|
}
|
|
|
|
if ( indexPrefix.startsWith('-') || indexPrefix.startsWith('_') || indexPrefix.startsWith('+') ) {
|
|
errors.pushObject(intl.t('loggingPage.elasticsearch.indexPatterns.errors.startsWith'))
|
|
}
|
|
|
|
INVALID_PREFIX_CHAR.forEach((char) => {
|
|
if ( indexPrefix.indexOf(char) > -1 ) {
|
|
errors.pushObject(intl.t('loggingPage.elasticsearch.indexPatterns.errors.invalidCharacters', { char }))
|
|
}
|
|
})
|
|
|
|
const esErrors = get(this, 'esErrors')
|
|
const { endpoint, sslVerify } = config
|
|
|
|
if (!endpoint) {
|
|
errors.pushObject(intl.t('loggingPage.elasticsearch.endpoint.required'))
|
|
} else if (esErrors) {
|
|
errors.pushObject(intl.t(esErrors))
|
|
}
|
|
|
|
set(elasticsearchConfig, 'endpoint', this.formatUrl(endpoint))
|
|
|
|
if (endpoint.startsWith('https')) {
|
|
if (!sslVerify) {
|
|
set(elasticsearchConfig, 'certificate', null)
|
|
}
|
|
} else {
|
|
setProperties(elasticsearchConfig, {
|
|
certificate: null,
|
|
clientKey: null,
|
|
clientCert: null,
|
|
clientKeyPass: null,
|
|
sslVerify: false,
|
|
})
|
|
}
|
|
|
|
return errors
|
|
},
|
|
});
|