Konfigurációk generálása nginxhez, egyetlen lehívási kérelem előzményei

Üdvözlet elvtársak. Gyönyörű a harci szervereimen nginx 2006 óta működik, és az adminisztráció évei alatt rengeteg konfigurációt és sablont halmoztam fel. Sokat dicsértem az nginxet és valahogy úgy alakult, hogy még egy nginx hubot is elindítottam a hubon, mutasd meg m/
Barátaim megkérték, hogy hozzak létre nekik egy fejlesztőfarmot, és ahelyett, hogy elhurcoltam volna a sajátos sablonokat, eszembe jutott egy érdekes projekt. nginxconfig.io, ami szétszórja a konfigokat a polcokon és mindent előkészít a lets encrypt stb. Arra gondoltam, miért ne? Feldühített azonban az a tény, hogy az nginxconfig felajánlja, hogy töltsem le a zip-archívumot a böngészőbe anélkül, hogy a wget/fetch/curl segítségével közvetlenül a szerverre tölthetném fel. Micsoda baromság, miért kell a böngészőben, a szerveren kell a konzolból. Dühösen elmentem a githubba, hogy megnézzem a projekt lényegét, ami a villájához vezetett, és ennek eredményeként egy húzási kérést. Amiről nem írnék, ha nem lenne érdekes 😉

Konfigurációk generálása nginxhez, egyetlen lehívási kérelem előzményei

Persze mielőtt beleástam volna magam a forrásokba, megnéztem, hogy a Chrome honnan húzza ki a generált zip archívumot konfigokkal, és ott egy „blob:” kezdetű cím várt rám, hoppá. Az már világossá vált, hogy a szolgáltatás nem generál semmit, sőt, mindezt a js teszi. Valójában a zip-archívumot maga az ügyfél, a böngésző és a javascript hozza létre. Azok. az a szépség, hogy a projekt nginxconfig.io egyszerűen elmenthető html oldalként, feltölthető egyesekre narod.ru és működni fog) Ez egy nagyon vicces és érdekes megoldás, azonban borzasztóan kényelmetlen a szerverek beállításához, valójában pontosan arra, amire ez a projekt készült. Töltsd le böngészővel a generált archívumot, majd 2019-ben nc... segítségével vidd át a szerverre? Azt a feladatot tűztem ki magam elé, hogy megtaláljam a módját, hogyan töltsem le közvetlenül a szerverre a kapott konfigurációt.
Miután befejeztem a projektet, elkezdtem gondolkodni azon, hogy mik a lehetőségeim. A feladatot nehezítette, hogy nem akartam eltérni attól a feltételtől, hogy a projekt tiszta front-end maradjon, minden háttér nélkül. Természetesen a legegyszerűbb megoldás az lenne, ha előhúzzuk a nodejs-t, és rákényszerítjük, hogy direkt hivatkozások segítségével állítson elő egy archívumot konfigurációkkal.
Valójában nem volt sok lehetőség. Pontosabban csak egy jutott eszembe. Be kell állítanunk a konfigurációkat, és kapnunk kell egy hivatkozást, amit a szerverkonzolra másolhatunk, hogy zip archívumot kapjunk.
Az így létrejövő zip-archívumban több szövegfájl súlya meglehetősen kevés, szó szerint néhány kilobájt. A kézenfekvő megoldás az volt, hogy a generált zip archívumból lekértem a base64 karakterláncot és bedobtam a pufferbe, miközben a szerveren a konzolban lévő paranccsal.

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

létrehozhatjuk ugyanezt a zip fájlt.

nginxconfig.io AngularJS-ben íródott, el sem tudom képzelni, hány kilométernyi kódra lett volna szükség, ha a szerző nem választott volna reaktív js keretrendszert. De tökéletesen el tudom képzelni, mennyivel egyszerűbben és szebben lehetne mindezt megvalósítani a VueJS-ben, bár ez egy teljesen más téma.
A projekt erőforrásaiban egy módszert látunk a zip archívum létrehozására:

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

minden nagyon egyszerű, a könyvtár használatával jszip A konfigurációs fájlok elhelyezésére egy zip jön létre. A zip-archívum létrehozása után a js a könyvtár segítségével továbbítja azt a böngészőnek FileSaver.js:

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

ahol a tartalom a zip-archívum eredményül kapott blob-objektuma.

Ok, nem kellett mást tennem, mint hozzáadni egy másik gombot mellé, és amikor rákattintottam, akkor nem mentem el a kapott zip archívumot a böngészőbe, hanem lekérem onnan a base64 kódot. Egy kis babrálás után 2 módszert kaptam egyetlen downloadZip helyett:

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

Amint azt már észrevetted, a zip-archívum generálását áthelyeztem a private generateZip metódusra és így tovább. Ez az AngularJS, és maga a szerző is ragaszkodik a visszahívásokhoz, és nem ígéretekkel valósította meg. A downloadZip továbbra is a saveAs-t tette ki kimenetként, míg a downloadBase64 valamivel mást csinált. Létrehozunk egy FileReader objektumot, ami html5-ben érkezett hozzánk, és már elég elérhető használatra. Ami egyszerre tud base64 karakterláncot készíteni egy blobból, vagy inkább DataURL karakterláncot, de ez nem annyira fontos számunkra, mert A DataURL pontosan azt tartalmazza, amire szükségünk van. Bingo, egy kis gubanc várt rám, amikor megpróbáltam mindezt a pufferbe tenni. A szerző a könyvtárat használta a projektben clipboardjs, amely lehetővé teszi a vágólappal való munkát flash objektumok nélkül, a kiválasztott szöveg alapján. Kezdetben úgy döntöttem, hogy a base64-emet egy display:none; elembe teszem, de ebben az esetben nem tudtam a vágólapra tenni, mert nem történik szétválás. Ezért a display:none helyett; én csináltam

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

ami lehetővé tette számomra, hogy elrejtsem az elemet, és ténylegesen az oldalon hagyjam. Voila, a feladat befejeződött, amikor a gombomra kattintottam, egy ilyen sor került a pufferbe:

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

amit egyszerűen beillesztettem a szerveren lévő konzolba és azonnal kaptam egy zip archívumot az összes konfiggal.
És persze küldtem lehúzási kérelmet a szerzőnek, mert... a projekt aktív és élénk, szeretném látni a frissítéseket a szerzőtől és saját gombom) Az érdeklődőknek itt van a villámat projektet és magát húzza meg a kérést, ahol láthatod, hogy mit javítottam/hoztam hozzá.
Jó fejlődést mindenkinek)

Konfigurációk generálása nginxhez, egyetlen lehívási kérelem előzményei

Forrás: will.com

Hozzászólás