Nginx konfigurāciju ģenerēšana, viena vilkšanas pieprasījuma vēsture

Sveicieni, biedri. Skaisti manos kaujas serveros nginx darbojas kopš 2006. gada, un tās administrēšanas gadu laikā esmu uzkrājis daudz konfigurāciju un veidņu. Es ļoti slavēju nginx un kaut kā sanāca, ka es pat iedarbināju nginx hubu uz rumbas, dižoties m/
Draugi man lūdza izveidot viņiem attīstības fermu, un tā vietā, lai vilktu viņiem savas īpašās veidnes, es atcerējos interesantu projektu. nginxconfig.io, kas izkaisa konfigurācijas pa plauktiem un sagatavo visu, lai varētu šifrēt utt. Es domāju, kāpēc gan ne? Tomēr mani saniknoja fakts, ka nginxconfig piedāvā lejupielādēt zip arhīvu pārlūkprogrammā, neļaujot to augšupielādēt tieši serverī, izmantojot wget/fetch/curl. Kādas muļķības, kāpēc man to vajag pārlūkprogrammā, man to vajag serverī no konsoles. Dusmīgs es devos uz github, lai apskatītu projekta iekšpusi, kas noveda pie tā dakšas un, kā rezultātā, pull pieprasījums. Par ko es nerakstītu, ja nebūtu interesanti 😉

Nginx konfigurāciju ģenerēšana, viena vilkšanas pieprasījuma vēsture

Protams, pirms rakšanās avotos paskatījos, kur Chrome izvelk ģenerēto zip arhīvu ar konfigurācijām, un tur mani gaidīja adrese, kas sākas ar “blob:”, ups. Jau kļuvis skaidrs, ka pakalpojums neko neģenerē, patiesībā to visu dara js. Patiešām, zip arhīvu ģenerē pats klients, pārlūkprogramma un JavaScript. Tie. skaistums ir tas, ka projekts nginxconfig.io var vienkārši saglabāt kā html lapu, augšupielādēt kādā narod.ru un tas darbosies) Šis ir ļoti smieklīgs un interesants risinājums, tomēr tas ir šausmīgi neērti serveru iestatīšanai, patiesībā tieši tam, kam šis projekts tika izveidots. Lejupielādēt ģenerēto arhīvu ar pārlūkprogrammu un pēc tam pārsūtīt to uz serveri, izmantojot nc... 2019. gadā? Es uzstādīju sev uzdevumu atrast veidu, kā iegūto konfigurāciju lejupielādēt tieši serverī.
Pēc projekta pabeigšanas es sāku domāt par manām iespējām. Uzdevumu sarežģīja tas, ka negribēju atkāpties no nosacījuma, ka projektam jāpaliek tīram priekšgalam, bez jebkāda aizmugures. Protams, vienkāršākais risinājums būtu uzvilkt nodejs un piespiest to ģenerēt arhīvu ar konfigurācijām, izmantojot tiešās saites.
Patiesībā nebija daudz iespēju. Precīzāk, prātā ienāca tikai viens. Mums ir jāiestata konfigurācijas un jāiegūst saite, kuru varam kopēt uz servera konsoli, lai iegūtu zip arhīvu.
Vairāki teksta faili iegūtajā zip arhīvā svēra diezgan daudz, burtiski dažus kilobaitus. Acīmredzamais risinājums bija iegūt base64 virkni no ģenerētā zip arhīva un iemest to buferī, atrodoties serverī ar komandu konsolē

echo 'base64string' | base64 --decode > config.zip

mēs varētu izveidot šo pašu zip failu.

nginxconfig.io bija rakstīts AngularJS, pat nevaru iedomāties, cik kilometri koda būtu bijis vajadzīgs, ja autors nebūtu izvēlējies reaktīvo js karkasu. Bet es lieliski varu iedomāties, cik daudz vienkāršāk un skaistāk to visu varētu īstenot VueJS, lai gan šī ir pavisam cita tēma.
Projekta resursos mēs redzam metodi zip arhīva ģenerēšanai:

