Generiranje konfiguracija za nginx, povijest jednog zahtjeva za povlačenjem

Pozdrav drugovi. Lijepo na mojim borbenim serverima Nginx radi od 2006. godine i tijekom godina njegove administracije skupio sam puno konfiguracija i predložaka. Puno sam hvalio nginx i nekako je ispalo da sam čak pokrenuo i nginx hub na hubu, pohvali se m/
Prijatelji su me zamolili da im postavim razvojnu farmu i umjesto da im dovučem svoje specifične predloške, sjetio sam se zanimljivog projekta nginxconfig.io, koji razbacuje konfiguracije po policama i priprema sve za lets encrypt itd. Pomislio sam, zašto ne? Međutim, razbjesnila me činjenica da mi nginxconfig nudi preuzimanje zip arhive u preglednik, a da mi ne dopušta da je učitam izravno na poslužitelj koristeći wget/fetch/curl. Kakve gluposti, zasto mi to treba u browseru, treba mi na serveru sa konzole. Ljut, otišao sam na github da vidim srž projekta, što je dovelo do njegovog forka i, kao rezultat, zahtjeva za povlačenjem. O čemu ne bih pisala da nije zanimljivo 😉

Generiranje konfiguracija za nginx, povijest jednog zahtjeva za povlačenjem

Naravno, prije kopanja po izvorima pogledao sam odakle Chrome izvlači generiranu zip arhivu s konfiguracijama i tamo me čekala adresa koja počinje s “blob:”, ups. Već je postalo jasno da usluga ne generira ništa usput, dapače, sve to radi js. Doista, zip arhivu generiraju klijent, preglednik i sam javascript. Oni. ljepota je u tome što projekt nginxconfig.io može se jednostavno spremiti kao html stranica, učitati na neke narod.ru i radit će) Ovo je vrlo smiješno i zanimljivo rješenje, međutim, užasno je nezgodno za postavljanje poslužitelja, zapravo, upravo za ono za što je ovaj projekt stvoren. Preuzmite generiranu arhivu preglednikom, a zatim je prenesite na poslužitelj pomoću nc... u 2019? Postavio sam si zadatak pronaći način za preuzimanje dobivene konfiguracije izravno na poslužitelj.
Nakon račvanja projekta, počeo sam razmišljati o tome koje su mi mogućnosti. Zadatak je bio kompliciran činjenicom da nisam želio odstupiti od uvjeta da projekt ostane čisti front-end, bez back-enda. Naravno, najjednostavnije rješenje bilo bi povući nodejs i prisiliti ga da generira arhivu s konfiguracijama koristeći izravne veze.
Zapravo, nije bilo puno opcija. Točnije, samo jedno mi je palo na pamet. Moramo postaviti konfiguracije i dobiti vezu koju možemo kopirati na konzolu poslužitelja da dobijemo zip arhivu.
Nekoliko tekstualnih datoteka u rezultirajućoj zip arhivi teško je bilo, doslovno nekoliko kilobajta. Očito rješenje bilo je dobiti niz base64 iz generirane zip arhive i baciti ga u međuspremnik, dok ste na poslužitelju s naredbom u konzoli

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

mogli bismo stvoriti ovu istu zip datoteku.

nginxconfig.io napisan u AngularJS, ne mogu ni zamisliti koliko bi kilometara koda bilo potrebno da autor nije odabrao reaktivni js okvir. Ali mogu savršeno zamisliti koliko bi se sve to jednostavnije i ljepše moglo implementirati u VueJS, iako je ovo sasvim druga tema.
U resursima projekta vidimo metodu za generiranje zip arhive:

$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',
	});
};

sve je vrlo jednostavno, pomoću knjižnice jszip Zip se stvara tamo gdje su smještene konfiguracijske datoteke. Nakon stvaranja zip arhive, js je šalje u preglednik pomoću biblioteke FileSaver.js:

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

gdje je sadržaj rezultirajući blob objekt zip arhive.

Ok, sve što sam trebao učiniti je dodati još jedan gumb pokraj njega i kada bih kliknuo na njega, ne bih spremio dobivenu zip arhivu u preglednik, već bih dobio base64 kod iz nje. Nakon malo petljanja, dobio sam 2 metode, umjesto samo jednog downloadZipa:

$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',
	});
};

Kao što ste možda primijetili, premjestio sam generiranje same zip arhive na privatnu genereZip metodu, i tako dalje. Ovo je AngularJS, a sam autor se drži povratnih poziva i nije to implementirao kroz obećanja. downloadZip je i dalje radio saveAs kao izlaz, dok je downloadBase64 radio nešto malo drugačije. Stvaramo FileReader objekt koji nam je došao u html5 i već je prilično pristupačan za upotrebu. Što u jednom trenutku može napraviti base64 string od blob-a, točnije, napravi DataURL string, ali nama to nije toliko važno, jer DataURL sadrži točno ono što nam treba. Bingo, čekala me mala začkoljica kad sam sve ovo pokušao staviti u buffer. Autorica je u projektu koristila knjižnicu međuspremnikjs, koji vam omogućuje rad s međuspremnikom bez flash objekata, na temelju odabranog teksta. U početku sam odlučio staviti svoju base64 u element s display:none;, ali u ovom slučaju je nisam mogao staviti u međuspremnik jer ne dolazi do razdvajanja. Stoga, umjesto display:none; učinio sam

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

što mi je omogućilo da sakrijem element od pogleda i zapravo ga ostavim na stranici. Voila, zadatak je dovršen, kada sam kliknuo na svoj gumb, u međuspremnik je postavljena ovakva linija:

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

koju sam jednostavno zalijepio u konzolu na serveru i odmah dobio zip arhivu sa svim konfiguracijama.
I, naravno, poslao sam zahtjev za povlačenje autoru, jer... projekt je aktivan i živahan, volio bih vidjeti ažuriranja od autora i imati svoj gumb) Za zainteresirane, evo ga moja vilica projekt i ja zahtjev za povlačenjem, gdje možete vidjeti što sam ispravio/dodao.
Sretan razvoj svima)

Generiranje konfiguracija za nginx, povijest jednog zahtjeva za povlačenjem

Izvor: www.habr.com

Dodajte komentar