Commit 4c529b27223359dda8ef2b188e558fba3fa0c418
1 parent
426655c30a
Exists in
master
queues and providers dump
Showing 2 changed files with 95 additions and 13 deletions Inline Diff
lib/apiserver/routers/smstools-config.js
1 | const childProcess = require('child_process'); | 1 | const childProcess = require('child_process'); |
2 | 2 | ||
3 | const express = require('express'); | 3 | const express = require('express'); |
4 | const bodyParser = require('body-parser'); | 4 | const bodyParser = require('body-parser'); |
5 | 5 | ||
6 | const config = require('komodo-sdk/config'); | 6 | const config = require('komodo-sdk/config'); |
7 | const logger = require('komodo-sdk/logger'); | 7 | const logger = require('komodo-sdk/logger'); |
8 | 8 | ||
9 | const smstoolsConfig = require('../../smstools-config'); | 9 | const smstoolsConfig = require('../../smstools-config'); |
10 | const smstoolsConfigData = require('../../smstools-config/config-file'); | ||
10 | const smstoolsConfigCreator = require('../../smstools-config/creator'); | 11 | const smstoolsConfigCreator = require('../../smstools-config/creator'); |
11 | const smstoolsConfigSetter = require('../../smstools-config/setter'); | 12 | const smstoolsConfigSetter = require('../../smstools-config/setter'); |
12 | const smstoolsConfigData = require('../../smstools-config/config-file'); | 13 | const queuesAndProviders = require('../../smstools-config/queues-and-providers'); |
14 | |||
13 | 15 | ||
14 | const router = express.Router(); | 16 | const router = express.Router(); |
15 | module.exports = router; | 17 | module.exports = router; |
16 | 18 | ||
17 | function pageIndex(req, res) { | 19 | function pageIndex(req, res) { |
18 | const configString = smstoolsConfigCreator(); | 20 | const configString = smstoolsConfigCreator(); |
19 | res.json({ | 21 | res.json({ |
20 | dirty: smstoolsConfig.config.dirty, | 22 | dirty: smstoolsConfig.config.dirty, |
21 | config: smstoolsConfig.config, | 23 | config: smstoolsConfig.config, |
22 | configStringLength: configString.length, | 24 | configStringLength: configString.length, |
23 | configStringNrLines: (configString.match(/\n/g) || []).length, | 25 | configStringNrLines: (configString.match(/\n/g) || []).length, |
24 | configString, | 26 | configString, |
25 | }); | 27 | }); |
26 | } | 28 | } |
27 | 29 | ||
28 | function pageGenerate(req, res) { | 30 | function pageGenerate(req, res) { |
29 | res.end(smstoolsConfigCreator()); | 31 | res.end(smstoolsConfigCreator()); |
30 | } | 32 | } |
31 | 33 | ||
32 | async function pageModemList(req, res) { | 34 | async function pageModemList(req, res) { |
33 | const modems = []; | 35 | const modems = []; |
34 | // eslint-disable-next-line no-restricted-syntax | 36 | // eslint-disable-next-line no-restricted-syntax |
35 | for (const [key, value] of Object.entries(smstoolsConfigData.modems || {})) { | 37 | for (const [key, value] of Object.entries(smstoolsConfigData.modems || {})) { |
36 | modems.push({ | 38 | modems.push({ |
37 | label: `${key}: ${value.device}, INCOMING${value.outgoing ? ' and OUTGOING' : ''}`, | 39 | label: `${key}: ${value.device}, INCOMING${value.outgoing ? ' and OUTGOING' : ''}`, |
38 | value: key, | 40 | value: key, |
39 | data: value, | 41 | data: value, |
40 | }); | 42 | }); |
41 | } | 43 | } |
42 | 44 | ||
43 | res.json(modems); | 45 | res.json(modems); |
44 | } | 46 | } |
45 | 47 | ||
46 | async function pageSet(req, res) { | 48 | async function pageSet(req, res) { |
47 | const keyword = (req.params.keyword || req.query.keyword || '').trim(); | 49 | const keyword = (req.params.keyword || req.query.keyword || '').trim(); |
48 | const value = (req.query.value || '').trim(); | 50 | const value = (req.query.value || '').trim(); |
49 | 51 | ||
50 | if (!keyword) { | 52 | if (!keyword) { |
51 | res.end('Invalid keyword'); | 53 | res.end('Invalid keyword'); |
52 | return; | 54 | return; |
53 | } | 55 | } |
54 | 56 | ||
55 | const result = await smstoolsConfigSetter.set(keyword, value); | 57 | const result = await smstoolsConfigSetter.set(keyword, value); |
56 | res.json({ | 58 | res.json({ |
57 | dirty: !!smstoolsConfigData.dirty, | 59 | dirty: !!smstoolsConfigData.dirty, |
58 | result, | 60 | result, |
59 | }); | 61 | }); |
60 | } | 62 | } |
61 | 63 | ||
62 | async function pageModemSet(req, res) { | 64 | async function pageModemSet(req, res) { |
63 | if (!req.body) { | 65 | if (!req.body) { |
64 | res.json({ | 66 | res.json({ |
65 | status: 'NOT OK', | 67 | status: 'NOT OK', |
66 | message: 'Empty body', | 68 | message: 'Empty body', |
67 | }); | 69 | }); |
68 | return; | 70 | return; |
69 | } | 71 | } |
70 | 72 | ||
71 | const modemName = (req.params.modemName || '').trim(); | 73 | const modemName = (req.params.modemName || '').trim(); |
72 | if (!modemName) { | 74 | if (!modemName) { |
73 | res.json({ | 75 | res.json({ |
74 | status: 'NOT OK', | 76 | status: 'NOT OK', |
75 | message: 'Invalid modem name', | 77 | message: 'Invalid modem name', |
76 | }); | 78 | }); |
77 | return; | 79 | return; |
78 | } | 80 | } |
79 | 81 | ||
80 | const result = await smstoolsConfigSetter.setModem(modemName, req.body); | 82 | const result = await smstoolsConfigSetter.setModem(modemName, req.body); |
81 | res.json({ | 83 | res.json({ |
82 | dirty: !!smstoolsConfigData.dirty, | 84 | dirty: !!smstoolsConfigData.dirty, |
83 | result, | 85 | result, |
84 | }); | 86 | }); |
85 | } | 87 | } |
86 | 88 | ||
87 | async function pageModemSetSingleValue(req, res) { | 89 | async function pageModemSetSingleValue(req, res) { |
88 | if (!req.body) { | 90 | if (!req.body) { |
89 | res.json({ | 91 | res.json({ |
90 | status: 'NOT OK', | 92 | status: 'NOT OK', |
91 | message: 'Empty body', | 93 | message: 'Empty body', |
92 | }); | 94 | }); |
93 | return; | 95 | return; |
94 | } | 96 | } |
95 | 97 | ||
96 | const modemName = (req.params.modemName || '').trim(); | 98 | const modemName = (req.params.modemName || '').trim(); |
97 | if (!modemName) { | 99 | if (!modemName) { |
98 | res.json({ | 100 | res.json({ |
99 | status: 'NOT OK', | 101 | status: 'NOT OK', |
100 | message: 'Invalid modem name', | 102 | message: 'Invalid modem name', |
101 | }); | 103 | }); |
102 | return; | 104 | return; |
103 | } | 105 | } |
104 | 106 | ||
105 | const keyword = (req.body.keyword || '').trim(); | 107 | const keyword = (req.body.keyword || '').trim(); |
106 | if (!keyword) { | 108 | if (!keyword) { |
107 | res.json({ | 109 | res.json({ |
108 | status: 'NOT OK', | 110 | status: 'NOT OK', |
109 | message: 'Invalid keyword', | 111 | message: 'Invalid keyword', |
110 | }); | 112 | }); |
111 | return; | 113 | return; |
112 | } | 114 | } |
113 | 115 | ||
114 | const { value } = req.body; | 116 | const { value } = req.body; |
115 | 117 | ||
116 | const result = await smstoolsConfigSetter.setModemSingleValue(modemName, keyword, value); | 118 | const result = await smstoolsConfigSetter.setModemSingleValue(modemName, keyword, value); |
117 | res.json({ | 119 | res.json({ |
118 | dirty: !!smstoolsConfigData.dirty, | 120 | dirty: !!smstoolsConfigData.dirty, |
119 | result, | 121 | result, |
120 | }); | 122 | }); |
121 | } | 123 | } |
122 | 124 | ||
123 | async function pageModemDelete(req, res) { | 125 | async function pageModemDelete(req, res) { |
124 | const modemName = (req.params.modemName || '').trim(); | 126 | const modemName = (req.params.modemName || '').trim(); |
125 | if (!modemName) { | 127 | if (!modemName) { |
126 | res.json({ | 128 | res.json({ |
127 | status: 'NOT OK', | 129 | status: 'NOT OK', |
128 | message: 'Invalid modem name', | 130 | message: 'Invalid modem name', |
129 | }); | 131 | }); |
130 | return; | 132 | return; |
131 | } | 133 | } |
132 | 134 | ||
133 | const result = await smstoolsConfigSetter.delModem(modemName); | 135 | const result = await smstoolsConfigSetter.delModem(modemName); |
134 | res.json({ | 136 | res.json({ |
135 | dirty: !!smstoolsConfigData.dirty, | 137 | dirty: !!smstoolsConfigData.dirty, |
136 | result, | 138 | result, |
137 | }); | 139 | }); |
138 | } | 140 | } |
139 | 141 | ||
140 | async function pageInstallConfig(req, res) { | 142 | async function pageInstallConfig(req, res) { |
141 | logger.info('ROUTER-SMSTOOLS-CONFIG: Going to write configuration and restart smsd service'); | 143 | logger.info('ROUTER-SMSTOOLS-CONFIG: Going to write configuration and restart smsd service'); |
142 | await smstoolsConfigSetter.writeConfig(); | 144 | await smstoolsConfigSetter.writeConfig(); |
143 | 145 | ||
144 | const fileToExec = `${process.cwd()}/bin/smstools-config-install`; | 146 | const fileToExec = `${process.cwd()}/bin/smstools-config-install`; |
145 | childProcess.execFile(fileToExec, [config.smstools_config_file || '/etc/smsd.conf'], (err, stdout, stderr) => { | 147 | childProcess.execFile(fileToExec, [config.smstools_config_file || '/etc/smsd.conf'], (err, stdout, stderr) => { |
146 | res.json({ | 148 | res.json({ |
147 | err, | 149 | err, |
148 | stdout, | 150 | stdout, |
149 | stderr, | 151 | stderr, |
150 | }); | 152 | }); |
151 | }); | 153 | }); |
152 | } | 154 | } |
153 | 155 | ||
154 | function pageSmsdLog(req, res) { | 156 | function pageQueuesAndProviders(req, res) { |
155 | // deprecated | 157 | res.end(queuesAndProviders.dump); |
156 | const maxLines = (req.params.maxLines || 200); | ||
157 | childProcess.exec(`tail -n ${maxLines} /var/log/smsd/smsd.log | tac`, (err, stdout, stderr) => { | ||
158 | res.json({ | ||
159 | err, | ||
160 | stdout, | ||
161 | stderr, | ||
162 | }); | ||
163 | }); | ||
164 | } | 158 | } |
165 | 159 | ||
166 | router.get('/', pageIndex); | 160 | router.get('/', pageIndex); |
167 | router.get('/generate', pageGenerate); | 161 | router.get('/generate', pageGenerate); |
168 | router.get('/modems', pageModemList); | 162 | router.get('/modems', pageModemList); |
169 | 163 | ||
170 | router.get('/set/:keyword', pageSet); | 164 | router.get('/set/:keyword', pageSet); |
171 | router.post('/modem/set/:modemName', bodyParser.json({ type: '*/json' }), pageModemSet); | 165 | router.post('/modem/set/:modemName', bodyParser.json({ type: '*/json' }), pageModemSet); |
172 | router.post('/modem/set-single-value/:modemName', bodyParser.json({ type: '*/json' }), pageModemSetSingleValue); | 166 | router.post('/modem/set-single-value/:modemName', bodyParser.json({ type: '*/json' }), pageModemSetSingleValue); |
173 | router.get('/modem/delete/:modemName', pageModemDelete); | 167 | router.get('/modem/delete/:modemName', pageModemDelete); |
174 | router.get('/install-config', pageInstallConfig); | 168 | router.get('/install-config', pageInstallConfig); |
175 | router.get('/smsd-log/:maxLines', pageSmsdLog); | 169 | router.get('/queues-and-providers', pageQueuesAndProviders); |
lib/smstools-config/queues-and-providers.js
File was created | 1 | const fs = require('fs'); | |
2 | |||
3 | const config = require('komodo-sdk/config'); | ||
4 | const logger = require('komodo-sdk/logger'); | ||
5 | const smstoolsConfig = require('./config-file'); | ||
6 | |||
7 | const queuesBaseDir = config.smstools_queues_base_dir || '/var/spool/sms'; | ||
8 | |||
9 | function composeQueueDir(queueName) { | ||
10 | return `${queuesBaseDir}/${queueName}`; | ||
11 | } | ||
12 | |||
13 | async function createDirectory(dirname) { | ||
14 | let isExists = true; | ||
15 | try { | ||
16 | await fs.promises.access(dirname); | ||
17 | } catch (e) { | ||
18 | isExists = false; | ||
19 | } | ||
20 | |||
21 | if (isExists) return; | ||
22 | |||
23 | try { | ||
24 | fs.promises.mkdir(dirname, { recursive: true, mode: 0o770 }); | ||
25 | } catch (e) { | ||
26 | logger.warn('QUEUES-AND-PROVIDERS: Exception on creating directory', { | ||
27 | dirname, | ||
28 | e: e.message || e.toString(), | ||
29 | }); | ||
30 | } | ||
31 | } | ||
32 | |||
33 | function queuesSorted(queuesArray) { | ||
34 | const result = (queuesArray || smstoolsConfig.queues || []).sort((a, b) => { | ||
35 | const orderA = (a && Number(a.order)) || 0; | ||
36 | const orderB = (b && Number(b.order)) || 0; | ||
37 | |||
38 | if (orderA < orderB) return -1; | ||
39 | if (orderA > orderB) return 1; | ||
40 | return 0; | ||
41 | }); | ||
42 | |||
43 | return result; | ||
44 | } | ||
45 | |||
46 | exports.dump = async (mkdirIfQueueDirNotExists) => { | ||
47 | if (config.smstools_disable_queue) return ''; | ||
48 | |||
49 | const queues = queuesSorted(); | ||
50 | const queuesCount = queues.length; | ||
51 | |||
52 | const configLines = ['[queues]']; | ||
53 | const providerLines = ['[providers]']; | ||
54 | const queuesDirs = []; | ||
55 | let hasQueues = false; | ||
56 | let hasProviders = false; | ||
57 | for (let i = 0; i < queuesCount; i += 1) { | ||
58 | const queue = queues[i]; | ||
59 | |||
60 | // eslint-disable-next-line no-continue | ||
61 | if (!queue.name || !queue.enabled) continue; | ||
62 | |||
63 | const queueDir = composeQueueDir(queue.name); | ||
64 | queuesDirs.push(queueDir); | ||
65 | if (mkdirIfQueueDirNotExists) { | ||
66 | // eslint-disable-next-line no-await-in-loop | ||
67 | await createDirectory(queueDir); | ||
68 | } | ||
69 | |||
70 | const line = `${queue.name} = ${queueDir}`; | ||
71 | configLines.push(line); | ||
72 | hasQueues = true; | ||
73 | |||
74 | const hasPrefix = (!queue.prefix || !queue.prefix.length); | ||
75 | if (hasPrefix) { | ||
76 | const providerLine = `${queue.name} = ${queue.prefix.join(', ')}`; | ||
77 | providerLines.push(providerLine); | ||
78 | hasProviders = true; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | if (!hasQueues) return ''; | ||
83 | |||
84 | if (!hasProviders) { | ||
85 | return configLines.join('\n'); | ||
86 | } | ||
87 | |||
88 | return `${configLines.join('\n')}\n${providerLines.join('\n')}`; | ||
89 | }; | ||
90 |