$scope.downloadZip = function() {
	var zip = new JSZip();

	var sourceCodes = $window.document.querySelectorAll('main .file .code.source');

	for (var i = 0; i < sourceCodes.length; i++) {
		var sourceCode = sourceCodes[i];

		var name	= sourceCode.dataset.filename;
		var content	= sourceCode.children[0].children[0].innerText;

		if (!$scope.isSymlink() && name.match(/^sites-available//)) {
			name = name.replace(/^sites-available//, 'sites-enabled/');
		}

		zip.file(name, content);

		if (name.match(/^sites-available//)) {
			zip.file(name.replace(/^sites-available//, 'sites-enabled/'), '../' + name, {
				unixPermissions: parseInt('120755', 8),
			});
		}
	}

	zip.generateAsync({
		type: 'blob',
		platform: 'UNIX',
	}).then(function(content) {
		saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_zip',
	});
};

viss ir pavisam vienkārši, izmantojot bibliotēku jszip Vietā, kur tiek ievietoti konfigurācijas faili, tiek izveidots zip. Pēc zip arhīva izveides js ievada to pārlūkprogrammā, izmantojot bibliotēku FileSaver.js:

saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');

kur saturs ir iegūtais zip arhīva blob objekts.

Ok, atlika tikai pievienot vēl vienu pogu blakus un noklikšķinot uz tās es nesaglabātu iegūto zip arhīvu pārlūkprogrammā, bet gan dabūtu no tā base64 kodu. Pēc nelielas pamošanās es ieguvu 2 metodes, nevis tikai vienu downloadZip:

$scope.downloadZip = function() {
	generateZip(function (content) {
		saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_zip',
	});
};
$scope.downloadBase64 = function() {
	generateZip(function (content) {
		var reader = new FileReader();
		reader.readAsDataURL(content);
		reader.onloadend = function() {
			var base64 = reader.result.replace(/^data:.+;base64,/, '');
			// в переменной base64 как раз нужный мне zip архив в виде base64 строки
		}
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_base64',
	});
};

Kā jūs, iespējams, pamanījāt, es pārcēlu paša zip arhīva ģenerēšanu uz privāto generateZip metodi utt. Tas ir AngularJS, un pats autors pieturas pie atzvanīšanas un neīstenoja to caur solījumiem. downloadZip joprojām saglabāja As kā izvadi, savukārt downloadBase64 darīja kaut ko nedaudz savādāk. Mēs izveidojam FileReader objektu, kas nonāca pie mums html5 un jau ir diezgan pieejams lietošanai. Kas vienā reizē var izveidot base64 virkni no blob, vai drīzāk, tas veido DataURL virkni, bet tas mums nav tik svarīgi, jo DataURL satur tieši to, kas mums nepieciešams. Bingo, mani gaidīja neliela aizķeršanās, kad mēģināju to visu ielikt buferī. Autore projektā izmantoja bibliotēku starpliktuves, kas ļauj strādāt ar starpliktuvi bez zibspuldzes objektiem, pamatojoties uz atlasīto tekstu. Sākotnēji es nolēmu ievietot savu base64 elementā ar displeju:none;, taču šajā gadījumā es to nevarēju ievietot starpliktuvē, jo atdalīšanās nenotiek. Tāpēc displeja vietā:none; ES izdarīju

position: absolute;
z-index: -1;
opacity: 0;

kas ļāva man gan paslēpt elementu no skata, gan faktiski atstāt to lapā. Voila, uzdevums tika pabeigts, kad es noklikšķināju uz savas pogas, buferī tika ievietota šāda rinda:

echo 'base64string' | base64 --decode > config.zip

kuru es vienkārši ielīmēju servera konsolē un uzreiz saņēmu zip arhīvu ar visām konfigurācijām.
Un, protams, nosūtīju autoram pull pieprasījumu, jo... projekts ir aktīvs un dzīvs, gribētos redzēt autora atjauninājumus un savu pogu) Interesentiem te mana dakša projekts un es pull pieprasījums, kur var redzēt, ko es laboju/pievienoju.
Laimīgu attīstību visiem)

Nginx konfigurāciju ģenerēšana, viena vilkšanas pieprasījuma vēsture

Avots: www.habr.com

Pievieno komentāru